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

Topic revision: r2 - 08 Jan 2006 - MattWalsh
 
This site is powered by the TWiki collaboration platformCopyright © 2008-2012 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback