/*
 * 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);


/* 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};


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


/* =========================================================================
 * 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;
}

/* =========================================================================
 * 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
 * ========================================================================= */
static int __cdecl 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

    __ms_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;
    }

    __ms_va_start(parms, format);
    SetLastError(NO_ERROR);
    len = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, format, 0, 0, output_bufW,
                   MAX_WRITECONSOLE_SIZE/sizeof(*output_bufW), &parms);
    __ms_va_end(parms);
    if (len == 0 && GetLastError() != NO_ERROR) {
      WINE_FIXME("Could not format string: le=%u, fmt=%s\n", GetLastError(), wine_dbgstr_w(format));
      return 0;
    }

    /* Try to write as unicode whenever we think it's a console */
    if (toConsole) {
      res = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
                          output_bufW, len, &nOut, NULL);
    }

    /* If writing to console has failed (ever) we assume it's 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;
}

/* =========================================================================
 * 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[] = {'%', '1', '\n', 0};
      XCOPY_wprintf(infostr, lpMsgBuf);
      LocalFree ((HLOCAL)lpMsgBuf);
    }
}


/* =========================================================================
 * 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 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;
}

/* =========================================================================
 * 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;
}

/* =========================================================================
   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[]   = {'%', '1', ' ', '-', '>', ' ',
                                               '%', '2', '\n', 0};

                    XCOPY_wprintf(infostr, copyFrom, copyTo);
                } else {
                    const WCHAR infostr[] = {'%', '1', '\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;
}


/* =========================================================================
   XCOPY_ParseCommandLine - Parses the command line
   ========================================================================= */
static BOOL is_whitespace(WCHAR c)
{
    return c == ' ' || c == '\t';
}

static WCHAR *skip_whitespace(WCHAR *p)
{
    for (; *p && is_whitespace(*p); p++);
    return p;
}

/* Windows XCOPY uses a simplified command line parsing algorithm
   that lacks the escaped-quote logic of build_argv(), because
   literal double quotes are illegal in any of its arguments.
   Example: 'XCOPY "c:\DIR A" "c:DIR B\"' is OK. */
static int find_end_of_word(const WCHAR *word, WCHAR **end)
{
    BOOL in_quotes = 0;
    const WCHAR *ptr = word;
    for (;;) {
        for (; *ptr != '\0' && *ptr != '"' &&
                 (in_quotes || !is_whitespace(*ptr)); ptr++);
        if (*ptr == '"') {
            in_quotes = !in_quotes;
            ptr++;
        }
        /* Odd number of double quotes is illegal for XCOPY */
        if (in_quotes && *ptr == '\0')
            return RC_INITERROR;
        if (*ptr == '\0' || (!in_quotes && is_whitespace(*ptr)))
            break;
    }
    *end = (WCHAR*)ptr;
    return RC_OK;
}

/* Remove all double quotes from a word */
static void strip_quotes(WCHAR *word, WCHAR **end)
{
    WCHAR *rp, *wp;
    for (rp = word, wp = word; *rp != '\0'; rp++) {
        if (*rp == '"')
            continue;
        if (wp < rp)
            *wp = *rp;
        wp++;
    }
    *wp = '\0';
    *end = wp;
}

static int XCOPY_ParseCommandLine(WCHAR *suppliedsource,
                                  WCHAR *supplieddestination, DWORD *pflags)
{
    const WCHAR EXCLUDE[]  = {'E', 'X', 'C', 'L', 'U', 'D', 'E', ':', 0};
    DWORD flags = *pflags;
    WCHAR *cmdline, *word, *end, *next;
    int rc = RC_INITERROR;

    cmdline = _wcsdup(GetCommandLineW());
    if (cmdline == NULL)
        return rc;

    /* Skip first arg, which is the program name */
    if ((rc = find_end_of_word(cmdline, &word)) != RC_OK)
        goto out;
    word = skip_whitespace(word);

    while (*word)
    {
        WCHAR first;
        if ((rc = find_end_of_word(word, &end)) != RC_OK)
            goto out;

        next = skip_whitespace(end);
        first = word[0];
        *end = '\0';
        strip_quotes(word, &end);
        WINE_TRACE("Processing Arg: '%s'\n", wine_dbgstr_w(word));

        /* First non-switch parameter is source, second is destination */
        if (first != '/') {
            if (suppliedsource[0] == 0x00) {
                lstrcpyW(suppliedsource, word);
            } else if (supplieddestination[0] == 0x00) {
                lstrcpyW(supplieddestination, word);
            } else {
                XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARMS));
                goto out;
            }
        } 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(word[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,
                                         &word[1], 8,
                                         EXCLUDE, -1) == 2) {
                        if (XCOPY_ProcessExcludeList(&word[9])) {
                          XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
                          goto out;
                        } else flags |= OPT_EXCLUDELIST;
                      } else flags |= OPT_EMPTYDIR | OPT_RECURSIVE;
                      break;

            /* D can be /D or /D: */
            case 'D': if (word[2]==':' && isdigit(word[3])) {
                          SYSTEMTIME st;
                          WCHAR     *pos = &word[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);
                              while (*pos && isdigit(*pos)) 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);
                              goto out;
                          }
                      } else {
                          flags |= OPT_DATENEWER;
                      }
                      break;

            case '-': if (toupper(word[2])=='Y')
                          flags &= ~OPT_NOPROMPT; break;
            case '?': XCOPY_wprintf(XCOPY_LoadMessage(STRING_HELP));
                      rc = RC_HELP;
                      goto out;
            default:
                WINE_TRACE("Unhandled parameter '%s'\n", wine_dbgstr_w(word));
                XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARM), word);
                goto out;
            }
        }
        word = next;
    }

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

    *pflags = flags;
    rc = RC_OK;

 out:
    free(cmdline);
    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 */
        /* Also if destination ends with backslash */
        if ((flags & OPT_ASSUMEDIR &&
            (wcschr(srcspec, '?') || wcschr(srcspec, '*'))) ||
            (supplieddestination[lstrlenW(supplieddestination)-1] == '\\')) {

            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;
}


/* =========================================================================
   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};

    /* 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;

    /*
     * Parse the command line
     */
    if ((rc = XCOPY_ParseCommandLine(suppliedsource, supplieddestination,
                                     &flags)) != RC_OK) {
        if (rc == RC_HELP)
            return RC_OK;
        else
            return rc;
    }

    /* 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 */
    rc = XCOPY_ProcessSourceParm(suppliedsource, sourcestem, sourcespec, flags);
    if (rc != RC_OK) return rc;

    /* Extract required information from destination specification */
    rc = XCOPY_ProcessDestParm(supplieddestination, destinationstem,
                               destinationspec, sourcespec, flags);
    if (rc != RC_OK) return rc;

    /* 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;

}
