/*
 * XCOPY - Wine-compatible xcopy program
 *
 * Copyright (C) 2007 J. Edmeades
 *
 * 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
 */

/*
 * FIXME:
 * This should now support all options listed in the xcopy help from
 * windows XP except:
 *  /Z - Copy from network drives in restartable mode
 *  /X - Copy file audit settings (sets /O)
 *  /O - Copy file ownership + ACL info
 *  /G - Copy encrypted files to unencrypted destination
 *  /V - Verifies files
 */

/*
 * Notes:
 * Apparently, valid return codes are:
 *   0 - OK
 *   1 - No files found to copy
 *   2 - CTRL+C during copy
 *   4 - Initialization error, or invalid source specification
 *   5 - Disk write error
 */


#include <stdio.h>
#include <windows.h>
#include <wine/debug.h>
#include <wine/unicode.h>
#include "xcopy.h"

WINE_DEFAULT_DEBUG_CHANNEL(xcopy);

/* Prototypes */
static int XCOPY_ProcessSourceParm(WCHAR *suppliedsource, WCHAR *stem,
                                   WCHAR *spec, DWORD flags);
static int XCOPY_ProcessDestParm(WCHAR *supplieddestination, WCHAR *stem,
                                 WCHAR *spec, WCHAR *srcspec, DWORD flags);
static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec,
                        WCHAR *deststem, WCHAR *destspec,
                        DWORD flags);
static BOOL XCOPY_CreateDirectory(const WCHAR* path);
static BOOL XCOPY_ProcessExcludeList(WCHAR* parms);
static BOOL XCOPY_ProcessExcludeFile(WCHAR* filename, WCHAR* endOfName);
static WCHAR *XCOPY_LoadMessage(UINT id);
static void XCOPY_FailMessage(DWORD err);
static int XCOPY_wprintf(const WCHAR *format, ...);

/* Typedefs */
typedef struct _EXCLUDELIST
{
  struct _EXCLUDELIST *next;
  WCHAR               *name;
} EXCLUDELIST;


/* Global variables */
static ULONG filesCopied           = 0;              /* Number of files copied  */
static EXCLUDELIST *excludeList    = NULL;           /* Excluded strings list   */
static FILETIME dateRange;                           /* Date range to copy after*/
static const WCHAR wchr_slash[]   = {'\\', 0};
static const WCHAR wchr_star[]    = {'*', 0};
static const WCHAR wchr_dot[]     = {'.', 0};
static const WCHAR wchr_dotdot[]  = {'.', '.', 0};

/* Constants (Mostly for widechars) */


/* To minimize stack usage during recursion, some temporary variables
   made global                                                        */
static WCHAR copyFrom[MAX_PATH];
static WCHAR copyTo[MAX_PATH];


/* =========================================================================
   main - Main entrypoint for the xcopy command

     Processes the args, and drives the actual copying
   ========================================================================= */
int wmain (int argc, WCHAR *argvW[])
{
    int     rc = 0;
    WCHAR   suppliedsource[MAX_PATH] = {0};   /* As supplied on the cmd line */
    WCHAR   supplieddestination[MAX_PATH] = {0};
    WCHAR   sourcestem[MAX_PATH] = {0};       /* Stem of source          */
    WCHAR   sourcespec[MAX_PATH] = {0};       /* Filespec of source      */
    WCHAR   destinationstem[MAX_PATH] = {0};  /* Stem of destination     */
    WCHAR   destinationspec[MAX_PATH] = {0};  /* Filespec of destination */
    WCHAR   copyCmd[MAXSTRING];               /* COPYCMD env var         */
    DWORD   flags = 0;                        /* Option flags            */
    const WCHAR PROMPTSTR1[]  = {'/', 'Y', 0};
    const WCHAR PROMPTSTR2[]  = {'/', 'y', 0};
    const WCHAR COPYCMD[]  = {'C', 'O', 'P', 'Y', 'C', 'M', 'D', 0};
    const WCHAR EXCLUDE[]  = {'E', 'X', 'C', 'L', 'U', 'D', 'E', ':', 0};

    /*
     * Parse the command line
     */

    /* Confirm at least one parameter */
    if (argc < 2) {
        XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARMS));
        return RC_INITERROR;
    }

    /* Preinitialize flags based on COPYCMD */
    if (GetEnvironmentVariableW(COPYCMD, copyCmd, MAXSTRING)) {
        if (wcsstr(copyCmd, PROMPTSTR1) != NULL ||
            wcsstr(copyCmd, PROMPTSTR2) != NULL) {
            flags |= OPT_NOPROMPT;
        }
    }

    /* FIXME: On UNIX, files starting with a '.' are treated as hidden under
       wine, but on windows these can be normal files. At least one installer
       uses files such as .packlist and (validly) expects them to be copied.
       Under wine, if we do not copy hidden files by default then they get
       lose                                                                   */
    flags |= OPT_COPYHIDSYS;

    /* Skip first arg, which is the program name */
    argvW++;

    while (argc > 1)
    {
        argc--;
        WINE_TRACE("Processing Arg: '%s'\n", wine_dbgstr_w(*argvW));

        /* First non-switch parameter is source, second is destination */
        if (*argvW[0] != '/') {
            if (suppliedsource[0] == 0x00) {
                lstrcpyW(suppliedsource, *argvW);
            } else if (supplieddestination[0] == 0x00) {
                lstrcpyW(supplieddestination, *argvW);
            } else {
                XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARMS));
                return RC_INITERROR;
            }
        } else {
            /* Process all the switch options
                 Note: Windows docs say /P prompts when dest is created
                       but tests show it is done for each src file
                       regardless of the destination                   */
            switch (toupper(argvW[0][1])) {
            case 'I': flags |= OPT_ASSUMEDIR;     break;
            case 'S': flags |= OPT_RECURSIVE;     break;
            case 'Q': flags |= OPT_QUIET;         break;
            case 'F': flags |= OPT_FULL;          break;
            case 'L': flags |= OPT_SIMULATE;      break;
            case 'W': flags |= OPT_PAUSE;         break;
            case 'T': flags |= OPT_NOCOPY | OPT_RECURSIVE; break;
            case 'Y': flags |= OPT_NOPROMPT;      break;
            case 'N': flags |= OPT_SHORTNAME;     break;
            case 'U': flags |= OPT_MUSTEXIST;     break;
            case 'R': flags |= OPT_REPLACEREAD;   break;
            case 'H': flags |= OPT_COPYHIDSYS;    break;
            case 'C': flags |= OPT_IGNOREERRORS;  break;
            case 'P': flags |= OPT_SRCPROMPT;     break;
            case 'A': flags |= OPT_ARCHIVEONLY;   break;
            case 'M': flags |= OPT_ARCHIVEONLY |
                               OPT_REMOVEARCH;    break;

            /* E can be /E or /EXCLUDE */
            case 'E': if (CompareStringW(LOCALE_USER_DEFAULT,
                                         NORM_IGNORECASE | SORT_STRINGSORT,
                                         &argvW[0][1], 8,
                                         EXCLUDE, -1) == 2) {
                        if (XCOPY_ProcessExcludeList(&argvW[0][9])) {
                          XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
                          return RC_INITERROR;
                        } else flags |= OPT_EXCLUDELIST;
                      } else flags |= OPT_EMPTYDIR | OPT_RECURSIVE;
                      break;

            /* D can be /D or /D: */
            case 'D': if ((argvW[0][2])==':' && isdigit(argvW[0][3])) {
                          SYSTEMTIME st;
                          WCHAR     *pos = &argvW[0][3];
                          BOOL       isError = FALSE;
                          memset(&st, 0x00, sizeof(st));

                          /* Parse the arg : Month */
                          st.wMonth = _wtol(pos);
                          while (*pos && isdigit(*pos)) pos++;
                          if (*pos++ != '-') isError = TRUE;

                          /* Parse the arg : Day */
                          if (!isError) {
                              st.wDay = _wtol(pos);
                              while (*pos && isdigit(*pos)) pos++;
                              if (*pos++ != '-') isError = TRUE;
                          }

                          /* Parse the arg : Day */
                          if (!isError) {
                              st.wYear = _wtol(pos);
                              if (st.wYear < 100) st.wYear+=2000;
                          }

                          if (!isError && SystemTimeToFileTime(&st, &dateRange)) {
                              SYSTEMTIME st;
                              WCHAR datestring[32], timestring[32];

                              flags |= OPT_DATERANGE;

                              /* Debug info: */
                              FileTimeToSystemTime (&dateRange, &st);
                              GetDateFormatW(0, DATE_SHORTDATE, &st, NULL, datestring,
                                             sizeof(datestring)/sizeof(WCHAR));
                              GetTimeFormatW(0, TIME_NOSECONDS, &st,
                                             NULL, timestring, sizeof(timestring)/sizeof(WCHAR));

                              WINE_TRACE("Date being used is: %s %s\n",
                                         wine_dbgstr_w(datestring), wine_dbgstr_w(timestring));
                          } else {
                              XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
                              return RC_INITERROR;
                          }
                      } else {
                          flags |= OPT_DATENEWER;
                      }
                      break;

            case '-': if (toupper(argvW[0][2])=='Y')
                          flags &= ~OPT_NOPROMPT; break;
            case '?': XCOPY_wprintf(XCOPY_LoadMessage(STRING_HELP));
                      return RC_OK;
            default:
                WINE_TRACE("Unhandled parameter '%s'\n", wine_dbgstr_w(*argvW));
                XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARM), *argvW);
                return RC_INITERROR;
            }
        }
        argvW++;
    }

    /* Default the destination if not supplied */
    if (supplieddestination[0] == 0x00)
        lstrcpyW(supplieddestination, wchr_dot);

    /* Trace out the supplied information */
    WINE_TRACE("Supplied parameters:\n");
    WINE_TRACE("Source      : '%s'\n", wine_dbgstr_w(suppliedsource));
    WINE_TRACE("Destination : '%s'\n", wine_dbgstr_w(supplieddestination));

    /* Extract required information from source specification */
    XCOPY_ProcessSourceParm(suppliedsource, sourcestem, sourcespec, flags);

    /* Extract required information from destination specification */
    XCOPY_ProcessDestParm(supplieddestination, destinationstem,
                               destinationspec, sourcespec, flags);

    /* Trace out the resulting information */
    WINE_TRACE("Resolved parameters:\n");
    WINE_TRACE("Source Stem : '%s'\n", wine_dbgstr_w(sourcestem));
    WINE_TRACE("Source Spec : '%s'\n", wine_dbgstr_w(sourcespec));
    WINE_TRACE("Dest   Stem : '%s'\n", wine_dbgstr_w(destinationstem));
    WINE_TRACE("Dest   Spec : '%s'\n", wine_dbgstr_w(destinationspec));

    /* Pause if necessary */
    if (flags & OPT_PAUSE) {
        DWORD count;
        char pausestr[10];

        XCOPY_wprintf(XCOPY_LoadMessage(STRING_PAUSE));
        ReadFile (GetStdHandle(STD_INPUT_HANDLE), pausestr, sizeof(pausestr),
                  &count, NULL);
    }

    /* Now do the hard work... */
    rc = XCOPY_DoCopy(sourcestem, sourcespec,
                destinationstem, destinationspec,
                flags);

    /* Clear up exclude list allocated memory */
    while (excludeList) {
        EXCLUDELIST *pos = excludeList;
        excludeList = excludeList -> next;
        HeapFree(GetProcessHeap(), 0, pos->name);
        HeapFree(GetProcessHeap(), 0, pos);
    }

    /* Finished - print trailer and exit */
    if (flags & OPT_SIMULATE) {
        XCOPY_wprintf(XCOPY_LoadMessage(STRING_SIMCOPY), filesCopied);
    } else if (!(flags & OPT_NOCOPY)) {
        XCOPY_wprintf(XCOPY_LoadMessage(STRING_COPY), filesCopied);
    }
    if (rc == RC_OK && filesCopied == 0) rc = RC_NOFILES;
    return rc;

}


/* =========================================================================
   XCOPY_ProcessSourceParm - Takes the supplied source parameter, and
     converts it into a stem and a filespec
   ========================================================================= */
static int XCOPY_ProcessSourceParm(WCHAR *suppliedsource, WCHAR *stem,
                                   WCHAR *spec, DWORD flags)
{
    WCHAR             actualsource[MAX_PATH];
    WCHAR            *starPos;
    WCHAR            *questPos;
    DWORD             attribs;

    /*
     * Validate the source, expanding to full path ensuring it exists
     */
    if (GetFullPathNameW(suppliedsource, MAX_PATH, actualsource, NULL) == 0) {
        WINE_FIXME("Unexpected failure expanding source path (%d)\n", GetLastError());
        return RC_INITERROR;
    }

    /* If full names required, convert to using the full path */
    if (flags & OPT_FULL) {
        lstrcpyW(suppliedsource, actualsource);
    }

    /*
     * Work out the stem of the source
     */

    /* If a directory is supplied, use that as-is (either fully or
          partially qualified)
       If a filename is supplied + a directory or drive path, use that
          as-is
       Otherwise
          If no directory or path specified, add eg. C:
          stem is Drive/Directory is bit up to last \ (or first :)
          spec is bit after that                                         */

    starPos = wcschr(suppliedsource, '*');
    questPos = wcschr(suppliedsource, '?');
    if (starPos || questPos) {
        attribs = 0x00;  /* Ensures skips invalid or directory check below */
    } else {
        attribs = GetFileAttributesW(actualsource);
    }

    if (attribs == INVALID_FILE_ATTRIBUTES) {
        XCOPY_FailMessage(GetLastError());
        return RC_INITERROR;

    /* Directory:
         stem should be exactly as supplied plus a '\', unless it was
          eg. C: in which case no slash required */
    } else if (attribs & FILE_ATTRIBUTE_DIRECTORY) {
        WCHAR lastChar;

        WINE_TRACE("Directory supplied\n");
        lstrcpyW(stem, suppliedsource);
        lastChar = stem[lstrlenW(stem)-1];
        if (lastChar != '\\' && lastChar != ':') {
            lstrcatW(stem, wchr_slash);
        }
        lstrcpyW(spec, wchr_star);

    /* File or wildcard search:
         stem should be:
           Up to and including last slash if directory path supplied
           If c:filename supplied, just the c:
           Otherwise stem should be the current drive letter + ':' */
    } else {
        WCHAR *lastDir;

        WINE_TRACE("Filename supplied\n");
        lastDir   = wcsrchr(suppliedsource, '\\');

        if (lastDir) {
            lstrcpyW(stem, suppliedsource);
            stem[(lastDir-suppliedsource) + 1] = 0x00;
            lstrcpyW(spec, (lastDir+1));
        } else if (suppliedsource[1] == ':') {
            lstrcpyW(stem, suppliedsource);
            stem[2] = 0x00;
            lstrcpyW(spec, suppliedsource+2);
        } else {
            WCHAR curdir[MAXSTRING];
            GetCurrentDirectoryW(sizeof(curdir)/sizeof(WCHAR), curdir);
            stem[0] = curdir[0];
            stem[1] = curdir[1];
            stem[2] = 0x00;
            lstrcpyW(spec, suppliedsource);
        }
    }

    return RC_OK;
}

/* =========================================================================
   XCOPY_ProcessDestParm - Takes the supplied destination parameter, and
     converts it into a stem
   ========================================================================= */
static int XCOPY_ProcessDestParm(WCHAR *supplieddestination, WCHAR *stem, WCHAR *spec,
                                 WCHAR *srcspec, DWORD flags)
{
    WCHAR  actualdestination[MAX_PATH];
    DWORD attribs;
    BOOL isDir = FALSE;

    /*
     * Validate the source, expanding to full path ensuring it exists
     */
    if (GetFullPathNameW(supplieddestination, MAX_PATH, actualdestination, NULL) == 0) {
        WINE_FIXME("Unexpected failure expanding source path (%d)\n", GetLastError());
        return RC_INITERROR;
    }

    /* Destination is either a directory or a file */
    attribs = GetFileAttributesW(actualdestination);

    if (attribs == INVALID_FILE_ATTRIBUTES) {

        /* If /I supplied and wildcard copy, assume directory */
        if (flags & OPT_ASSUMEDIR &&
            (wcschr(srcspec, '?') || wcschr(srcspec, '*'))) {

            isDir = TRUE;

        } else {
            DWORD count;
            char  answer[10] = "";
            WCHAR fileChar[2];
            WCHAR dirChar[2];

            /* Read the F and D characters from the resource file */
            wcscpy(fileChar, XCOPY_LoadMessage(STRING_FILE_CHAR));
            wcscpy(dirChar, XCOPY_LoadMessage(STRING_DIR_CHAR));

            while (answer[0] != fileChar[0] && answer[0] != dirChar[0]) {
                XCOPY_wprintf(XCOPY_LoadMessage(STRING_QISDIR), supplieddestination);

                ReadFile(GetStdHandle(STD_INPUT_HANDLE), answer, sizeof(answer), &count, NULL);
                WINE_TRACE("User answer %c\n", answer[0]);

                answer[0] = toupper(answer[0]);
            }

            if (answer[0] == dirChar[0]) {
                isDir = TRUE;
            } else {
                isDir = FALSE;
            }
        }
    } else {
        isDir = (attribs & FILE_ATTRIBUTE_DIRECTORY);
    }

    if (isDir) {
        lstrcpyW(stem, actualdestination);
        *spec = 0x00;

        /* Ensure ends with a '\' */
        if (stem[lstrlenW(stem)-1] != '\\') {
            lstrcatW(stem, wchr_slash);
        }

    } else {
        WCHAR drive[MAX_PATH];
        WCHAR dir[MAX_PATH];
        WCHAR fname[MAX_PATH];
        WCHAR ext[MAX_PATH];
        _wsplitpath(actualdestination, drive, dir, fname, ext);
        lstrcpyW(stem, drive);
        lstrcatW(stem, dir);
        lstrcpyW(spec, fname);
        lstrcatW(spec, ext);
    }
    return RC_OK;
}

/* =========================================================================
   XCOPY_DoCopy - Recursive function to copy files based on input parms
     of a stem and a spec

      This works by using FindFirstFile supplying the source stem and spec.
      If results are found, any non-directory ones are processed
      Then, if /S or /E is supplied, another search is made just for
      directories, and this function is called again for that directory

   ========================================================================= */
