/*
 * CMD - Wine-compatible command line interface - Directory functions.
 *
 * Copyright (C) 1999 D A Pickles
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

/*
 * NOTES:
 * On entry, global variables quals, param1, param2 contain
 * the qualifiers (uppercased and concatenated) and parameters entered, with
 * environment-variable and batch parameter substitution already done.
 */

#define WIN32_LEAN_AND_MEAN

#include "wcmd.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(cmd);

int WCMD_dir_sort (const void *a, const void *b);
char * WCMD_filesize64 (ULONGLONG free);
char * WCMD_strrev (char *buff);
static void WCMD_getfileowner(char *filename, char *owner, int ownerlen);
static void WCMD_dir_trailer(char drive);

extern int echo_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
extern DWORD errorlevel;

typedef enum _DISPLAYTIME
{
    Creation = 0,
    Access,
    Written
} DISPLAYTIME;

typedef enum _DISPLAYORDER
{
    Name = 0,
    Extension,
    Size,
    Date
} DISPLAYORDER;

typedef struct _DIRECTORY_STACK
{
  struct _DIRECTORY_STACK *next;
  char  *dirName;
  char  *fileName;
} DIRECTORY_STACK;

static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *parms, int level);
static int file_total, dir_total, recurse, wide, bare, max_width, lower;
static int shortname, usernames;
static ULONGLONG byte_total;
static DISPLAYTIME dirTime;
static DISPLAYORDER dirOrder;
static BOOL orderReverse, orderGroupDirs, orderGroupDirsReverse, orderByCol;
static BOOL separator;
static ULONG showattrs, attrsbits;

/*****************************************************************************
 * WCMD_directory
 *
 * List a file directory.
 *
 */

void WCMD_directory (char *cmd) {

  char path[MAX_PATH], cwd[MAX_PATH];
  int status, paged_mode;
  CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
  char *p;
  char string[MAXSTRING];
  int   argno         = 0;
  int   argsProcessed = 0;
  char *argN          = cmd;
  char  lastDrive;
  BOOL  trailerReqd = FALSE;
  DIRECTORY_STACK *fullParms = NULL;
  DIRECTORY_STACK *prevEntry = NULL;
  DIRECTORY_STACK *thisEntry = NULL;
  char drive[10];
  char dir[MAX_PATH];
  char fname[MAX_PATH];
  char ext[MAX_PATH];

  errorlevel = 0;

  /* Prefill Quals with (uppercased) DIRCMD env var */
  if (GetEnvironmentVariable ("DIRCMD", string, sizeof(string))) {
    p = string;
    while ( (*p = toupper(*p)) ) ++p;
    strcat(string,quals);
    strcpy(quals, string);
  }

  byte_total = 0;
  file_total = dir_total = 0;

  /* Initialize all flags to their defaults as if no DIRCMD or quals */
  paged_mode = FALSE;
  recurse    = FALSE;
  wide       = FALSE;
  bare       = FALSE;
  lower      = FALSE;
  shortname  = FALSE;
  usernames  = FALSE;
  orderByCol = FALSE;
  separator  = TRUE;
  dirTime = Written;
  dirOrder = Name;
  orderReverse = FALSE;
  orderGroupDirs = FALSE;
  orderGroupDirsReverse = FALSE;
  showattrs  = 0;
  attrsbits  = 0;

  /* Handle args - Loop through so right most is the effective one */
  /* Note: /- appears to be a negate rather than an off, eg. dir
           /-W is wide, or dir /w /-w /-w is also wide             */
  p = quals;
  while (*p && (*p=='/' || *p==' ')) {
    BOOL negate = FALSE;
    if (*p++==' ') continue;  /* Skip / and blanks introduced through DIRCMD */

    if (*p=='-') {
      negate = TRUE;
      p++;
    }

    WINE_TRACE("Processing arg '%c' (in %s)\n", *p, quals);
    switch (*p) {
    case 'P': if (negate) paged_mode = !paged_mode;
              else paged_mode = TRUE;
              break;
    case 'S': if (negate) recurse = !recurse;
              else recurse = TRUE;
              break;
    case 'W': if (negate) wide = !wide;
              else wide = TRUE;
              break;
    case 'B': if (negate) bare = !bare;
              else bare = TRUE;
              break;
    case 'L': if (negate) lower = !lower;
              else lower = TRUE;
              break;
    case 'X': if (negate) shortname = !shortname;
              else shortname = TRUE;
              break;
    case 'Q': if (negate) usernames = !usernames;
              else usernames = TRUE;
              break;
    case 'D': if (negate) orderByCol = !orderByCol;
              else orderByCol = TRUE;
              break;
    case 'C': if (negate) separator = !separator;
              else separator = TRUE;
              break;
    case 'T': p = p + 1;
              if (*p==':') p++;  /* Skip optional : */

              if (*p == 'A') dirTime = Access;
              else if (*p == 'C') dirTime = Creation;
              else if (*p == 'W') dirTime = Written;

              /* Support /T and /T: with no parms, default to written */
              else if (*p == 0x00 || *p == '/') {
                dirTime = Written;
                p = p - 1; /* So when step on, move to '/' */
              } else {
                SetLastError(ERROR_INVALID_PARAMETER);
                WCMD_print_error();
                errorlevel = 1;
                return;
              }
              break;
    case 'O': p = p + 1;
              if (*p==':') p++;  /* Skip optional : */
              while (*p && *p != '/') {
                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, quals);
                switch (*p) {
                case 'N': dirOrder = Name;       break;
                case 'E': dirOrder = Extension;  break;
                case 'S': dirOrder = Size;       break;
                case 'D': dirOrder = Date;       break;
                case '-': if (*(p+1)=='G') orderGroupDirsReverse=TRUE;
                          else orderReverse = TRUE;
                          break;
                case 'G': orderGroupDirs = TRUE; break;
                default:
                    SetLastError(ERROR_INVALID_PARAMETER);
                    WCMD_print_error();
                    errorlevel = 1;
                    return;
                }
                p++;
              }
              p = p - 1; /* So when step on, move to '/' */
              break;
    case 'A': p = p + 1;
              showattrs = 0;
              attrsbits = 0;
              if (*p==':') p++;  /* Skip optional : */
              while (*p && *p != '/') {
                BOOL anegate = FALSE;
                ULONG mask;

                /* Note /A: - options are 'offs' not toggles */
                if (*p=='-') {
                  anegate = TRUE;
                  p++;
                }

                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, quals);
                switch (*p) {
                case 'D': mask = FILE_ATTRIBUTE_DIRECTORY; break;
                case 'H': mask = FILE_ATTRIBUTE_HIDDEN;    break;
                case 'S': mask = FILE_ATTRIBUTE_SYSTEM;    break;
                case 'R': mask = FILE_ATTRIBUTE_READONLY;  break;
                case 'A': mask = FILE_ATTRIBUTE_ARCHIVE;   break;
                default:
                    SetLastError(ERROR_INVALID_PARAMETER);
                    WCMD_print_error();
                    errorlevel = 1;
                    return;
                }

                /* Keep running list of bits we care about */
                attrsbits |= mask;

                /* Mask shows what MUST be in the bits we care about */
                if (anegate) showattrs = showattrs & ~mask;
                else showattrs |= mask;

                p++;
              }
              p = p - 1; /* So when step on, move to '/' */
              WINE_TRACE("Result: showattrs %x, bits %x\n", showattrs, attrsbits);
              break;
    default:
              SetLastError(ERROR_INVALID_PARAMETER);
              WCMD_print_error();
              errorlevel = 1;
              return;
    }
    p = p + 1;
  }

  /* Handle conflicting args and initialization */
  if (bare || shortname) wide = FALSE;
  if (bare) shortname = FALSE;
  if (wide) usernames = FALSE;
  if (orderByCol) wide = TRUE;

  if (wide) {
      if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
          max_width = consoleInfo.dwSize.X;
      else
          max_width = 80;
  }
  if (paged_mode) {
     WCMD_enter_paged_mode();
  }

  argno         = 0;
  argsProcessed = 0;
  argN          = cmd;
  GetCurrentDirectory (1024, cwd);
  strcat(cwd, "\\");

  /* Loop through all args, calculating full effective directory */
  fullParms = NULL;
  prevEntry = NULL;
  while (argN) {
    char fullname[MAXSTRING];
    char *thisArg = WCMD_parameter (cmd, argno++, &argN);
    if (argN && argN[0] != '/') {

      WINE_TRACE("Found parm '%s'\n", thisArg);
      if (thisArg[1] == ':' && thisArg[2] == '\\') {
        strcpy(fullname, thisArg);
      } else if (thisArg[1] == ':' && thisArg[2] != '\\') {
        char envvar[4];
        sprintf(envvar, "=%c:", thisArg[0]);
        if (!GetEnvironmentVariable(envvar, fullname, MAX_PATH)) {
          sprintf(fullname, "%c:", thisArg[0]);
        }
        strcat(fullname, "\\");
        strcat(fullname, &thisArg[2]);
      } else if (thisArg[0] == '\\') {
        strncpy(fullname, cwd, 2);
        fullname[2] = 0x00;
        strcat((fullname+2), thisArg);
      } else {
        strcpy(fullname, cwd);
        strcat(fullname, thisArg);
      }
      WINE_TRACE("Using location '%s'\n", fullname);

      status = GetFullPathName (fullname, sizeof(path), path, NULL);

      /*
       *  If the path supplied does not include a wildcard, and the endpoint of the
       *  path references a directory, we need to list the *contents* of that
       *  directory not the directory file itself.
       */
      if ((strchr(path, '*') == NULL) && (strchr(path, '%') == NULL)) {
        status = GetFileAttributes (path);
        if ((status != INVALID_FILE_ATTRIBUTES) && (status & FILE_ATTRIBUTE_DIRECTORY)) {
          if (path[strlen(path)-1] == '\\') {
            strcat (path, "*");
          }
          else {
            strcat (path, "\\*");
          }
        }
      } else {
        /* Special case wildcard search with no extension (ie parameters ending in '.') as
           GetFullPathName strips off the additional '.'                                  */
        if (fullname[strlen(fullname)-1] == '.') strcat(path, ".");
      }

      WINE_TRACE("Using path '%s'\n", path);
      thisEntry = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK));
      if (fullParms == NULL) fullParms = thisEntry;
      if (prevEntry != NULL) prevEntry->next = thisEntry;
      prevEntry = thisEntry;
      thisEntry->next = NULL;

      /* Split into components */
      WCMD_splitpath(path, drive, dir, fname, ext);
      WINE_TRACE("Path Parts: drive: '%s' dir: '%s' name: '%s' ext:'%s'\n",
                 drive, dir, fname, ext);

      thisEntry->dirName = HeapAlloc(GetProcessHeap(),0,strlen(drive)+strlen(dir)+1);
      strcpy(thisEntry->dirName, drive);
      strcat(thisEntry->dirName, dir);

      thisEntry->fileName = HeapAlloc(GetProcessHeap(),0,strlen(fname)+strlen(ext)+1);
      strcpy(thisEntry->fileName, fname);
      strcat(thisEntry->fileName, ext);

    }
  }

  /* If just 'dir' entered, a '*' parameter is assumed */
  if (fullParms == NULL) {
    WINE_TRACE("Inserting default '*'\n");
    fullParms = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0, sizeof(DIRECTORY_STACK));
    fullParms->next = NULL;
    fullParms->dirName = HeapAlloc(GetProcessHeap(),0,(strlen(cwd)+1));
    strcpy(fullParms->dirName, cwd);
    fullParms->fileName = HeapAlloc(GetProcessHeap(),0,2);
    strcpy(fullParms->fileName, "*");
  }

  lastDrive = '?';
  prevEntry = NULL;
  thisEntry = fullParms;
  trailerReqd = FALSE;

  while (thisEntry != NULL) {

    /* Output disk free (trailer) and volume information (header) if the drive
       letter changes */
    if (lastDrive != toupper(thisEntry->dirName[0])) {

      /* Trailer Information */
      if (lastDrive != '?') {
        trailerReqd = FALSE;
        WCMD_dir_trailer(prevEntry->dirName[0]);
      }

      lastDrive = toupper(thisEntry->dirName[0]);

      if (!bare) {
         char drive[3];

         WINE_TRACE("Writing volume for '%c:'\n", thisEntry->dirName[0]);
         strncpy(drive, thisEntry->dirName, 2);
         drive[2] = 0x00;
         status = WCMD_volume (0, drive);
         trailerReqd = TRUE;
         if (!status) {
           errorlevel = 1;
           goto exit;
         }
      }
    } else {
      if (!bare) WCMD_output ("\n\n");
    }

    /* Clear any errors from previous invocations, and process it */
    errorlevel = 0;
    prevEntry = thisEntry;
    thisEntry = WCMD_list_directory (thisEntry, 0);
  }

  /* Trailer Information */
  if (trailerReqd) {
    WCMD_dir_trailer(prevEntry->dirName[0]);
  }

exit:
  if (paged_mode) WCMD_leave_paged_mode();

  /* Free storage allocated for parms */
  while (fullParms != NULL) {
    prevEntry = fullParms;
    fullParms = prevEntry->next;
    HeapFree(GetProcessHeap(),0,prevEntry->dirName);
    HeapFree(GetProcessHeap(),0,prevEntry->fileName);
    HeapFree(GetProcessHeap(),0,prevEntry);
  }
}

/*****************************************************************************
 * WCMD_list_directory
 *
 * List a single file directory. This function (and those below it) can be called
 * recursively when the /S switch is used.
 *
 * FIXME: Assumes 24-line display for the /P qualifier.
 */

static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int level) {

  char string[1024], datestring[32], timestring[32];
  char real_path[MAX_PATH];
  WIN32_FIND_DATA *fd;
  FILETIME ft;
  SYSTEMTIME st;
  HANDLE hff;
  int dir_count, file_count, entry_count, i, widest, cur_width, tmp_width;
  int numCols, numRows;
  int rows, cols;
  ULARGE_INTEGER byte_count, file_size;
  DIRECTORY_STACK *parms;
  int concurrentDirs = 0;
  BOOL done_header = FALSE;


  dir_count = 0;
  file_count = 0;
  entry_count = 0;
  byte_count.QuadPart = 0;
  widest = 0;
  cur_width = 0;

  /* Loop merging all the files from consecutive parms which relate to the
     same directory. Note issuing a directory header with no contents
     mirrors what windows does                                            */
  parms = inputparms;
  fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATA));
  while (parms && strcmp(inputparms->dirName, parms->dirName) == 0) {
    concurrentDirs++;

    /* Work out the full path + filename */
    strcpy(real_path, parms->dirName);
    strcat(real_path, parms->fileName);

    /* Load all files into an in memory structure */
    WINE_TRACE("Looking for matches to '%s'\n", real_path);
    hff = FindFirstFile (real_path, (fd+entry_count));
    if (hff != INVALID_HANDLE_VALUE) {
      do {
        /* Skip any which are filtered out by attribute */
        if (((fd+entry_count)->dwFileAttributes & attrsbits) != showattrs) continue;

        entry_count++;

        /* Keep running track of longest filename for wide output */
        if (wide || orderByCol) {
           int tmpLen = strlen((fd+(entry_count-1))->cFileName) + 3;
           if ((fd+(entry_count-1))->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) tmpLen = tmpLen + 2;
           if (tmpLen > widest) widest = tmpLen;
        }

        fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATA));
        if (fd == NULL) {
          FindClose (hff);
          WCMD_output ("Memory Allocation Error");
          errorlevel = 1;
          return parms->next;
        }
      } while (FindNextFile(hff, (fd+entry_count)) != 0);
      FindClose (hff);
    }

    /* Work out the actual current directory name without a trailing \ */
    strcpy(real_path, parms->dirName);
    real_path[strlen(parms->dirName)-1] = 0x00;

    /* Output the results */
    if (!bare) {
       if (level != 0 && (entry_count > 0)) WCMD_output ("\n");
       if (!recurse || ((entry_count > 0) && done_header==FALSE)) {
           WCMD_output ("Directory of %s\n\n", real_path);
           done_header = TRUE;
       }
    }

    /* Move to next parm */
    parms = parms->next;
  }

  /* Handle case where everything is filtered out */
  if (entry_count > 0) {

    /* Sort the list of files */
    qsort (fd, entry_count, sizeof(WIN32_FIND_DATA), WCMD_dir_sort);

    /* Work out the number of columns */
    WINE_TRACE("%d entries, maxwidth=%d, widest=%d\n", entry_count, max_width, widest);
    if (wide || orderByCol) {
      numCols = max(1, (int)max_width / widest);
      numRows = entry_count / numCols;
      if (entry_count % numCols) numRows++;
    } else {
      numCols = 1;
      numRows = entry_count;
    }
    WINE_TRACE("cols=%d, rows=%d\n", numCols, numRows);

    for (rows=0; rows<numRows; rows++) {
     BOOL addNewLine = TRUE;
     for (cols=0; cols<numCols; cols++) {
      char username[24];

      /* Work out the index of the entry being pointed to */
      if (orderByCol) {
        i = (cols * numRows) + rows;
        if (i >= entry_count) continue;
      } else {
        i = (rows * numCols) + cols;
        if (i >= entry_count) continue;
      }

      /* /L convers all names to lower case */
      if (lower) {
          char *p = (fd+i)->cFileName;
          while ( (*p = tolower(*p)) ) ++p;
      }

      /* /Q gets file ownership information */
      if (usernames) {
          lstrcpy (string, inputparms->dirName);
          lstrcat (string, (fd+i)->cFileName);
          WCMD_getfileowner(string, username, sizeof(username));
      }

      if (dirTime == Written) {
        FileTimeToLocalFileTime (&(fd+i)->ftLastWriteTime, &ft);
      } else if (dirTime == Access) {
        FileTimeToLocalFileTime (&(fd+i)->ftLastAccessTime, &ft);
      } else {
        FileTimeToLocalFileTime (&(fd+i)->ftCreationTime, &ft);
      }
      FileTimeToSystemTime (&ft, &st);
      GetDateFormat (0, DATE_SHORTDATE, &st, NULL, datestring,
			sizeof(datestring));
      GetTimeFormat (0, TIME_NOSECONDS, &st,
			NULL, timestring, sizeof(timestring));

      if (wide) {

        tmp_width = cur_width;
        if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
            WCMD_output ("[%s]", (fd+i)->cFileName);
            dir_count++;
            tmp_width = tmp_width + strlen((fd+i)->cFileName) + 2;
        } else {
            WCMD_output ("%s", (fd+i)->cFileName);
            tmp_width = tmp_width + strlen((fd+i)->cFileName) ;
            file_count++;
            file_size.u.LowPart = (fd+i)->nFileSizeLow;
            file_size.u.HighPart = (fd+i)->nFileSizeHigh;
        byte_count.QuadPart += file_size.QuadPart;
        }
        cur_width = cur_width + widest;

        if ((cur_width + widest) > max_width) {
            cur_width = 0;
        } else {
            WCMD_output ("%*.s", (tmp_width - cur_width) ,"");
        }

      } else if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
        dir_count++;

        if (!bare) {
           WCMD_output ("%10s  %8s  <DIR>         ", datestring, timestring);
           if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
           if (usernames) WCMD_output ("%-23s", username);
           WCMD_output("%s",(fd+i)->cFileName);
        } else {
           if (!((strcmp((fd+i)->cFileName, ".") == 0) ||
                 (strcmp((fd+i)->cFileName, "..") == 0))) {
              WCMD_output ("%s%s", recurse?inputparms->dirName:"", (fd+i)->cFileName);
           } else {
              addNewLine = FALSE;
           }
        }
      }
      else {
        file_count++;
        file_size.u.LowPart = (fd+i)->nFileSizeLow;
        file_size.u.HighPart = (fd+i)->nFileSizeHigh;
        byte_count.QuadPart += file_size.QuadPart;
        if (!bare) {
           WCMD_output ("%10s  %8s    %10s  ", datestring, timestring,
                        WCMD_filesize64(file_size.QuadPart));
           if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
           if (usernames) WCMD_output ("%-23s", username);
           WCMD_output("%s",(fd+i)->cFileName);
        } else {
           WCMD_output ("%s%s", recurse?inputparms->dirName:"", (fd+i)->cFileName);
        }
      }
     }
     if (addNewLine) WCMD_output ("\n");
     cur_width = 0;
    }

    if (!bare) {
       if (file_count == 1) {
         WCMD_output ("       1 file %25s bytes\n", WCMD_filesize64 (byte_count.QuadPart));
       }
       else {
         WCMD_output ("%8d files %24s bytes\n", file_count, WCMD_filesize64 (byte_count.QuadPart));
       }
    }
    byte_total = byte_total + byte_count.QuadPart;
    file_total = file_total + file_count;
    dir_total = dir_total + dir_count;

    if (!bare && !recurse) {
       if (dir_count == 1) WCMD_output ("%8d directory         ", 1);
       else WCMD_output ("%8d directories", dir_count);
    }
  }
  HeapFree(GetProcessHeap(),0,fd);

  /* When recursing, look in all subdirectories for matches */
  if (recurse) {
    DIRECTORY_STACK *dirStack = NULL;
    DIRECTORY_STACK *lastEntry = NULL;
    WIN32_FIND_DATA finddata;

    /* Build path to search */
    strcpy(string, inputparms->dirName);
    strcat(string, "*");

    WINE_TRACE("Recursive, looking for '%s'\n", string);
    hff = FindFirstFile (string, &finddata);
    if (hff != INVALID_HANDLE_VALUE) {
      do {
        if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
            (strcmp(finddata.cFileName, "..") != 0) &&
            (strcmp(finddata.cFileName, ".") != 0)) {

          DIRECTORY_STACK *thisDir;
          int              dirsToCopy = concurrentDirs;

          /* Loop creating list of subdirs for all concurrent entries */
          parms = inputparms;
          while (dirsToCopy > 0) {
            dirsToCopy--;

            /* Work out search parameter in sub dir */
            strcpy (string, inputparms->dirName);
            strcat (string, finddata.cFileName);
            strcat (string, "\\");
            WINE_TRACE("Recursive, Adding to search list '%s'\n", string);

            /* Allocate memory, add to list */
            thisDir = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK));
            if (dirStack == NULL) dirStack = thisDir;
            if (lastEntry != NULL) lastEntry->next = thisDir;
            lastEntry = thisDir;
            thisDir->next = NULL;
            thisDir->dirName = HeapAlloc(GetProcessHeap(),0,(strlen(string)+1));
            strcpy(thisDir->dirName, string);
            thisDir->fileName = HeapAlloc(GetProcessHeap(),0,(strlen(parms->fileName)+1));
            strcpy(thisDir->fileName, parms->fileName);
            parms = parms->next;
          }
        }
      } while (FindNextFile(hff, &finddata) != 0);
      FindClose (hff);

      while (dirStack != NULL) {
        DIRECTORY_STACK *thisDir = dirStack;
        dirStack = WCMD_list_directory (thisDir, 1);
        while (thisDir != dirStack) {
          DIRECTORY_STACK *tempDir = thisDir->next;
          HeapFree(GetProcessHeap(),0,thisDir->dirName);
          HeapFree(GetProcessHeap(),0,thisDir->fileName);
          HeapFree(GetProcessHeap(),0,thisDir);
          thisDir = tempDir;
        }
      }
    }
  }

  /* Handle case where everything is filtered out */
  if ((file_total + dir_total == 0) && (level == 0)) {
    SetLastError (ERROR_FILE_NOT_FOUND);
    WCMD_print_error ();
    errorlevel = 1;
  }

  return parms;
}

