Inspired and modified from
this example
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef struct file_list_tag
{
string* name;
// ... put other useful properties here
} list_entry;
struct flist
{
int num_entries;
int max_entries;
list_entry *files;
};
void addfile(flist *list, char* filename, char* root)
{
if (list->num_entries == list->max_entries)
{
int newsize = list->max_entries == 0 ? 16 : list->max_entries * 2;
list_entry *temp;
if (list->files == NULL)
{ temp = (list_entry *) malloc(newsize * sizeof(list_entry));
}
else
{ temp = (list_entry *) realloc(list->files, newsize * sizeof(list_entry));
}
if (temp == NULL)
{ fprintf(stderr, "Out of memory\n");
exit(1);
}
else
{ list->max_entries = newsize;
list->files = temp;
} }
list->files[list->num_entries].name = new string(root);
*(list->files[list->num_entries].name) += "\\";
*(list->files[list->num_entries].name) += filename;
list->num_entries++;
}
int sortfiles(const void *a, const void *b)
{
const WIN32_FIND_DATA *pa = (WIN32_FIND_DATA *) a;
const WIN32_FIND_DATA *pb = (WIN32_FIND_DATA *) b;
int a_is_dir = pa->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
int b_is_dir = pb->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
if (a_is_dir ^ b_is_dir)
{
// one of each, prefer the directories first
if (a_is_dir) return(-1);
if (b_is_dir) return(+1);
return(0);
}
else
{
// both files, or both directories - return the strcmp result
return(strcmp(pa->cFileName, pb->cFileName));
}
}
void doit(char *root, flist* list)
{
HANDLE h;
WIN32_FIND_DATA info;
// build a list of files
h = FindFirstFile("*.*", &info);
if (h != INVALID_HANDLE_VALUE)
{ do
{ if (!(strcmp(info.cFileName, ".") == 0 || strcmp(info.cFileName, "..") == 0))
{ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
char newroot[MAX_PATH];
sprintf(newroot, "%s\\%s", root, info.cFileName);
SetCurrentDirectory(info.cFileName);
doit(newroot, list);
SetCurrentDirectory("..");
}
else
{ addfile(list, info.cFileName, root);
}
}
} while (FindNextFile(h, &info));
if (GetLastError() != ERROR_NO_MORE_FILES)
{ fprintf(stderr, "file scan error\n");
exit(1);
}
FindClose(h);
}
else
{ fprintf(stderr, "handle error\n");
exit(1);
}
}
void WIN_get_file_list(char* directory)
{
struct flist my_list;
my_list.num_entries = 0;
my_list.max_entries = 0;
my_list.files = NULL;
char olddir[MAX_PATH];
if (GetCurrentDirectory(MAX_PATH, olddir) == 0)
{ fprintf(stderr, "can't get current directory %s\n", olddir);
exit(1);
}
if (!SetCurrentDirectory(directory))
{ fprintf(stderr, "can't get scan directory %s\n", directory);
exit(1);
}
doit(".", &my_list);
qsort(my_list.files, my_list.num_entries, sizeof(my_list.files[0]), sortfiles);
SetCurrentDirectory(olddir);
}
--
MattWalsh - 07 Jan 2006