static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec,
                        WCHAR *deststem, WCHAR *destspec,
                        DWORD flags)
{
    WIN32_FIND_DATAW *finddata;
    HANDLE          h;
    BOOL            findres = TRUE;
    WCHAR           *inputpath, *outputpath;
    BOOL            copiedFile = FALSE;
    DWORD           destAttribs, srcAttribs;
    BOOL            skipFile;
    int             ret = 0;

    /* Allocate some working memory on heap to minimize footprint */
    finddata = HeapAlloc(GetProcessHeap(), 0, sizeof(WIN32_FIND_DATAW));
    inputpath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));
    outputpath = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR));

    /* Build the search info into a single parm */
    lstrcpyW(inputpath, srcstem);
    lstrcatW(inputpath, srcspec);

    /* Search 1 - Look for matching files */
    h = FindFirstFileW(inputpath, finddata);
    while (h != INVALID_HANDLE_VALUE && findres) {

        skipFile = FALSE;

        /* Ignore . and .. */
        if (lstrcmpW(finddata->cFileName, wchr_dot)==0 ||
            lstrcmpW(finddata->cFileName, wchr_dotdot)==0 ||
            finddata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

            WINE_TRACE("Skipping directory, . or .. (%s)\n", wine_dbgstr_w(finddata->cFileName));
        } else {

            /* Get the filename information */
            lstrcpyW(copyFrom, srcstem);
            if (flags & OPT_SHORTNAME) {
              lstrcatW(copyFrom, finddata->cAlternateFileName);
            } else {
              lstrcatW(copyFrom, finddata->cFileName);
            }

            lstrcpyW(copyTo, deststem);
            if (*destspec == 0x00) {
                if (flags & OPT_SHORTNAME) {
                    lstrcatW(copyTo, finddata->cAlternateFileName);
                } else {
                    lstrcatW(copyTo, finddata->cFileName);
                }
            } else {
                lstrcatW(copyTo, destspec);
            }

            /* Do the copy */
            WINE_TRACE("ACTION: Copy '%s' -> '%s'\n", wine_dbgstr_w(copyFrom),
                                                      wine_dbgstr_w(copyTo));
            if (!copiedFile && !(flags & OPT_SIMULATE)) XCOPY_CreateDirectory(deststem);

            /* See if allowed to copy it */
            srcAttribs = GetFileAttributesW(copyFrom);
            WINE_TRACE("Source attribs: %d\n", srcAttribs);

            if ((srcAttribs & FILE_ATTRIBUTE_HIDDEN) ||
                (srcAttribs & FILE_ATTRIBUTE_SYSTEM)) {

                if (!(flags & OPT_COPYHIDSYS)) {
                    skipFile = TRUE;
                }
            }

            if (!(srcAttribs & FILE_ATTRIBUTE_ARCHIVE) &&
                (flags & OPT_ARCHIVEONLY)) {
                skipFile = TRUE;
            }

            /* See if file exists */
            destAttribs = GetFileAttributesW(copyTo);
            WINE_TRACE("Dest attribs: %d\n", srcAttribs);

            /* Check date ranges if a destination file already exists */
            if (!skipFile && (flags & OPT_DATERANGE) &&
                (CompareFileTime(&finddata->ftLastWriteTime, &dateRange) < 0)) {
                WINE_TRACE("Skipping file as modified date too old\n");
                skipFile = TRUE;
            }

            /* If just /D supplied, only overwrite if src newer than dest */
            if (!skipFile && (flags & OPT_DATENEWER) &&
               (destAttribs != INVALID_FILE_ATTRIBUTES)) {
                HANDLE h = CreateFileW(copyTo, GENERIC_READ, FILE_SHARE_READ,
                                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
                                      NULL);
                if (h != INVALID_HANDLE_VALUE) {
                    FILETIME writeTime;
                    GetFileTime(h, NULL, NULL, &writeTime);

                    if (CompareFileTime(&finddata->ftLastWriteTime, &writeTime) <= 0) {
                        WINE_TRACE("Skipping file as dest newer or same date\n");
                        skipFile = TRUE;
                    }
                    CloseHandle(h);
                }
            }

            /* See if exclude list provided. Note since filenames are case
               insensitive, need to uppercase the filename before doing
               strstr                                                     */
            if (!skipFile && (flags & OPT_EXCLUDELIST)) {
                EXCLUDELIST *pos = excludeList;
                WCHAR copyFromUpper[MAX_PATH];

                /* Uppercase source filename */
                lstrcpyW(copyFromUpper, copyFrom);
                CharUpperBuffW(copyFromUpper, lstrlenW(copyFromUpper));

                /* Loop through testing each exclude line */
                while (pos) {
                    if (wcsstr(copyFromUpper, pos->name) != NULL) {
                        WINE_TRACE("Skipping file as matches exclude '%s'\n",
                                   wine_dbgstr_w(pos->name));
                        skipFile = TRUE;
                        pos = NULL;
                    } else {
                        pos = pos->next;
                    }
                }
            }

            /* Prompt each file if necessary */
            if (!skipFile && (flags & OPT_SRCPROMPT)) {
                DWORD count;
                char  answer[10];
                BOOL  answered = FALSE;
                WCHAR yesChar[2];
                WCHAR noChar[2];

                /* Read the Y and N characters from the resource file */
                wcscpy(yesChar, XCOPY_LoadMessage(STRING_YES_CHAR));
                wcscpy(noChar, XCOPY_LoadMessage(STRING_NO_CHAR));

                while (!answered) {
                    XCOPY_wprintf(XCOPY_LoadMessage(STRING_SRCPROMPT), copyFrom);
                    ReadFile (GetStdHandle(STD_INPUT_HANDLE), answer, sizeof(answer),
                              &count, NULL);

                    answered = TRUE;
                    if (toupper(answer[0]) == noChar[0])
                        skipFile = TRUE;
                    else if (toupper(answer[0]) != yesChar[0])
                        answered = FALSE;
                }
            }

            if (!skipFile &&
                destAttribs != INVALID_FILE_ATTRIBUTES && !(flags & OPT_NOPROMPT)) {
                DWORD count;
                char  answer[10];
                BOOL  answered = FALSE;
                WCHAR yesChar[2];
                WCHAR allChar[2];
                WCHAR noChar[2];

                /* Read the A,Y and N characters from the resource file */
                wcscpy(yesChar, XCOPY_LoadMessage(STRING_YES_CHAR));
                wcscpy(allChar, XCOPY_LoadMessage(STRING_ALL_CHAR));
                wcscpy(noChar, XCOPY_LoadMessage(STRING_NO_CHAR));

                while (!answered) {
                    XCOPY_wprintf(XCOPY_LoadMessage(STRING_OVERWRITE), copyTo);
                    ReadFile (GetStdHandle(STD_INPUT_HANDLE), answer, sizeof(answer),
                              &count, NULL);

                    answered = TRUE;
                    if (toupper(answer[0]) == allChar[0])
                        flags |= OPT_NOPROMPT;
                    else if (toupper(answer[0]) == noChar[0])
                        skipFile = TRUE;
                    else if (toupper(answer[0]) != yesChar[0])
                        answered = FALSE;
                }
            }

            /* See if it has to exist! */
            if (destAttribs == INVALID_FILE_ATTRIBUTES && (flags & OPT_MUSTEXIST)) {
                skipFile = TRUE;
            }

            /* Output a status message */
            if (!skipFile) {
                if (flags & OPT_QUIET) {
                    /* Skip message */
                } else if (flags & OPT_FULL) {
                    const WCHAR infostr[]   = {'%', 's', ' ', '-', '>', ' ',
                                               '%', 's', '\n', 0};

                    XCOPY_wprintf(infostr, copyFrom, copyTo);
                } else {
                    const WCHAR infostr[] = {'%', 's', '\n', 0};
                    XCOPY_wprintf(infostr, copyFrom);
                }

                /* If allowing overwriting of read only files, remove any
                   write protection                                       */
                if ((destAttribs & FILE_ATTRIBUTE_READONLY) &&
                    (flags & OPT_REPLACEREAD)) {
                    SetFileAttributesW(copyTo, destAttribs & ~FILE_ATTRIBUTE_READONLY);
                }

                copiedFile = TRUE;
                if (flags & OPT_SIMULATE || flags & OPT_NOCOPY) {
                    /* Skip copy */
                } else if (CopyFileW(copyFrom, copyTo, FALSE) == 0) {

                    DWORD error = GetLastError();
                    XCOPY_wprintf(XCOPY_LoadMessage(STRING_COPYFAIL),
                           copyFrom, copyTo, error);
                    XCOPY_FailMessage(error);

                    if (flags & OPT_IGNOREERRORS) {
                        skipFile = TRUE;
                    } else {
                        ret = RC_WRITEERROR;
                        goto cleanup;
                    }
                }

                /* If /M supplied, remove the archive bit after successful copy */
                if (!skipFile) {
                    if ((srcAttribs & FILE_ATTRIBUTE_ARCHIVE) &&
                        (flags & OPT_REMOVEARCH)) {
                        SetFileAttributesW(copyFrom, (srcAttribs & ~FILE_ATTRIBUTE_ARCHIVE));
                    }
                    filesCopied++;
                }
            }
        }

        /* Find next file */
        findres = FindNextFileW(h, finddata);
    }
    FindClose(h);

    /* Search 2 - do subdirs */
    if (flags & OPT_RECURSIVE) {
        lstrcpyW(inputpath, srcstem);
        lstrcatW(inputpath, wchr_star);
        findres = TRUE;
        WINE_TRACE("Processing subdirs with spec: %s\n", wine_dbgstr_w(inputpath));

        h = FindFirstFileW(inputpath, finddata);
        while (h != INVALID_HANDLE_VALUE && findres) {

            /* Only looking for dirs */
            if ((finddata->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
                (lstrcmpW(finddata->cFileName, wchr_dot) != 0) &&
                (lstrcmpW(finddata->cFileName, wchr_dotdot) != 0)) {

                WINE_TRACE("Handling subdir: %s\n", wine_dbgstr_w(finddata->cFileName));

                /* Make up recursive information */
                lstrcpyW(inputpath, srcstem);
                lstrcatW(inputpath, finddata->cFileName);
                lstrcatW(inputpath, wchr_slash);

                lstrcpyW(outputpath, deststem);
                if (*destspec == 0x00) {
                    lstrcatW(outputpath, finddata->cFileName);

                    /* If /E is supplied, create the directory now */
                    if ((flags & OPT_EMPTYDIR) &&
                        !(flags & OPT_SIMULATE))
                        XCOPY_CreateDirectory(outputpath);

                    lstrcatW(outputpath, wchr_slash);
                }

                XCOPY_DoCopy(inputpath, srcspec, outputpath, destspec, flags);
            }

            /* Find next one */
            findres = FindNextFileW(h, finddata);
        }
    }

cleanup:

    /* free up memory */
    HeapFree(GetProcessHeap(), 0, finddata);
    HeapFree(GetProcessHeap(), 0, inputpath);
    HeapFree(GetProcessHeap(), 0, outputpath);

    return ret;
}