/*****************************************************************************
 * WCMD_filesize64
 *
 * Convert a 64-bit number into a character string, with commas every three digits.
 * Result is returned in a static string overwritten with each call.
 * FIXME: There must be a better algorithm!
 */

char * WCMD_filesize64 (ULONGLONG n) {

  ULONGLONG q;
  unsigned int r, i;
  char *p;
  static char buff[32];

  p = buff;
  i = -3;
  do {
    if (separator && ((++i)%3 == 1)) *p++ = ',';
    q = n / 10;
    r = n - (q * 10);
    *p++ = r + '0';
    *p = '\0';
    n = q;
  } while (n != 0);
  WCMD_strrev (buff);
  return buff;
}

/*****************************************************************************
 * WCMD_strrev
 *
 * Reverse a character string in-place (strrev() is not available under unixen :-( ).
 */

char * WCMD_strrev (char *buff) {

  int r, i;
  char b;

  r = lstrlen (buff);
  for (i=0; i<r/2; i++) {
    b = buff[i];
    buff[i] = buff[r-i-1];
    buff[r-i-1] = b;
  }
  return (buff);
}


/*****************************************************************************
 * WCMD_dir_sort
 *
 * Sort based on the /O options supplied on the command line
 */
int WCMD_dir_sort (const void *a, const void *b)
{
  WIN32_FIND_DATA *filea = (WIN32_FIND_DATA *)a;
  WIN32_FIND_DATA *fileb = (WIN32_FIND_DATA *)b;
  int result = 0;

  /* If /OG or /O-G supplied, dirs go at the top or bottom, ignoring the
     requested sort order for the directory components                   */
  if (orderGroupDirs &&
      ((filea->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ||
       (fileb->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)))
  {
    BOOL aDir = filea->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
    if (aDir) result = -1;
    else result = 1;
    if (orderGroupDirsReverse) result = -result;
    return result;

  /* Order by Name: */
  } else if (dirOrder == Name) {
    result = lstrcmpi(filea->cFileName, fileb->cFileName);

  /* Order by Size: */
  } else if (dirOrder == Size) {
    ULONG64 sizea = (((ULONG64)filea->nFileSizeHigh) << 32) + filea->nFileSizeLow;
    ULONG64 sizeb = (((ULONG64)fileb->nFileSizeHigh) << 32) + fileb->nFileSizeLow;
    if( sizea < sizeb ) result = -1;
    else if( sizea == sizeb ) result = 0;
    else result = 1;

  /* Order by Date: (Takes into account which date (/T option) */
  } else if (dirOrder == Date) {

    FILETIME *ft;
    ULONG64 timea, timeb;

    if (dirTime == Written) {
      ft = &filea->ftLastWriteTime;
      timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
      ft = &fileb->ftLastWriteTime;
      timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
    } else if (dirTime == Access) {
      ft = &filea->ftLastAccessTime;
      timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
      ft = &fileb->ftLastAccessTime;
      timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
    } else {
      ft = &filea->ftCreationTime;
      timea = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
      ft = &fileb->ftCreationTime;
      timeb = (((ULONG64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
    }
    if( timea < timeb ) result = -1;
    else if( timea == timeb ) result = 0;
    else result = 1;

  /* Order by Extension: (Takes into account which date (/T option) */
  } else if (dirOrder == Extension) {
      char drive[10];
      char dir[MAX_PATH];
      char fname[MAX_PATH];
      char extA[MAX_PATH];
      char extB[MAX_PATH];

      /* Split into components */
      WCMD_splitpath(filea->cFileName, drive, dir, fname, extA);
      WCMD_splitpath(fileb->cFileName, drive, dir, fname, extB);
      result = lstrcmpi(extA, extB);
  }

  if (orderReverse) result = -result;
  return result;
}

/*****************************************************************************
 * WCMD_getfileowner
 *
 * Reverse a character string in-place (strrev() is not available under unixen :-( ).
 */
void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {

    ULONG sizeNeeded = 0;
    DWORD rc;
    char name[MAXSTRING];
    char domain[MAXSTRING];

    /* In case of error, return empty string */
    *owner = 0x00;

    /* Find out how much space we need for the owner security descritpor */
    GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, 0, 0, &sizeNeeded);
    rc = GetLastError();

    if(rc == ERROR_INSUFFICIENT_BUFFER && sizeNeeded > 0) {

        LPBYTE secBuffer;
        PSID pSID = NULL;
        BOOL defaulted = FALSE;
        ULONG nameLen = MAXSTRING;
        ULONG domainLen = MAXSTRING;
        SID_NAME_USE nameuse;

        secBuffer = (LPBYTE) HeapAlloc(GetProcessHeap(),0,sizeNeeded * sizeof(BYTE));
        if(!secBuffer) return;

        /* Get the owners security descriptor */
        if(!GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, secBuffer,
                            sizeNeeded, &sizeNeeded)) {
            HeapFree(GetProcessHeap(),0,secBuffer);
            return;
        }

        /* Get the SID from the SD */
        if(!GetSecurityDescriptorOwner(secBuffer, &pSID, &defaulted)) {
            HeapFree(GetProcessHeap(),0,secBuffer);
            return;
        }

        /* Convert to a username */
        if (LookupAccountSid(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) {
            snprintf(owner, ownerlen, "%s%c%s", domain, '\\', name);
        }
        HeapFree(GetProcessHeap(),0,secBuffer);
    }
    return;
}

/*****************************************************************************
 * WCMD_dir_trailer
 *
 * Print out the trailer for the supplied drive letter
 */
static void WCMD_dir_trailer(char drive) {
    ULARGE_INTEGER avail, total, freebytes;
    DWORD status;
    char driveName[4] = "c:\\";

    driveName[0] = drive;
    status = GetDiskFreeSpaceEx (driveName, &avail, &total, &freebytes);
    WINE_TRACE("Writing trailer for '%s' gave %d(%d)\n", driveName, status, GetLastError());

    if (errorlevel==0 && !bare) {
      if (recurse) {
        WCMD_output ("\n     Total files listed:\n%8d files%25s bytes\n",
             file_total, WCMD_filesize64 (byte_total));
        WCMD_output ("%8d directories %18s bytes free\n\n",
             dir_total, WCMD_filesize64 (freebytes.QuadPart));
      } else {
        WCMD_output (" %18s bytes free\n\n", WCMD_filesize64 (freebytes.QuadPart));
      }
    }
}