/* =========================================================================
 * Routine copied from cmd.exe md command -
 * This works recursively. so creating dir1\dir2\dir3 will create dir1 and
 * dir2 if they do not already exist.
 * ========================================================================= */
static BOOL XCOPY_CreateDirectory(const WCHAR* path)
{
    int len;
    WCHAR *new_path;
    BOOL ret = TRUE;

    new_path = HeapAlloc(GetProcessHeap(),0, sizeof(WCHAR) * (lstrlenW(path)+1));
    lstrcpyW(new_path,path);

    while ((len = lstrlenW(new_path)) && new_path[len - 1] == '\\')
        new_path[len - 1] = 0;

    while (!CreateDirectoryW(new_path,NULL))
    {
        WCHAR *slash;
        DWORD last_error = GetLastError();
        if (last_error == ERROR_ALREADY_EXISTS)
            break;

        if (last_error != ERROR_PATH_NOT_FOUND)
        {
            ret = FALSE;
            break;
        }

        if (!(slash = wcsrchr(new_path,'\\')) && ! (slash = wcsrchr(new_path,'/')))
        {
            ret = FALSE;
            break;
        }

        len = slash - new_path;
        new_path[len] = 0;
        if (!XCOPY_CreateDirectory(new_path))
        {
            ret = FALSE;
            break;
        }
        new_path[len] = '\\';
    }
    HeapFree(GetProcessHeap(),0,new_path);
    return ret;
}

/* =========================================================================
 * Process the /EXCLUDE: file list, building up a list of substrings to
 * avoid copying
 * Returns TRUE on any failure
 * ========================================================================= */
static BOOL XCOPY_ProcessExcludeList(WCHAR* parms) {

    WCHAR *filenameStart = parms;

    WINE_TRACE("/EXCLUDE parms: '%s'\n", wine_dbgstr_w(parms));
    excludeList = NULL;

    while (*parms && *parms != ' ' && *parms != '/') {

        /* If found '+' then process the file found so far */
        if (*parms == '+') {
            if (XCOPY_ProcessExcludeFile(filenameStart, parms)) {
                return TRUE;
            }
            filenameStart = parms+1;
        }
        parms++;
    }

    if (filenameStart != parms) {
        if (XCOPY_ProcessExcludeFile(filenameStart, parms)) {
            return TRUE;
        }
    }

    return FALSE;
}

/* =========================================================================
 * Process a single file from the /EXCLUDE: file list, building up a list
 * of substrings to avoid copying
 * Returns TRUE on any failure
 * ========================================================================= */
static BOOL XCOPY_ProcessExcludeFile(WCHAR* filename, WCHAR* endOfName) {

    WCHAR   endChar = *endOfName;
    WCHAR   buffer[MAXSTRING];
    FILE   *inFile  = NULL;
    const WCHAR readTextMode[]  = {'r', 't', 0};

    /* Null terminate the filename (temporarily updates the filename hence
         parms not const)                                                 */
    *endOfName = 0x00;

    /* Open the file */
    inFile = _wfopen(filename, readTextMode);
    if (inFile == NULL) {
        XCOPY_wprintf(XCOPY_LoadMessage(STRING_OPENFAIL), filename);
        *endOfName = endChar;
        return TRUE;
    }

    /* Process line by line */
    while (fgetws(buffer, sizeof(buffer)/sizeof(WCHAR), inFile) != NULL) {
        EXCLUDELIST *thisEntry;
        int length = lstrlenW(buffer);

        /* Strip CRLF */
        buffer[length-1] = 0x00;

        /* If more than CRLF */
        if (length > 1) {
          thisEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCLUDELIST));
          thisEntry->next = excludeList;
          excludeList = thisEntry;
          thisEntry->name = HeapAlloc(GetProcessHeap(), 0,
                                      (length * sizeof(WCHAR))+1);
          lstrcpyW(thisEntry->name, buffer);
          CharUpperBuffW(thisEntry->name, length);
          WINE_TRACE("Read line : '%s'\n", wine_dbgstr_w(thisEntry->name));
        }
    }

    /* See if EOF or error occurred */
    if (!feof(inFile)) {
        XCOPY_wprintf(XCOPY_LoadMessage(STRING_READFAIL), filename);
        *endOfName = endChar;
        return TRUE;
    }

    /* Revert the input string to original form, and cleanup + return */
    *endOfName = endChar;
    fclose(inFile);
    return FALSE;
}

/* =========================================================================
 * Load a string from the resource file, handling any error
 * Returns string retrieved from resource file
 * ========================================================================= */
static WCHAR *XCOPY_LoadMessage(UINT id) {
    static WCHAR msg[MAXSTRING];
    const WCHAR failedMsg[]  = {'F', 'a', 'i', 'l', 'e', 'd', '!', 0};

    if (!LoadStringW(GetModuleHandleW(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) {
       WINE_FIXME("LoadString failed with %d\n", GetLastError());
       lstrcpyW(msg, failedMsg);
    }
    return msg;
}

/* =========================================================================
 * Load a string for a system error and writes it to the screen
 * Returns string retrieved from resource file
 * ========================================================================= */
static void XCOPY_FailMessage(DWORD err) {
    LPWSTR lpMsgBuf;
    int status;

    status = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
                            FORMAT_MESSAGE_FROM_SYSTEM,
                            NULL, err, 0,
                            (LPWSTR) &lpMsgBuf, 0, NULL);
    if (!status) {
      WINE_FIXME("FIXME: Cannot display message for error %d, status %d\n",
                 err, GetLastError());
    } else {
      const WCHAR infostr[] = {'%', 's', '\n', 0};
      XCOPY_wprintf(infostr, lpMsgBuf);
      LocalFree ((HLOCAL)lpMsgBuf);
    }
}

/* =========================================================================
 * Output a formatted unicode string. Ideally this will go to the console
 *  and hence required WriteConsoleW to output it, however if file i/o is
 *  redirected, it needs to be WriteFile'd using OEM (not ANSI) format
 * ========================================================================= */
int XCOPY_wprintf(const WCHAR *format, ...) {

    static WCHAR *output_bufW = NULL;
    static char  *output_bufA = NULL;
    static BOOL  toConsole    = TRUE;
    static BOOL  traceOutput  = FALSE;
#define MAX_WRITECONSOLE_SIZE 65535

    va_list parms;
    DWORD   nOut;
    int len;
    DWORD   res = 0;

    /*
     * Allocate buffer to use when writing to console
     * Note: Not freed - memory will be allocated once and released when
     *         xcopy ends
     */

    if (!output_bufW) output_bufW = HeapAlloc(GetProcessHeap(), 0,
                                              MAX_WRITECONSOLE_SIZE);
    if (!output_bufW) {
      WINE_FIXME("Out of memory - could not allocate 2 x 64K buffers\n");
      return 0;
    }

    va_start(parms, format);
    len = vsnprintfW(output_bufW, MAX_WRITECONSOLE_SIZE/sizeof(WCHAR), format, parms);
    va_end(parms);
    if (len < 0) {
      WINE_FIXME("String too long.\n");
      return 0;
    }

    /* Try to write as unicode all the time we think its a console */
    if (toConsole) {
      res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
                          output_bufW, len, &nOut, NULL);
    }

    /* If writing to console has failed (ever) we assume its file
       i/o so convert to OEM codepage and output                  */
    if (!res) {
      BOOL usedDefaultChar = FALSE;
      DWORD convertedChars;

      toConsole = FALSE;

      /*
       * Allocate buffer to use when writing to file. Not freed, as above
       */
      if (!output_bufA) output_bufA = HeapAlloc(GetProcessHeap(), 0,
                                                MAX_WRITECONSOLE_SIZE);
      if (!output_bufA) {
        WINE_FIXME("Out of memory - could not allocate 2 x 64K buffers\n");
        return 0;
      }

      /* Convert to OEM, then output */
      convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, output_bufW,
                          len, output_bufA, MAX_WRITECONSOLE_SIZE,
                          "?", &usedDefaultChar);
      WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), output_bufA, convertedChars,
                &nOut, FALSE);
    }

    /* Trace whether screen or console */
    if (!traceOutput) {
      WINE_TRACE("Writing to console? (%d)\n", toConsole);
      traceOutput = TRUE;
    }
    return nOut;
}
