/*
 * CMD - Wine-compatible command line interface.
 *
 * Copyright (C) 1999 - 2001 D A Pickles
 * 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:
 * - Cannot handle parameters in quotes
 * - Lots of functionality missing from builtins
 */

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

WINE_DEFAULT_DEBUG_CHANNEL(cmd);

const WCHAR inbuilt[][10] = {
        {'A','T','T','R','I','B','\0'},
        {'C','A','L','L','\0'},
        {'C','D','\0'},
        {'C','H','D','I','R','\0'},
        {'C','L','S','\0'},
        {'C','O','P','Y','\0'},
        {'C','T','T','Y','\0'},
        {'D','A','T','E','\0'},
        {'D','E','L','\0'},
        {'D','I','R','\0'},
        {'E','C','H','O','\0'},
        {'E','R','A','S','E','\0'},
        {'F','O','R','\0'},
        {'G','O','T','O','\0'},
        {'H','E','L','P','\0'},
        {'I','F','\0'},
        {'L','A','B','E','L','\0'},
        {'M','D','\0'},
        {'M','K','D','I','R','\0'},
        {'M','O','V','E','\0'},
        {'P','A','T','H','\0'},
        {'P','A','U','S','E','\0'},
        {'P','R','O','M','P','T','\0'},
        {'R','E','M','\0'},
        {'R','E','N','\0'},
        {'R','E','N','A','M','E','\0'},
        {'R','D','\0'},
        {'R','M','D','I','R','\0'},
        {'S','E','T','\0'},
        {'S','H','I','F','T','\0'},
        {'T','I','M','E','\0'},
        {'T','I','T','L','E','\0'},
        {'T','Y','P','E','\0'},
        {'V','E','R','I','F','Y','\0'},
        {'V','E','R','\0'},
        {'V','O','L','\0'},
        {'E','N','D','L','O','C','A','L','\0'},
        {'S','E','T','L','O','C','A','L','\0'},
        {'P','U','S','H','D','\0'},
        {'P','O','P','D','\0'},
        {'A','S','S','O','C','\0'},
        {'C','O','L','O','R','\0'},
        {'F','T','Y','P','E','\0'},
        {'M','O','R','E','\0'},
        {'E','X','I','T','\0'}
};

HINSTANCE hinst;
DWORD errorlevel;
int echo_mode = 1, verify_mode = 0, defaultColor = 7;
static int opt_c, opt_k, opt_s;
const WCHAR newline[] = {'\n','\0'};
static const WCHAR equalsW[] = {'=','\0'};
static const WCHAR closeBW[] = {')','\0'};
WCHAR anykey[100];
WCHAR version_string[100];
WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
BATCH_CONTEXT *context = NULL;
extern struct env_stack *pushd_directories;
static const WCHAR *pagedMessage = NULL;
static char  *output_bufA = NULL;
#define MAX_WRITECONSOLE_SIZE 65535
BOOL unicodePipes = FALSE;


/*******************************************************************
 * WCMD_output_asis_len - send output to current standard output
 *
 * 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 void WCMD_output_asis_len(const WCHAR *message, int len, HANDLE device) {

    DWORD   nOut= 0;
    DWORD   res = 0;

    /* If nothing to write, return (MORE does this sometimes) */
    if (!len) return;

    /* Try to write as unicode assuming it is to a console */
    res = WriteConsoleW(device, message, len, &nOut, NULL);

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

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

        /* Convert to OEM, then output */
        convertedChars = WideCharToMultiByte(GetConsoleOutputCP(), 0, message,
                            len, output_bufA, MAX_WRITECONSOLE_SIZE,
                            "?", &usedDefaultChar);
        WriteFile(device, output_bufA, convertedChars,
                  &nOut, FALSE);
      } else {
        WriteFile(device, message, len*sizeof(WCHAR),
                  &nOut, FALSE);
      }
    }
    return;
}

/*******************************************************************
 * WCMD_output - send output to current standard output device.
 *
 */

void WCMD_output (const WCHAR *format, ...) {

  va_list ap;
  WCHAR string[1024];
  int ret;

  va_start(ap,format);
  ret = vsnprintfW(string, sizeof(string)/sizeof(WCHAR), format, ap);
  if( ret >= (sizeof(string)/sizeof(WCHAR))) {
       WINE_ERR("Output truncated in WCMD_output\n" );
       ret = (sizeof(string)/sizeof(WCHAR)) - 1;
       string[ret] = '\0';
  }
  va_end(ap);
  WCMD_output_asis_len(string, ret, GetStdHandle(STD_OUTPUT_HANDLE));
}


static int line_count;
static int max_height;
static int max_width;
static BOOL paged_mode;
static int numChars;

void WCMD_enter_paged_mode(const WCHAR *msg)
{
  CONSOLE_SCREEN_BUFFER_INFO consoleInfo;

  if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) {
    max_height = consoleInfo.dwSize.Y;
    max_width  = consoleInfo.dwSize.X;
  } else {
    max_height = 25;
    max_width  = 80;
  }
  paged_mode = TRUE;
  line_count = 0;
  numChars   = 0;
  pagedMessage = (msg==NULL)? anykey : msg;
}

void WCMD_leave_paged_mode(void)
{
  paged_mode = FALSE;
  pagedMessage = NULL;
}

/***************************************************************************
 * WCMD_Readfile
 *
 *	Read characters in from a console/file, returning result in Unicode
 *      with signature identical to ReadFile
 */
BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
                          LPDWORD charsRead, const LPOVERLAPPED unused) {

    BOOL   res;

    /* Try to read from console as Unicode */
    res = ReadConsoleW(hIn, intoBuf, maxChars, charsRead, NULL);

    /* If reading from console has failed we assume its file
       i/o so read in and convert from OEM codepage               */
    if (!res) {

        DWORD numRead;
        /*
         * Allocate buffer to use when reading from file. Not freed
         */
        if (!output_bufA) output_bufA = HeapAlloc(GetProcessHeap(), 0,
                                                  MAX_WRITECONSOLE_SIZE);
        if (!output_bufA) {
          WINE_FIXME("Out of memory - could not allocate ansi 64K buffer\n");
          return 0;
        }

        /* Read from file (assume OEM codepage) */
        res = ReadFile(hIn, output_bufA, maxChars, &numRead, unused);

        /* Convert from OEM */
        *charsRead = MultiByteToWideChar(GetConsoleCP(), 0, output_bufA, numRead,
                         intoBuf, maxChars);

    }
    return res;
}

/*******************************************************************
 * WCMD_output_asis - send output to current standard output device.
 *        without formatting eg. when message contains '%'
 */
void WCMD_output_asis (const WCHAR *message) {
  DWORD count;
  const WCHAR* ptr;
  WCHAR string[1024];

  if (paged_mode) {
    do {
      ptr = message;
      while (*ptr && *ptr!='\n' && (numChars < max_width)) {
        numChars++;
        ptr++;
      };
      if (*ptr == '\n') ptr++;
      WCMD_output_asis_len(message, (ptr) ? ptr - message : strlenW(message),
                           GetStdHandle(STD_OUTPUT_HANDLE));
      if (ptr) {
        numChars = 0;
        if (++line_count >= max_height - 1) {
          line_count = 0;
          WCMD_output_asis_len(pagedMessage, strlenW(pagedMessage),
                               GetStdHandle(STD_OUTPUT_HANDLE));
          WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
                         sizeof(string)/sizeof(WCHAR), &count, NULL);
        }
      }
    } while (((message = ptr) != NULL) && (*ptr));
  } else {
    WCMD_output_asis_len(message, lstrlen(message),
                         GetStdHandle(STD_OUTPUT_HANDLE));
  }
}

/****************************************************************************
 * WCMD_print_error
 *
 * Print the message for GetLastError
 */

void WCMD_print_error (void) {
  LPVOID lpMsgBuf;
  DWORD error_code;
  int status;

  error_code = GetLastError ();
  status = FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
			  NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
  if (!status) {
    WINE_FIXME ("Cannot display message for error %d, status %d\n",
			error_code, GetLastError());
    return;
  }

  WCMD_output_asis_len(lpMsgBuf, lstrlen(lpMsgBuf),
                       GetStdHandle(STD_ERROR_HANDLE));
  LocalFree (lpMsgBuf);
  WCMD_output_asis_len (newline, lstrlen(newline),
                        GetStdHandle(STD_ERROR_HANDLE));
  return;
}

/******************************************************************************
 * WCMD_show_prompt
 *
 *	Display the prompt on STDout
 *
 */

static void WCMD_show_prompt (void) {

  int status;
  WCHAR out_string[MAX_PATH], curdir[MAX_PATH], prompt_string[MAX_PATH];
  WCHAR *p, *q;
  DWORD len;
  static const WCHAR envPrompt[] = {'P','R','O','M','P','T','\0'};

  len = GetEnvironmentVariable (envPrompt, prompt_string,
                                sizeof(prompt_string)/sizeof(WCHAR));
  if ((len == 0) || (len >= (sizeof(prompt_string)/sizeof(WCHAR)))) {
    const WCHAR dfltPrompt[] = {'$','P','$','G','\0'};
    strcpyW (prompt_string, dfltPrompt);
  }
  p = prompt_string;
  q = out_string;
  *q = '\0';
  while (*p != '\0') {
    if (*p != '$') {
      *q++ = *p++;
      *q = '\0';
    }
    else {
      p++;
      switch (toupper(*p)) {
        case '$':
	  *q++ = '$';
	  break;
	case 'A':
	  *q++ = '&';
	  break;
	case 'B':
	  *q++ = '|';
	  break;
	case 'C':
	  *q++ = '(';
	  break;
	case 'D':
	  GetDateFormat (LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, q, MAX_PATH);
	  while (*q) q++;
	  break;
	case 'E':
	  *q++ = '\E';
	  break;
	case 'F':
	  *q++ = ')';
	  break;
	case 'G':
	  *q++ = '>';
	  break;
	case 'H':
	  *q++ = '\b';
	  break;
	case 'L':
	  *q++ = '<';
	  break;
	case 'N':
          status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir);
	  if (status) {
	    *q++ = curdir[0];
	  }
	  break;
	case 'P':
          status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir);
	  if (status) {
	    strcatW (q, curdir);
	    while (*q) q++;
	  }
	  break;
	case 'Q':
	  *q++ = '=';
	  break;
	case 'S':
	  *q++ = ' ';
	  break;
	case 'T':
	  GetTimeFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL, q, MAX_PATH);
	  while (*q) q++;
	  break;
        case 'V':
	  strcatW (q, version_string);
	  while (*q) q++;
          break;
	case '_':
	  *q++ = '\n';
	  break;
	case '+':
	  if (pushd_directories) {
	    memset(q, '+', pushd_directories->u.stackdepth);
	    q = q + pushd_directories->u.stackdepth;
	  }
	  break;
      }
      p++;
      *q = '\0';
    }
  }
  WCMD_output_asis (out_string);
}


/*************************************************************************
 * WCMD_strdupW
 *    A wide version of strdup as its missing from unicode.h
 */
WCHAR *WCMD_strdupW(WCHAR *input) {
   int len=strlenW(input)+1;
   /* Note: Use malloc not HeapAlloc to emulate strdup */
   WCHAR *result = malloc(len * sizeof(WCHAR));
   memcpy(result, input, len * sizeof(WCHAR));
   return result;
}

/***************************************************************************
 * WCMD_strtrim_leading_spaces
 *
 *	Remove leading spaces from a string. Return a pointer to the first
 *	non-space character. Does not modify the input string
 */
WCHAR *WCMD_strtrim_leading_spaces (WCHAR *string) {

  WCHAR *ptr;

  ptr = string;
  while (*ptr == ' ') ptr++;
  return ptr;
}

/*************************************************************************
 * WCMD_opt_s_strip_quotes
 *
 *	Remove first and last quote WCHARacters, preserving all other text
 */
static void WCMD_opt_s_strip_quotes(WCHAR *cmd) {
  WCHAR *src = cmd + 1, *dest = cmd, *lastq = NULL;
  while((*dest=*src) != '\0') {
      if (*src=='\"')
          lastq=dest;
      dest++, src++;
  }
  if (lastq) {
      dest=lastq++;
      while ((*dest++=*lastq++) != 0)
          ;
  }
}


/*************************************************************************
 * WCMD_expand_envvar
 *
 *	Expands environment variables, allowing for WCHARacter substitution
 */
static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
    WCHAR *endOfVar = NULL, *s;
    WCHAR *colonpos = NULL;
    WCHAR thisVar[MAXSTRING];
    WCHAR thisVarContents[MAXSTRING];
    WCHAR savedchar = 0x00;
    int len;

    static const WCHAR ErrorLvl[]  = {'E','R','R','O','R','L','E','V','E','L','\0'};
    static const WCHAR ErrorLvlP[] = {'%','E','R','R','O','R','L','E','V','E','L','%','\0'};
    static const WCHAR Date[]      = {'D','A','T','E','\0'};
    static const WCHAR DateP[]     = {'%','D','A','T','E','%','\0'};
    static const WCHAR Time[]      = {'T','I','M','E','\0'};
    static const WCHAR TimeP[]     = {'%','T','I','M','E','%','\0'};
    static const WCHAR Cd[]        = {'C','D','\0'};
    static const WCHAR CdP[]       = {'%','C','D','%','\0'};
    static const WCHAR Random[]    = {'R','A','N','D','O','M','\0'};
    static const WCHAR RandomP[]   = {'%','R','A','N','D','O','M','%','\0'};
    static const WCHAR Delims[]    = {'%',' ',':','\0'};

    WINE_TRACE("Expanding: %s (%s,%s)\n", wine_dbgstr_w(start),
               wine_dbgstr_w(forVal), wine_dbgstr_w(forVar));

    /* Find the end of the environment variable, and extract name */
    endOfVar = strpbrkW(start+1, Delims);

    if (endOfVar == NULL || *endOfVar==' ') {

      /* In batch program, missing terminator for % and no following
         ':' just removes the '%'                                   */
      if (context) {
        s = WCMD_strdupW(start + 1);
        strcpyW (start, s);
        free(s);
        return start;
      } else {

        /* In command processing, just ignore it - allows command line
           syntax like: for %i in (a.a) do echo %i                     */
        return start+1;
      }
    }

    /* If ':' found, process remaining up until '%' (or stop at ':' if
       a missing '%' */
    if (*endOfVar==':') {
        WCHAR *endOfVar2 = strchrW(endOfVar+1, '%');
        if (endOfVar2 != NULL) endOfVar = endOfVar2;
    }

    memcpy(thisVar, start, ((endOfVar - start) + 1) * sizeof(WCHAR));
    thisVar[(endOfVar - start)+1] = 0x00;
    colonpos = strchrW(thisVar+1, ':');

    /* If there's complex substitution, just need %var% for now
       to get the expanded data to play with                    */
    if (colonpos) {
        *colonpos = '%';
        savedchar = *(colonpos+1);
        *(colonpos+1) = 0x00;
    }

    WINE_TRACE("Retrieving contents of %s\n", wine_dbgstr_w(thisVar));

    /* Expand to contents, if unchanged, return */
    /* Handle DATE, TIME, ERRORLEVEL and CD replacements allowing */
    /* override if existing env var called that name              */
    if ((CompareString (LOCALE_USER_DEFAULT,
                        NORM_IGNORECASE | SORT_STRINGSORT,
                        thisVar, 12, ErrorLvlP, -1) == 2) &&
                (GetEnvironmentVariable(ErrorLvl, thisVarContents, 1) == 0) &&
                (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
      static const WCHAR fmt[] = {'%','d','\0'};
      wsprintf(thisVarContents, fmt, errorlevel);
      len = strlenW(thisVarContents);

    } else if ((CompareString (LOCALE_USER_DEFAULT,
                               NORM_IGNORECASE | SORT_STRINGSORT,
                               thisVar, 6, DateP, -1) == 2) &&
                (GetEnvironmentVariable(Date, thisVarContents, 1) == 0) &&
                (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {

      GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL,
                    NULL, thisVarContents, MAXSTRING);
      len = strlenW(thisVarContents);

    } else if ((CompareString (LOCALE_USER_DEFAULT,
                               NORM_IGNORECASE | SORT_STRINGSORT,
                               thisVar, 6, TimeP, -1) == 2) &&
                (GetEnvironmentVariable(Time, thisVarContents, 1) == 0) &&
                (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
      GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL,
                        NULL, thisVarContents, MAXSTRING);
      len = strlenW(thisVarContents);

    } else if ((CompareString (LOCALE_USER_DEFAULT,
                               NORM_IGNORECASE | SORT_STRINGSORT,
                               thisVar, 4, CdP, -1) == 2) &&
                (GetEnvironmentVariable(Cd, thisVarContents, 1) == 0) &&
                (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
      GetCurrentDirectory (MAXSTRING, thisVarContents);
      len = strlenW(thisVarContents);

    } else if ((CompareString (LOCALE_USER_DEFAULT,
                               NORM_IGNORECASE | SORT_STRINGSORT,
                               thisVar, 8, RandomP, -1) == 2) &&
                (GetEnvironmentVariable(Random, thisVarContents, 1) == 0) &&
                (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
      static const WCHAR fmt[] = {'%','d','\0'};
      wsprintf(thisVarContents, fmt, rand() % 32768);
      len = strlenW(thisVarContents);

    /* Look for a matching 'for' variable */
    } else if (forVar &&
               (CompareString (LOCALE_USER_DEFAULT,
                               SORT_STRINGSORT,
                               thisVar,
                               (colonpos - thisVar) - 1,
                               forVar, -1) == 2)) {
      strcpyW(thisVarContents, forVal);
      len = strlenW(thisVarContents);

    } else {

      len = ExpandEnvironmentStrings(thisVar, thisVarContents,
                               sizeof(thisVarContents)/sizeof(WCHAR));
    }

    if (len == 0)
      return endOfVar+1;

    /* In a batch program, unknown env vars are replaced with nothing,
         note syntax %garbage:1,3% results in anything after the ':'
         except the %
       From the command line, you just get back what you entered      */
    if (lstrcmpiW(thisVar, thisVarContents) == 0) {

      /* Restore the complex part after the compare */
      if (colonpos) {
        *colonpos = ':';
        *(colonpos+1) = savedchar;
      }

      /* Command line - just ignore this */
      if (context == NULL) return endOfVar+1;

      s = WCMD_strdupW(endOfVar + 1);

      /* Batch - replace unknown env var with nothing */
      if (colonpos == NULL) {
        strcpyW (start, s);

      } else {
        len = strlenW(thisVar);
        thisVar[len-1] = 0x00;
        /* If %:...% supplied, : is retained */
        if (colonpos == thisVar+1) {
          strcpyW (start, colonpos);
        } else {
          strcpyW (start, colonpos+1);
        }
        strcatW (start, s);
      }
      free (s);
      return start;

    }

    /* See if we need to do complex substitution (any ':'s), if not
       then our work here is done                                  */
    if (colonpos == NULL) {
      s = WCMD_strdupW(endOfVar + 1);
      strcpyW (start, thisVarContents);
      strcatW (start, s);
      free(s);
      return start;
    }

    /* Restore complex bit */
    *colonpos = ':';
    *(colonpos+1) = savedchar;

    /*
        Handle complex substitutions:
           xxx=yyy    (replace xxx with yyy)
           *xxx=yyy   (replace up to and including xxx with yyy)
           ~x         (from x WCHARs in)
           ~-x        (from x WCHARs from the end)
           ~x,y       (from x WCHARs in for y WCHARacters)
           ~x,-y      (from x WCHARs in until y WCHARacters from the end)
     */

    /* ~ is substring manipulation */
    if (savedchar == '~') {

      int   substrposition, substrlength = 0;
      WCHAR *commapos = strchrW(colonpos+2, ',');
      WCHAR *startCopy;

      substrposition = atolW(colonpos+2);
      if (commapos) substrlength = atolW(commapos+1);

      s = WCMD_strdupW(endOfVar + 1);

      /* Check bounds */
      if (substrposition >= 0) {
        startCopy = &thisVarContents[min(substrposition, len)];
      } else {
        startCopy = &thisVarContents[max(0, len+substrposition-1)];
      }

      if (commapos == NULL) {
        strcpyW (start, startCopy); /* Copy the lot */
      } else if (substrlength < 0) {

        int copybytes = (len+substrlength-1)-(startCopy-thisVarContents);
        if (copybytes > len) copybytes = len;
        else if (copybytes < 0) copybytes = 0;
        memcpy (start, startCopy, copybytes * sizeof(WCHAR)); /* Copy the lot */
        start[copybytes] = 0x00;
      } else {
        memcpy (start, startCopy, substrlength * sizeof(WCHAR)); /* Copy the lot */
        start[substrlength] = 0x00;
      }

      strcatW (start, s);
      free(s);
      return start;

    /* search and replace manipulation */
    } else {
      WCHAR *equalspos = strstrW(colonpos, equalsW);
      WCHAR *replacewith = equalspos+1;
      WCHAR *found       = NULL;
      WCHAR *searchIn;
      WCHAR *searchFor;

      s = WCMD_strdupW(endOfVar + 1);
      if (equalspos == NULL) return start+1;

      /* Null terminate both strings */
      thisVar[strlenW(thisVar)-1] = 0x00;
      *equalspos = 0x00;

      /* Since we need to be case insensitive, copy the 2 buffers */
      searchIn  = WCMD_strdupW(thisVarContents);
      CharUpperBuff(searchIn, strlenW(thisVarContents));
      searchFor = WCMD_strdupW(colonpos+1);
      CharUpperBuff(searchFor, strlenW(colonpos+1));


      /* Handle wildcard case */
      if (*(colonpos+1) == '*') {
        /* Search for string to replace */
        found = strstrW(searchIn, searchFor+1);

        if (found) {
          /* Do replacement */
          strcpyW(start, replacewith);
          strcatW(start, thisVarContents + (found-searchIn) + strlenW(searchFor+1));
          strcatW(start, s);
          free(s);
        } else {
          /* Copy as it */
          strcpyW(start, thisVarContents);
          strcatW(start, s);
        }

      } else {
        /* Loop replacing all instances */
        WCHAR *lastFound = searchIn;
        WCHAR *outputposn = start;

        *start = 0x00;
        while ((found = strstrW(lastFound, searchFor))) {
            lstrcpynW(outputposn,
                    thisVarContents + (lastFound-searchIn),
                    (found - lastFound)+1);
            outputposn  = outputposn + (found - lastFound);
            strcatW(outputposn, replacewith);
            outputposn = outputposn + strlenW(replacewith);
            lastFound = found + strlenW(searchFor);
        }
        strcatW(outputposn,
                thisVarContents + (lastFound-searchIn));
        strcatW(outputposn, s);
      }
      free(searchIn);
      free(searchFor);
      return start;
    }
    return start+1;
}

/*****************************************************************************
 * Expand the command. Native expands lines from batch programs as they are
 * read in and not again, except for 'for' variable substitution.
 * eg. As evidence, "echo %1 && shift && echo %1" or "echo %%path%%"
 */
static void handleExpansion(WCHAR *cmd, BOOL justFors, WCHAR *forVariable, WCHAR *forValue) {

  /* For commands in a context (batch program):                  */
  /*   Expand environment variables in a batch file %{0-9} first */
  /*     including support for any ~ modifiers                   */
  /* Additionally:                                               */
  /*   Expand the DATE, TIME, CD, RANDOM and ERRORLEVEL special  */
  /*     names allowing environment variable overrides           */
  /* NOTE: To support the %PATH:xxx% syntax, also perform        */
  /*   manual expansion of environment variables here            */

  WCHAR *p = cmd;
  WCHAR *s, *t;
  int   i;

  while ((p = strchrW(p, '%'))) {

    WINE_TRACE("Translate command:%s %d (at: %s)\n",
                   wine_dbgstr_w(cmd), justFors, wine_dbgstr_w(p));
    i = *(p+1) - '0';

    /* Don't touch %% unless its in Batch */
    if (!justFors && *(p+1) == '%') {
      if (context) {
        s = WCMD_strdupW(p+1);
        strcpyW (p, s);
        free (s);
      }
      p+=1;

    /* Replace %~ modifications if in batch program */
    } else if (*(p+1) == '~') {
      WCMD_HandleTildaModifiers(&p, forVariable, forValue, justFors);
      p++;

    /* Replace use of %0...%9 if in batch program*/
    } else if (!justFors && context && (i >= 0) && (i <= 9)) {
      s = WCMD_strdupW(p+2);
      t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
      strcpyW (p, t);
      strcatW (p, s);
      free (s);

    /* Replace use of %* if in batch program*/
    } else if (!justFors && context && *(p+1)=='*') {
      WCHAR *startOfParms = NULL;
      s = WCMD_strdupW(p+2);
      t = WCMD_parameter (context -> command, 1, &startOfParms);
      if (startOfParms != NULL) strcpyW (p, startOfParms);
      else *p = 0x00;
      strcatW (p, s);
      free (s);

    } else if (forVariable &&
               (CompareString (LOCALE_USER_DEFAULT,
                               SORT_STRINGSORT,
                               p,
                               strlenW(forVariable),
                               forVariable, -1) == 2)) {
      s = WCMD_strdupW(p + strlenW(forVariable));
      strcpyW(p, forValue);
      strcatW(p, s);
      free(s);

    } else if (!justFors) {
      p = WCMD_expand_envvar(p, forVariable, forValue);

    /* In a FOR loop, see if this is the variable to replace */
    } else { /* Ignore %'s on second pass of batch program */
      p++;
    }
  }

  return;
}


/*******************************************************************
 * WCMD_parse - parse a command into parameters and qualifiers.
 *
 *	On exit, all qualifiers are concatenated into q, the first string
 *	not beginning with "/" is in p1 and the
 *	second in p2. Any subsequent non-qualifier strings are lost.
 *	Parameters in quotes are handled.
 */
static void WCMD_parse (WCHAR *s, WCHAR *q, WCHAR *p1, WCHAR *p2)
{
  int p = 0;

  *q = *p1 = *p2 = '\0';
  while (TRUE) {
    switch (*s) {
      case '/':
        *q++ = *s++;
	while ((*s != '\0') && (*s != ' ') && *s != '/') {
	  *q++ = toupperW (*s++);
	}
        *q = '\0';
	break;
      case ' ':
      case '\t':
	s++;
	break;
      case '"':
	s++;
	while ((*s != '\0') && (*s != '"')) {
	  if (p == 0) *p1++ = *s++;
	  else if (p == 1) *p2++ = *s++;
	  else s++;
	}
        if (p == 0) *p1 = '\0';
        if (p == 1) *p2 = '\0';
        p++;
	if (*s == '"') s++;
	break;
      case '\0':
        return;
      default:
	while ((*s != '\0') && (*s != ' ') && (*s != '\t')
               && (*s != '=')  && (*s != ',') ) {
	  if (p == 0) *p1++ = *s++;
	  else if (p == 1) *p2++ = *s++;
	  else s++;
	}
        /* Skip concurrent parms */
	while ((*s == ' ') || (*s == '\t') || (*s == '=')  || (*s == ',') ) s++;

        if (p == 0) *p1 = '\0';
        if (p == 1) *p2 = '\0';
	p++;
    }
  }
}

static void init_msvcrt_io_block(STARTUPINFO* st)
{
    STARTUPINFO st_p;
    /* fetch the parent MSVCRT info block if any, so that the child can use the
     * same handles as its grand-father
     */
    st_p.cb = sizeof(STARTUPINFO);
    GetStartupInfo(&st_p);
    st->cbReserved2 = st_p.cbReserved2;
    st->lpReserved2 = st_p.lpReserved2;
    if (st_p.cbReserved2 && st_p.lpReserved2)
    {
        /* Override the entries for fd 0,1,2 if we happened
         * to change those std handles (this depends on the way wcmd sets
         * it's new input & output handles)
         */
        size_t sz = max(sizeof(unsigned) + (sizeof(char) + sizeof(HANDLE)) * 3, st_p.cbReserved2);
        BYTE* ptr = HeapAlloc(GetProcessHeap(), 0, sz);
        if (ptr)
        {
            unsigned num = *(unsigned*)st_p.lpReserved2;
            char* flags = (char*)(ptr + sizeof(unsigned));
            HANDLE* handles = (HANDLE*)(flags + num * sizeof(char));

            memcpy(ptr, st_p.lpReserved2, st_p.cbReserved2);
            st->cbReserved2 = sz;
            st->lpReserved2 = ptr;

#define WX_OPEN 0x01    /* see dlls/msvcrt/file.c */
            if (num <= 0 || (flags[0] & WX_OPEN))
            {
                handles[0] = GetStdHandle(STD_INPUT_HANDLE);
                flags[0] |= WX_OPEN;
            }
            if (num <= 1 || (flags[1] & WX_OPEN))
            {
                handles[1] = GetStdHandle(STD_OUTPUT_HANDLE);
                flags[1] |= WX_OPEN;
            }
            if (num <= 2 || (flags[2] & WX_OPEN))
            {
                handles[2] = GetStdHandle(STD_ERROR_HANDLE);
                flags[2] |= WX_OPEN;
            }
#undef WX_OPEN
        }
    }
}

/******************************************************************************
 * WCMD_run_program
 *
 *	Execute a command line as an external program. Must allow recursion.
 *
 *      Precedence:
 *        Manual testing under windows shows PATHEXT plays a key part in this,
 *      and the search algorithm and precedence appears to be as follows.
 *
 *      Search locations:
 *        If directory supplied on command, just use that directory
 *        If extension supplied on command, look for that explicit name first
 *        Otherwise, search in each directory on the path
 *      Precedence:
 *        If extension supplied on command, look for that explicit name first
 *        Then look for supplied name .* (even if extension supplied, so
 *          'garbage.exe' will match 'garbage.exe.cmd')
 *        If any found, cycle through PATHEXT looking for name.exe one by one
 *      Launching
 *        Once a match has been found, it is launched - Code currently uses
 *          findexecutable to achieve this which is left untouched.
 */

void WCMD_run_program (WCHAR *command, int called) {

  WCHAR  temp[MAX_PATH];
  WCHAR  pathtosearch[MAXSTRING];
  WCHAR *pathposn;
  WCHAR  stemofsearch[MAX_PATH];
  WCHAR *lastSlash;
  WCHAR  pathext[MAXSTRING];
  BOOL  extensionsupplied = FALSE;
  BOOL  launched = FALSE;
  BOOL  status;
  BOOL  assumeInternal = FALSE;
  DWORD len;
  static const WCHAR envPath[] = {'P','A','T','H','\0'};
  static const WCHAR envPathExt[] = {'P','A','T','H','E','X','T','\0'};
  static const WCHAR delims[] = {'/','\\',':','\0'};

  WCMD_parse (command, quals, param1, param2);	/* Quick way to get the filename */
  if (!(*param1) && !(*param2))
    return;

  /* Calculate the search path and stem to search for */
  if (strpbrkW (param1, delims) == NULL) {  /* No explicit path given, search path */
    static const WCHAR curDir[] = {'.',';','\0'};
    strcpyW(pathtosearch, curDir);
    len = GetEnvironmentVariable (envPath, &pathtosearch[2], (sizeof(pathtosearch)/sizeof(WCHAR))-2);
    if ((len == 0) || (len >= (sizeof(pathtosearch)/sizeof(WCHAR)) - 2)) {
      static const WCHAR curDir[] = {'.','\0'};
      strcpyW (pathtosearch, curDir);
    }
    if (strchrW(param1, '.') != NULL) extensionsupplied = TRUE;
    strcpyW(stemofsearch, param1);

  } else {

    /* Convert eg. ..\fred to include a directory by removing file part */
    GetFullPathName(param1, sizeof(pathtosearch)/sizeof(WCHAR), pathtosearch, NULL);
    lastSlash = strrchrW(pathtosearch, '\\');
    if (lastSlash && strchrW(lastSlash, '.') != NULL) extensionsupplied = TRUE;
    strcpyW(stemofsearch, lastSlash+1);

    /* Reduce pathtosearch to a path with trailing '\' to support c:\a.bat and
       c:\windows\a.bat syntax                                                 */
    if (lastSlash) *(lastSlash + 1) = 0x00;
  }

  /* Now extract PATHEXT */
  len = GetEnvironmentVariable (envPathExt, pathext, sizeof(pathext)/sizeof(WCHAR));
  if ((len == 0) || (len >= (sizeof(pathext)/sizeof(WCHAR)))) {
    static const WCHAR dfltPathExt[] = {'.','b','a','t',';',
                                        '.','c','o','m',';',
                                        '.','c','m','d',';',
                                        '.','e','x','e','\0'};
    strcpyW (pathext, dfltPathExt);
  }

  /* Loop through the search path, dir by dir */
  pathposn = pathtosearch;
  WINE_TRACE("Searching in '%s' for '%s'\n", wine_dbgstr_w(pathtosearch),
             wine_dbgstr_w(stemofsearch));
  while (!launched && pathposn) {

    WCHAR  thisDir[MAX_PATH] = {'\0'};
    WCHAR *pos               = NULL;
    BOOL  found             = FALSE;
    const WCHAR slashW[] = {'\\','\0'};

    /* Work on the first directory on the search path */
    pos = strchrW(pathposn, ';');
    if (pos) {
      memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR));
      thisDir[(pos-pathposn)] = 0x00;
      pathposn = pos+1;

    } else {
      strcpyW(thisDir, pathposn);
      pathposn = NULL;
    }

    /* Since you can have eg. ..\.. on the path, need to expand
       to full information                                      */
    strcpyW(temp, thisDir);
    GetFullPathName(temp, MAX_PATH, thisDir, NULL);

    /* 1. If extension supplied, see if that file exists */
    strcatW(thisDir, slashW);
    strcatW(thisDir, stemofsearch);
    pos = &thisDir[strlenW(thisDir)]; /* Pos = end of name */

    /* 1. If extension supplied, see if that file exists */
    if (extensionsupplied) {
      if (GetFileAttributes(thisDir) != INVALID_FILE_ATTRIBUTES) {
        found = TRUE;
      }
    }

    /* 2. Any .* matches? */
    if (!found) {
      HANDLE          h;
      WIN32_FIND_DATA finddata;
      static const WCHAR allFiles[] = {'.','*','\0'};

      strcatW(thisDir,allFiles);
      h = FindFirstFile(thisDir, &finddata);
      FindClose(h);
      if (h != INVALID_HANDLE_VALUE) {

        WCHAR *thisExt = pathext;

        /* 3. Yes - Try each path ext */
        while (thisExt) {
          WCHAR *nextExt = strchrW(thisExt, ';');

          if (nextExt) {
            memcpy(pos, thisExt, (nextExt-thisExt) * sizeof(WCHAR));
            pos[(nextExt-thisExt)] = 0x00;
            thisExt = nextExt+1;
          } else {
            strcpyW(pos, thisExt);
            thisExt = NULL;
          }

          if (GetFileAttributes(thisDir) != INVALID_FILE_ATTRIBUTES) {
            found = TRUE;
            thisExt = NULL;
          }
        }
      }
    }

   /* Internal programs won't be picked up by this search, so even
      though not found, try one last createprocess and wait for it
      to complete.
      Note: Ideally we could tell between a console app (wait) and a
      windows app, but the API's for it fail in this case           */
    if (!found && pathposn == NULL) {
        WINE_TRACE("ASSUMING INTERNAL\n");
        assumeInternal = TRUE;
    } else {
        WINE_TRACE("Found as %s\n", wine_dbgstr_w(thisDir));
    }

    /* Once found, launch it */
    if (found || assumeInternal) {
      STARTUPINFO st;
      PROCESS_INFORMATION pe;
      SHFILEINFO psfi;
      DWORD console;
      HINSTANCE hinst;
      WCHAR *ext = strrchrW( thisDir, '.' );
      static const WCHAR batExt[] = {'.','b','a','t','\0'};
      static const WCHAR cmdExt[] = {'.','c','m','d','\0'};

      launched = TRUE;

      /* Special case BAT and CMD */
      if (ext && !strcmpiW(ext, batExt)) {
        WCMD_batch (thisDir, command, called, NULL, INVALID_HANDLE_VALUE);
        return;
      } else if (ext && !strcmpiW(ext, cmdExt)) {
        WCMD_batch (thisDir, command, called, NULL, INVALID_HANDLE_VALUE);
        return;
      } else {

        /* thisDir contains the file to be launched, but with what?
           eg. a.exe will require a.exe to be launched, a.html may be iexplore */
        hinst = FindExecutable (thisDir, NULL, temp);
        if ((INT_PTR)hinst < 32)
          console = 0;
        else
          console = SHGetFileInfo (temp, 0, &psfi, sizeof(psfi), SHGFI_EXETYPE);

        ZeroMemory (&st, sizeof(STARTUPINFO));
        st.cb = sizeof(STARTUPINFO);
        init_msvcrt_io_block(&st);

        /* Launch the process and if a CUI wait on it to complete
           Note: Launching internal wine processes cannot specify a full path to exe */
        status = CreateProcess (assumeInternal?NULL : thisDir,
                                command, NULL, NULL, TRUE, 0, NULL, NULL, &st, &pe);
        if ((opt_c || opt_k) && !opt_s && !status
            && GetLastError()==ERROR_FILE_NOT_FOUND && command[0]=='\"') {
          /* strip first and last quote WCHARacters and try again */
          WCMD_opt_s_strip_quotes(command);
          opt_s=1;
          WCMD_run_program(command, called);
          return;
        }
        if (!status) {
          WCMD_print_error ();
          /* If a command fails to launch, it sets errorlevel 9009 - which
             does not seem to have any associated constant definition     */
          errorlevel = 9009;
          return;
        }
        if (!assumeInternal && !console) errorlevel = 0;
        else
        {
            /* Always wait when called in a batch program context */
            if (assumeInternal || context || !HIWORD(console)) WaitForSingleObject (pe.hProcess, INFINITE);
            GetExitCodeProcess (pe.hProcess, &errorlevel);
            if (errorlevel == STILL_ACTIVE) errorlevel = 0;
        }
        CloseHandle(pe.hProcess);
        CloseHandle(pe.hThread);
        return;
      }
    }
  }

  /* Not found anywhere - give up */
  SetLastError(ERROR_FILE_NOT_FOUND);
  WCMD_print_error ();

  /* If a command fails to launch, it sets errorlevel 9009 - which
     does not seem to have any associated constant definition     */
  errorlevel = 9009;
  return;

}

/*****************************************************************************
 * Process one command. If the command is EXIT this routine does not return.
 * We will recurse through here executing batch files.
 */
void WCMD_execute (WCHAR *command, WCHAR *redirects,
                   WCHAR *forVariable, WCHAR *forValue,
                   CMD_LIST **cmdList)
{
    WCHAR *cmd, *p, *redir;
    int status, i;
    DWORD count, creationDisposition;
    HANDLE h;
    WCHAR *whichcmd;
    SECURITY_ATTRIBUTES sa;
    WCHAR *new_cmd = NULL;
    WCHAR *new_redir = NULL;
    HANDLE old_stdhandles[3] = {GetStdHandle (STD_INPUT_HANDLE),
                                GetStdHandle (STD_OUTPUT_HANDLE),
                                GetStdHandle (STD_ERROR_HANDLE)};
    DWORD  idx_stdhandles[3] = {STD_INPUT_HANDLE,
                                STD_OUTPUT_HANDLE,
                                STD_ERROR_HANDLE};
    BOOL piped = FALSE;

    WINE_TRACE("command on entry:%s (%p), with '%s'='%s'\n",
               wine_dbgstr_w(command), cmdList,
               wine_dbgstr_w(forVariable), wine_dbgstr_w(forValue));

    /* If the next command is a pipe then we implement pipes by redirecting
       the output from this command to a temp file and input into the
       next command from that temp file.
       FIXME: Use of named pipes would make more sense here as currently this
       process has to finish before the next one can start but this requires
       a change to not wait for the first app to finish but rather the pipe  */
    if (cmdList && (*cmdList)->nextcommand &&
        (*cmdList)->nextcommand->prevDelim == CMD_PIPE) {

        WCHAR temp_path[MAX_PATH];
        static const WCHAR cmdW[]     = {'C','M','D','\0'};

        /* Remember piping is in action */
        WINE_TRACE("Output needs to be piped\n");
        piped = TRUE;

        /* Generate a unique temporary filename */
        GetTempPath (sizeof(temp_path)/sizeof(WCHAR), temp_path);
        GetTempFileName (temp_path, cmdW, 0, (*cmdList)->nextcommand->pipeFile);
        WINE_TRACE("Using temporary file of %s\n",
                   wine_dbgstr_w((*cmdList)->nextcommand->pipeFile));
    }

    /* Move copy of the command onto the heap so it can be expanded */
    new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING * sizeof(WCHAR));
    if (!new_cmd)
    {
        WINE_ERR("Could not allocate memory for new_cmd\n");
        return;
    }
    strcpyW(new_cmd, command);

    /* Move copy of the redirects onto the heap so it can be expanded */
    new_redir = HeapAlloc( GetProcessHeap(), 0, MAXSTRING * sizeof(WCHAR));
    if (!new_redir)
    {
        WINE_ERR("Could not allocate memory for new_redir\n");
        HeapFree( GetProcessHeap(), 0, new_cmd );
        return;
    }

    /* If piped output, send stdout to the pipe by appending >filename to redirects */
    if (piped) {
        static const WCHAR redirOut[] = {'%','s',' ','>',' ','%','s','\0'};
        wsprintf (new_redir, redirOut, redirects, (*cmdList)->nextcommand->pipeFile);
        WINE_TRACE("Redirects now %s\n", wine_dbgstr_w(new_redir));
    } else {
        strcpyW(new_redir, redirects);
    }

    /* Expand variables in command line mode only (batch mode will
       be expanded as the line is read in, except for 'for' loops) */
    handleExpansion(new_cmd, (context != NULL), forVariable, forValue);
    handleExpansion(new_redir, (context != NULL), forVariable, forValue);
    cmd = new_cmd;

    /* Show prompt before batch line IF echo is on and in batch program */
    if (context && echo_mode && (cmd[0] != '@')) {
      WCMD_show_prompt();
      WCMD_output_asis ( cmd);
      WCMD_output_asis ( newline);
    }

/*
 *	Changing default drive has to be handled as a special case.
 */

    if ((cmd[1] == ':') && IsCharAlpha (cmd[0]) && (strlenW(cmd) == 2)) {
      WCHAR envvar[5];
      WCHAR dir[MAX_PATH];

      /* According to MSDN CreateProcess docs, special env vars record
         the current directory on each drive, in the form =C:
         so see if one specified, and if so go back to it             */
      strcpyW(envvar, equalsW);
      strcatW(envvar, cmd);
      if (GetEnvironmentVariable(envvar, dir, MAX_PATH) == 0) {
        static const WCHAR fmt[] = {'%','s','\\','\0'};
        wsprintf(cmd, fmt, cmd);
        WINE_TRACE("No special directory settings, using dir of %s\n", wine_dbgstr_w(cmd));
      }
      WINE_TRACE("Got directory %s as %s\n", wine_dbgstr_w(envvar), wine_dbgstr_w(cmd));
      status = SetCurrentDirectory (cmd);
      if (!status) WCMD_print_error ();
      HeapFree( GetProcessHeap(), 0, cmd );
      HeapFree( GetProcessHeap(), 0, new_redir );
      return;
    }

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

/*
 *	Redirect stdin, stdout and/or stderr if required.
 */

    /* STDIN could come from a preceding pipe, so delete on close if it does */
    if (cmdList && (*cmdList)->pipeFile[0] != 0x00) {
        WINE_TRACE("Input coming from %s\n", wine_dbgstr_w((*cmdList)->pipeFile));
        h = CreateFile ((*cmdList)->pipeFile, GENERIC_READ,
                  FILE_SHARE_READ, &sa, OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
        if (h == INVALID_HANDLE_VALUE) {
          WCMD_print_error ();
          HeapFree( GetProcessHeap(), 0, cmd );
          HeapFree( GetProcessHeap(), 0, new_redir );
          return;
        }
        SetStdHandle (STD_INPUT_HANDLE, h);

        /* No need to remember the temporary name any longer once opened */
        (*cmdList)->pipeFile[0] = 0x00;

    /* Otherwise STDIN could come from a '<' redirect */
    } else if ((p = strchrW(new_redir,'<')) != NULL) {
      h = CreateFile (WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL, NULL);
      if (h == INVALID_HANDLE_VALUE) {
	WCMD_print_error ();
        HeapFree( GetProcessHeap(), 0, cmd );
        HeapFree( GetProcessHeap(), 0, new_redir );
	return;
      }
      SetStdHandle (STD_INPUT_HANDLE, h);
    }

    /* Scan the whole command looking for > and 2> */
    redir = new_redir;
    while (redir != NULL && ((p = strchrW(redir,'>')) != NULL)) {
      int handle = 0;

      if (*(p-1)!='2') {
        handle = 1;
      } else {
        handle = 2;
      }

      p++;
      if ('>' == *p) {
        creationDisposition = OPEN_ALWAYS;
        p++;
      }
      else {
        creationDisposition = CREATE_ALWAYS;
      }

      /* Add support for 2>&1 */
      redir = p;
      if (*p == '&') {
        int idx = *(p+1) - '0';

        if (DuplicateHandle(GetCurrentProcess(),
                        GetStdHandle(idx_stdhandles[idx]),
                        GetCurrentProcess(),
                        &h,
                        0, TRUE, DUPLICATE_SAME_ACCESS) == 0) {
          WINE_FIXME("Duplicating handle failed with gle %d\n", GetLastError());
        }
        WINE_TRACE("Redirect %d (%p) to %d (%p)\n", handle, GetStdHandle(idx_stdhandles[idx]), idx, h);

      } else {
        WCHAR *param = WCMD_parameter (p, 0, NULL);
        h = CreateFile (param, GENERIC_WRITE, 0, &sa, creationDisposition,
                        FILE_ATTRIBUTE_NORMAL, NULL);
        if (h == INVALID_HANDLE_VALUE) {
          WCMD_print_error ();
          HeapFree( GetProcessHeap(), 0, cmd );
          HeapFree( GetProcessHeap(), 0, new_redir );
          return;
        }
        if (SetFilePointer (h, 0, NULL, FILE_END) ==
              INVALID_SET_FILE_POINTER) {
          WCMD_print_error ();
        }
        WINE_TRACE("Redirect %d to '%s' (%p)\n", handle, wine_dbgstr_w(param), h);
      }

      SetStdHandle (idx_stdhandles[handle], h);
    }

/*
 * Strip leading whitespaces, and a '@' if supplied
 */
    whichcmd = WCMD_strtrim_leading_spaces(cmd);
    WINE_TRACE("Command: '%s'\n", wine_dbgstr_w(cmd));
    if (whichcmd[0] == '@') whichcmd++;

/*
 *	Check if the command entered is internal. If it is, pass the rest of the
 *	line down to the command. If not try to run a program.
 */

    count = 0;
    while (IsCharAlphaNumeric(whichcmd[count])) {
      count++;
    }
    for (i=0; i<=WCMD_EXIT; i++) {
      if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
        whichcmd, count, inbuilt[i], -1) == 2) break;
    }
    p = WCMD_strtrim_leading_spaces (&whichcmd[count]);
    WCMD_parse (p, quals, param1, param2);
    WINE_TRACE("param1: %s, param2: %s\n", wine_dbgstr_w(param1), wine_dbgstr_w(param2));

    switch (i) {

      case WCMD_ATTRIB:
        WCMD_setshow_attrib ();
        break;
      case WCMD_CALL:
        WCMD_call (p);
        break;
      case WCMD_CD:
      case WCMD_CHDIR:
        WCMD_setshow_default (p);
        break;
      case WCMD_CLS:
        WCMD_clear_screen ();
        break;
      case WCMD_COPY:
        WCMD_copy ();
        break;
      case WCMD_CTTY:
        WCMD_change_tty ();
        break;
      case WCMD_DATE:
        WCMD_setshow_date ();
	break;
      case WCMD_DEL:
      case WCMD_ERASE:
        WCMD_delete (p, TRUE);
        break;
      case WCMD_DIR:
        WCMD_directory (p);
        break;
      case WCMD_ECHO:
        WCMD_echo(&whichcmd[count]);
        break;
      case WCMD_FOR:
        WCMD_for (p, cmdList);
        break;
      case WCMD_GOTO:
        WCMD_goto (cmdList);
        break;
      case WCMD_HELP:
        WCMD_give_help (p);
	break;
      case WCMD_IF:
	WCMD_if (p, cmdList);
        break;
      case WCMD_LABEL:
        WCMD_volume (1, p);
        break;
      case WCMD_MD:
      case WCMD_MKDIR:
        WCMD_create_dir ();
	break;
      case WCMD_MOVE:
        WCMD_move ();
        break;
      case WCMD_PATH:
        WCMD_setshow_path (p);
        break;
      case WCMD_PAUSE:
        WCMD_pause ();
        break;
      case WCMD_PROMPT:
        WCMD_setshow_prompt ();
        break;
      case WCMD_REM:
        break;
      case WCMD_REN:
      case WCMD_RENAME:
        WCMD_rename ();
	break;
      case WCMD_RD:
      case WCMD_RMDIR:
        WCMD_remove_dir (p);
        break;
      case WCMD_SETLOCAL:
        WCMD_setlocal(p);
        break;
      case WCMD_ENDLOCAL:
        WCMD_endlocal();
        break;
      case WCMD_SET:
        WCMD_setshow_env (p);
	break;
      case WCMD_SHIFT:
        WCMD_shift (p);
        break;
      case WCMD_TIME:
        WCMD_setshow_time ();
        break;
      case WCMD_TITLE:
        if (strlenW(&whichcmd[count]) > 0)
          WCMD_title(&whichcmd[count+1]);
        break;
      case WCMD_TYPE:
        WCMD_type (p);
	break;
      case WCMD_VER:
        WCMD_version ();
        break;
      case WCMD_VERIFY:
        WCMD_verify (p);
        break;
      case WCMD_VOL:
        WCMD_volume (0, p);
        break;
      case WCMD_PUSHD:
        WCMD_pushd(p);
        break;
      case WCMD_POPD:
        WCMD_popd();
        break;
      case WCMD_ASSOC:
        WCMD_assoc(p, TRUE);
        break;
      case WCMD_COLOR:
        WCMD_color();
        break;
      case WCMD_FTYPE:
        WCMD_assoc(p, FALSE);
        break;
      case WCMD_MORE:
        WCMD_more(p);
        break;
      case WCMD_EXIT:
        WCMD_exit (cmdList);
        break;
      default:
        WCMD_run_program (whichcmd, 0);
    }
    HeapFree( GetProcessHeap(), 0, cmd );
    HeapFree( GetProcessHeap(), 0, new_redir );

    /* Restore old handles */
    for (i=0; i<3; i++) {
      if (old_stdhandles[i] != GetStdHandle(idx_stdhandles[i])) {
        CloseHandle (GetStdHandle (idx_stdhandles[i]));
        SetStdHandle (idx_stdhandles[i], old_stdhandles[i]);
      }
    }
}
/*************************************************************************
 * WCMD_LoadMessage
 *    Load a string from the resource file, handling any error
 *    Returns string retrieved from resource file
 */
WCHAR *WCMD_LoadMessage(UINT id) {
    static WCHAR msg[2048];
    static const WCHAR failedMsg[]  = {'F','a','i','l','e','d','!','\0'};

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

/***************************************************************************
 * WCMD_DumpCommands
 *
 *	Dumps out the parsed command line to ensure syntax is correct
 */
static void WCMD_DumpCommands(CMD_LIST *commands) {
    WCHAR buffer[MAXSTRING];
    CMD_LIST *thisCmd = commands;
    const WCHAR fmt[] = {'%','p',' ','%','d',' ','%','2','.','2','d',' ',
                         '%','p',' ','%','s',' ','R','e','d','i','r',':',
                         '%','s','\0'};

    WINE_TRACE("Parsed line:\n");
    while (thisCmd != NULL) {
      sprintfW(buffer, fmt,
               thisCmd,
               thisCmd->prevDelim,
               thisCmd->bracketDepth,
               thisCmd->nextcommand,
               thisCmd->command,
               thisCmd->redirects);
      WINE_TRACE("%s\n", wine_dbgstr_w(buffer));
      thisCmd = thisCmd->nextcommand;
    }
}

/***************************************************************************
 * WCMD_addCommand
 *
 *   Adds a command to the current command list
 */
static void WCMD_addCommand(WCHAR *command, int *commandLen,
                     WCHAR *redirs,  int *redirLen,
                     WCHAR **copyTo, int **copyToLen,
                     CMD_DELIMITERS prevDelim, int curDepth,
                     CMD_LIST **lastEntry, CMD_LIST **output) {

    CMD_LIST *thisEntry = NULL;

    /* Allocate storage for command */
    thisEntry = HeapAlloc(GetProcessHeap(), 0, sizeof(CMD_LIST));

    /* Copy in the command */
    if (command) {
        thisEntry->command = HeapAlloc(GetProcessHeap(), 0,
                                      (*commandLen+1) * sizeof(WCHAR));
        memcpy(thisEntry->command, command, *commandLen * sizeof(WCHAR));
        thisEntry->command[*commandLen] = 0x00;

        /* Copy in the redirects */
        thisEntry->redirects = HeapAlloc(GetProcessHeap(), 0,
                                         (*redirLen+1) * sizeof(WCHAR));
        memcpy(thisEntry->redirects, redirs, *redirLen * sizeof(WCHAR));
        thisEntry->redirects[*redirLen] = 0x00;
        thisEntry->pipeFile[0] = 0x00;

        /* Reset the lengths */
        *commandLen   = 0;
        *redirLen     = 0;
        *copyToLen    = commandLen;
        *copyTo       = command;

    } else {
        thisEntry->command = NULL;
    }

    /* Fill in other fields */
    thisEntry->nextcommand = NULL;
    thisEntry->prevDelim = prevDelim;
    thisEntry->bracketDepth = curDepth;
    if (*lastEntry) {
        (*lastEntry)->nextcommand = thisEntry;
    } else {
        *output = thisEntry;
    }
    *lastEntry = thisEntry;
}

/***************************************************************************
 * WCMD_ReadAndParseLine
 *
 *   Either uses supplied input or
 *     Reads a file from the handle, and then...
 *   Parse the text buffer, spliting into separate commands
 *     - unquoted && strings split 2 commands but the 2nd is flagged as
 *            following an &&
 *     - ( as the first character just ups the bracket depth
 *     - unquoted ) when bracket depth > 0 terminates a bracket and
 *            adds a CMD_LIST structure with null command
 *     - Anything else gets put into the command string (including
 *            redirects)
 */
WCHAR *WCMD_ReadAndParseLine(WCHAR *optionalcmd, CMD_LIST **output, HANDLE readFrom) {

    WCHAR    *curPos;
    int       inQuotes = 0;
    WCHAR     curString[MAXSTRING];
    int       curStringLen = 0;
    WCHAR     curRedirs[MAXSTRING];
    int       curRedirsLen = 0;
    WCHAR    *curCopyTo;
    int      *curLen;
    int       curDepth = 0;
    CMD_LIST *lastEntry = NULL;
    CMD_DELIMITERS prevDelim = CMD_NONE;
    static WCHAR    *extraSpace = NULL;  /* Deliberately never freed */
    const WCHAR remCmd[] = {'r','e','m',' ','\0'};
    const WCHAR forCmd[] = {'f','o','r',' ','\0'};
    const WCHAR ifCmd[]  = {'i','f',' ','\0'};
    const WCHAR ifElse[] = {'e','l','s','e',' ','\0'};
    BOOL      inRem = FALSE;
    BOOL      inFor = FALSE;
    BOOL      inIn  = FALSE;
    BOOL      inIf  = FALSE;
    BOOL      inElse= FALSE;
    BOOL      onlyWhiteSpace = FALSE;
    BOOL      lastWasWhiteSpace = FALSE;
    BOOL      lastWasDo   = FALSE;
    BOOL      lastWasIn   = FALSE;
    BOOL      lastWasElse = FALSE;
    BOOL      lastWasRedirect = TRUE;

    /* Allocate working space for a command read from keyboard, file etc */
    if (!extraSpace)
      extraSpace = HeapAlloc(GetProcessHeap(), 0, (MAXSTRING+1) * sizeof(WCHAR));
    if (!extraSpace)
    {
        WINE_ERR("Could not allocate memory for extraSpace\n");
        return NULL;
    }

    /* If initial command read in, use that, otherwise get input from handle */
    if (optionalcmd != NULL) {
        strcpyW(extraSpace, optionalcmd);
    } else if (readFrom == INVALID_HANDLE_VALUE) {
        WINE_FIXME("No command nor handle supplied\n");
    } else {
        if (WCMD_fgets(extraSpace, MAXSTRING, readFrom) == NULL) return NULL;
    }
    curPos = extraSpace;

    /* Handle truncated input - issue warning */
    if (strlenW(extraSpace) == MAXSTRING -1) {
        WCMD_output_asis(WCMD_LoadMessage(WCMD_TRUNCATEDLINE));
        WCMD_output_asis(extraSpace);
        WCMD_output_asis(newline);
    }

    /* Replace env vars if in a batch context */
    if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);

    /* Start with an empty string, copying to the command string */
    curStringLen = 0;
    curRedirsLen = 0;
    curCopyTo    = curString;
    curLen       = &curStringLen;
    lastWasRedirect = FALSE;  /* Required for eg spaces between > and filename */

    /* Parse every character on the line being processed */
    while (*curPos != 0x00) {

      WCHAR thisChar;

      /* Debugging AID:
      WINE_TRACE("Looking at '%c' (len:%d, lws:%d, ows:%d)\n", *curPos, *curLen,
                 lastWasWhiteSpace, onlyWhiteSpace);
      */

      /* Certain commands need special handling */
      if (curStringLen == 0 && curCopyTo == curString) {
        const WCHAR forDO[]  = {'d','o',' ','\0'};

        /* If command starts with 'rem', ignore any &&, ( etc */
        if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
          curPos, 4, remCmd, -1) == 2) {
          inRem = TRUE;

        /* If command starts with 'for', handle ('s mid line after IN or DO */
        } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
          curPos, 4, forCmd, -1) == 2) {
          inFor = TRUE;

        /* If command starts with 'if' or 'else', handle ('s mid line. We should ensure this
           is only true in the command portion of the IF statement, but this
           should suffice for now
            FIXME: Silly syntax like "if 1(==1( (
                                        echo they equal
                                      )" will be parsed wrong */
        } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
          curPos, 3, ifCmd, -1) == 2) {
          inIf = TRUE;

        } else if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
          curPos, 5, ifElse, -1) == 2) {
          inElse = TRUE;
          lastWasElse = TRUE;
          onlyWhiteSpace = TRUE;
          memcpy(&curCopyTo[*curLen], curPos, 5*sizeof(WCHAR));
          (*curLen)+=5;
          curPos+=5;
          continue;

        /* In a for loop, the DO command will follow a close bracket followed by
           whitespace, followed by DO, ie closeBracket inserts a NULL entry, curLen
           is then 0, and all whitespace is skipped                                */
        } else if (inFor &&
                   (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
                    curPos, 3, forDO, -1) == 2)) {
          WINE_TRACE("Found DO\n");
          lastWasDo = TRUE;
          onlyWhiteSpace = TRUE;
          memcpy(&curCopyTo[*curLen], curPos, 3*sizeof(WCHAR));
          (*curLen)+=3;
          curPos+=3;
          continue;
        }
      } else if (curCopyTo == curString) {

        /* Special handling for the 'FOR' command */
        if (inFor && lastWasWhiteSpace) {
          const WCHAR forIN[] = {'i','n',' ','\0'};

          WINE_TRACE("Found 'FOR', comparing next parm: '%s'\n", wine_dbgstr_w(curPos));

          if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
              curPos, 3, forIN, -1) == 2) {
            WINE_TRACE("Found IN\n");
            lastWasIn = TRUE;
            onlyWhiteSpace = TRUE;
            memcpy(&curCopyTo[*curLen], curPos, 3*sizeof(WCHAR));
            (*curLen)+=3;
            curPos+=3;
            continue;
          }
        }
      }

      /* Nothing 'ends' a REM statement and &&, quotes etc are ineffective,
         so just use the default processing ie skip character specific
         matching below                                                    */
      if (!inRem) thisChar = *curPos;
      else        thisChar = 'X';  /* Character with no special processing */

      lastWasWhiteSpace = FALSE; /* Will be reset below */

      switch (thisChar) {

      case '=': /* drop through - ignore token delimiters at the start of a command */
      case ',': /* drop through - ignore token delimiters at the start of a command */
      case '\t':/* drop through - ignore token delimiters at the start of a command */
      case ' ':
                /* If a redirect in place, it ends here */
                if (!inQuotes && !lastWasRedirect) {

                  /* If finishing off a redirect, add a whitespace delimiter */
                  if (curCopyTo == curRedirs) {
                      curCopyTo[(*curLen)++] = ' ';
                  }
                  curCopyTo = curString;
                  curLen = &curStringLen;
                }
                if (*curLen > 0) {
                  curCopyTo[(*curLen)++] = *curPos;
                }

                /* Remember just processed whitespace */
                lastWasWhiteSpace = TRUE;

                break;

      case '>': /* drop through - handle redirect chars the same */
      case '<':
                /* Make a redirect start here */
                if (!inQuotes) {
                  curCopyTo = curRedirs;
                  curLen = &curRedirsLen;
                  lastWasRedirect = TRUE;
                }

                /* See if 1>, 2> etc, in which case we have some patching up
                   to do                                                     */
                if (curPos != extraSpace &&
                    *(curPos-1)>='1' && *(curPos-1)<='9') {

                    curStringLen--;
                    curString[curStringLen] = 0x00;
                    curCopyTo[(*curLen)++] = *(curPos-1);
                }

                curCopyTo[(*curLen)++] = *curPos;

                /* If a redirect is immediately followed by '&' (ie. 2>&1) then
                    do not process that ampersand as an AND operator */
                if (thisChar == '>' && *(curPos+1) == '&') {
                    curCopyTo[(*curLen)++] = *(curPos+1);
                    curPos++;
                }
                break;

      case '|': /* Pipe character only if not || */
                if (!inQuotes) {
                  lastWasRedirect = FALSE;

                  /* Add an entry to the command list */
                  if (curStringLen > 0) {

                    /* Add the current command */
                    WCMD_addCommand(curString, &curStringLen,
                          curRedirs, &curRedirsLen,
                          &curCopyTo, &curLen,
                          prevDelim, curDepth,
                          &lastEntry, output);

                  }

                  if (*(curPos+1) == '|') {
                    curPos++; /* Skip other | */
                    prevDelim = CMD_ONFAILURE;
                  } else {
                    prevDelim = CMD_PIPE;
                  }
                } else {
                  curCopyTo[(*curLen)++] = *curPos;
                }
                break;

      case '"': if (inQuotes && *(curPos+1) == ' ') {
                    inQuotes--; /* An end quote must be proceeded by a space */
                } else {
                    inQuotes++; /* Quotes within quotes are fun! */
                }
                curCopyTo[(*curLen)++] = *curPos;
                lastWasRedirect = FALSE;
                break;

      case '(': /* If a '(' is the first non whitespace in a command portion
                   ie start of line or just after &&, then we read until an
                   unquoted ) is found                                       */
                WINE_TRACE("Found '(' conditions: curLen(%d), inQ(%d), onlyWS(%d)"
                           ", for(%d, In:%d, Do:%d)"
                           ", if(%d, else:%d, lwe:%d)\n",
                           *curLen, inQuotes,
                           onlyWhiteSpace,
                           inFor, lastWasIn, lastWasDo,
                           inIf, inElse, lastWasElse);
                lastWasRedirect = FALSE;

                /* Ignore open brackets inside the for set */
                if (*curLen == 0 && !inIn) {
                  curDepth++;

                /* If in quotes, ignore brackets */
                } else if (inQuotes) {
                  curCopyTo[(*curLen)++] = *curPos;

                /* In a FOR loop, an unquoted '(' may occur straight after
                      IN or DO
                   In an IF statement just handle it regardless as we don't
                      parse the operands
                   In an ELSE statement, only allow it straight away after
                      the ELSE and whitespace
                 */
                } else if (inIf ||
                           (inElse && lastWasElse && onlyWhiteSpace) ||
                           (inFor && (lastWasIn || lastWasDo) && onlyWhiteSpace)) {

                   /* If entering into an 'IN', set inIn */
                  if (inFor && lastWasIn && onlyWhiteSpace) {
                    WINE_TRACE("Inside an IN\n");
                    inIn = TRUE;
                  }

                  /* Add the current command */
                  WCMD_addCommand(curString, &curStringLen,
                                  curRedirs, &curRedirsLen,
                                  &curCopyTo, &curLen,
                                  prevDelim, curDepth,
                                  &lastEntry, output);

                  curDepth++;
                } else {
                  curCopyTo[(*curLen)++] = *curPos;
                }
                break;

      case '&': if (!inQuotes) {
                  lastWasRedirect = FALSE;

                  /* Add an entry to the command list */
                  if (curStringLen > 0) {

                    /* Add the current command */
                    WCMD_addCommand(curString, &curStringLen,
                          curRedirs, &curRedirsLen,
                          &curCopyTo, &curLen,
                          prevDelim, curDepth,
                          &lastEntry, output);

                  }

                  if (*(curPos+1) == '&') {
                    curPos++; /* Skip other & */
                    prevDelim = CMD_ONSUCCESS;
                  } else {
                    prevDelim = CMD_NONE;
                  }
                } else {
                  curCopyTo[(*curLen)++] = *curPos;
                }
                break;

      case ')': if (!inQuotes && curDepth > 0) {
                  lastWasRedirect = FALSE;

                  /* Add the current command if there is one */
                  if (curStringLen) {

                      /* Add the current command */
                      WCMD_addCommand(curString, &curStringLen,
                            curRedirs, &curRedirsLen,
                            &curCopyTo, &curLen,
                            prevDelim, curDepth,
                            &lastEntry, output);
                  }

                  /* Add an empty entry to the command list */
                  prevDelim = CMD_NONE;
                  WCMD_addCommand(NULL, &curStringLen,
                        curRedirs, &curRedirsLen,
                        &curCopyTo, &curLen,
                        prevDelim, curDepth,
                        &lastEntry, output);
                  curDepth--;

                  /* Leave inIn if necessary */
                  if (inIn) inIn =  FALSE;
                } else {
                  curCopyTo[(*curLen)++] = *curPos;
                }
                break;
      default:
                lastWasRedirect = FALSE;
                curCopyTo[(*curLen)++] = *curPos;
      }

      curPos++;

      /* At various times we need to know if we have only skipped whitespace,
         so reset this variable and then it will remain true until a non
         whitespace is found                                               */
      if ((thisChar != ' ') && (thisChar != '\n')) onlyWhiteSpace = FALSE;

      /* Flag end of interest in FOR DO and IN parms once something has been processed */
      if (!lastWasWhiteSpace) {
        lastWasIn = lastWasDo = FALSE;
      }

      /* If we have reached the end, add this command into the list */
      if (*curPos == 0x00 && *curLen > 0) {

          /* Add an entry to the command list */
          WCMD_addCommand(curString, &curStringLen,
                curRedirs, &curRedirsLen,
                &curCopyTo, &curLen,
                prevDelim, curDepth,
                &lastEntry, output);
      }

      /* If we have reached the end of the string, see if bracketing outstanding */
      if (*curPos == 0x00 && curDepth > 0 && readFrom != INVALID_HANDLE_VALUE) {
        inRem = FALSE;
        prevDelim = CMD_NONE;
        inQuotes = 0;
        memset(extraSpace, 0x00, (MAXSTRING+1) * sizeof(WCHAR));

        /* Read more, skipping any blank lines */
        while (*extraSpace == 0x00) {
          if (!context) WCMD_output_asis( WCMD_LoadMessage(WCMD_MOREPROMPT));
          if (WCMD_fgets(extraSpace, MAXSTRING, readFrom) == NULL) break;
        }
        curPos = extraSpace;
        if (context) handleExpansion(extraSpace, FALSE, NULL, NULL);
      }
    }

    /* Dump out the parsed output */
    WCMD_DumpCommands(*output);

    return extraSpace;
}

/***************************************************************************
 * WCMD_process_commands
 *
 * Process all the commands read in so far
 */
CMD_LIST *WCMD_process_commands(CMD_LIST *thisCmd, BOOL oneBracket,
                                WCHAR *var, WCHAR *val) {

    int bdepth = -1;

    if (thisCmd && oneBracket) bdepth = thisCmd->bracketDepth;

    /* Loop through the commands, processing them one by one */
    while (thisCmd) {

      CMD_LIST *origCmd = thisCmd;

      /* If processing one bracket only, and we find the end bracket
         entry (or less), return                                    */
      if (oneBracket && !thisCmd->command &&
          bdepth <= thisCmd->bracketDepth) {
        WINE_TRACE("Finished bracket @ %p, next command is %p\n",
                   thisCmd, thisCmd->nextcommand);
        return thisCmd->nextcommand;
      }

      /* Ignore the NULL entries a ')' inserts (Only 'if' cares
         about them and it will be handled in there)
         Also, skip over any batch labels (eg. :fred)          */
      if (thisCmd->command && thisCmd->command[0] != ':') {
        WINE_TRACE("Executing command: '%s'\n", wine_dbgstr_w(thisCmd->command));
        WCMD_execute (thisCmd->command, thisCmd->redirects, var, val, &thisCmd);
      }

      /* Step on unless the command itself already stepped on */
      if (thisCmd == origCmd) thisCmd = thisCmd->nextcommand;
    }
    return NULL;
}

/***************************************************************************
 * WCMD_free_commands
 *
 * Frees the storage held for a parsed command line
 * - This is not done in the process_commands, as eventually the current
 *   pointer will be modified within the commands, and hence a single free
 *   routine is simpler
 */
void WCMD_free_commands(CMD_LIST *cmds) {

    /* Loop through the commands, freeing them one by one */
    while (cmds) {
      CMD_LIST *thisCmd = cmds;
      cmds = cmds->nextcommand;
      HeapFree(GetProcessHeap(), 0, thisCmd->command);
      HeapFree(GetProcessHeap(), 0, thisCmd);
    }
}


/*****************************************************************************
 * Main entry point. This is a console application so we have a main() not a
 * winmain().
 */

int wmain (int argc, WCHAR *argvW[])
{
  int     args;
  WCHAR  *cmd   = NULL;
  WCHAR string[1024];
  WCHAR envvar[4];
  HANDLE h;
  int opt_q;
  int opt_t = 0;
  static const WCHAR autoexec[] = {'\\','a','u','t','o','e','x','e','c','.',
                                   'b','a','t','\0'};
  char ansiVersion[100];
  CMD_LIST *toExecute = NULL;         /* Commands left to be executed */

  srand(time(NULL));

  /* Pre initialize some messages */
  strcpy(ansiVersion, PACKAGE_VERSION);
  MultiByteToWideChar(CP_ACP, 0, ansiVersion, -1, string, 1024);
  wsprintf(version_string, WCMD_LoadMessage(WCMD_VERSION), string);
  strcpyW(anykey, WCMD_LoadMessage(WCMD_ANYKEY));

  args  = argc;
  opt_c=opt_k=opt_q=opt_s=0;
  while (args > 0)
  {
      WCHAR c;
      WINE_TRACE("Command line parm: '%s'\n", wine_dbgstr_w(*argvW));
      if ((*argvW)[0]!='/' || (*argvW)[1]=='\0') {
          argvW++;
          args--;
          continue;
      }

      c=(*argvW)[1];
      if (tolowerW(c)=='c') {
          opt_c=1;
      } else if (tolowerW(c)=='q') {
          opt_q=1;
      } else if (tolowerW(c)=='k') {
          opt_k=1;
      } else if (tolowerW(c)=='s') {
          opt_s=1;
      } else if (tolowerW(c)=='a') {
          unicodePipes=FALSE;
      } else if (tolowerW(c)=='u') {
          unicodePipes=TRUE;
      } else if (tolowerW(c)=='t' && (*argvW)[2]==':') {
          opt_t=strtoulW(&(*argvW)[3], NULL, 16);
      } else if (tolowerW(c)=='x' || tolowerW(c)=='y') {
          /* Ignored for compatibility with Windows */
      }

      if ((*argvW)[2]==0) {
          argvW++;
          args--;
      }
      else /* handle `cmd /cnotepad.exe` and `cmd /x/c ...` */
      {
          *argvW+=2;
      }

      if (opt_c || opt_k) /* break out of parsing immediately after c or k */
          break;
  }

  if (opt_q) {
    const WCHAR eoff[] = {'O','F','F','\0'};
    WCMD_echo(eoff);
  }

  if (opt_c || opt_k) {
      int     len,qcount;
      WCHAR** arg;
      int     argsLeft;
      WCHAR*  p;

      /* opt_s left unflagged if the command starts with and contains exactly
       * one quoted string (exactly two quote characters). The quoted string
       * must be an executable name that has whitespace and must not have the
       * following characters: &<>()@^| */

      /* Build the command to execute */
      len = 0;
      qcount = 0;
      argsLeft = args;
      for (arg = argvW; argsLeft>0; arg++,argsLeft--)
      {
          int has_space,bcount;
          WCHAR* a;

          has_space=0;
          bcount=0;
          a=*arg;
          if( !*a ) has_space=1;
          while (*a!='\0') {
              if (*a=='\\') {
                  bcount++;
              } else {
                  if (*a==' ' || *a=='\t') {
                      has_space=1;
                  } else if (*a=='"') {
                      /* doubling of '\' preceding a '"',
                       * plus escaping of said '"'
                       */
                      len+=2*bcount+1;
                      qcount++;
                  }
                  bcount=0;
              }
              a++;
          }
          len+=(a-*arg) + 1; /* for the separating space */
          if (has_space)
          {
              len+=2; /* for the quotes */
              qcount+=2;
          }
      }

      if (qcount!=2)
          opt_s=1;

      /* check argvW[0] for a space and invalid characters */
      if (!opt_s) {
          opt_s=1;
          p=*argvW;
          while (*p!='\0') {
              if (*p=='&' || *p=='<' || *p=='>' || *p=='(' || *p==')'
                  || *p=='@' || *p=='^' || *p=='|') {
                  opt_s=1;
                  break;
              }
              if (*p==' ')
                  opt_s=0;
              p++;
          }
      }

      cmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
      if (!cmd)
          exit(1);

      p = cmd;
      argsLeft = args;
      for (arg = argvW; argsLeft>0; arg++,argsLeft--)
      {
          int has_space,has_quote;
          WCHAR* a;

          /* Check for quotes and spaces in this argument */
          has_space=has_quote=0;
          a=*arg;
          if( !*a ) has_space=1;
          while (*a!='\0') {
              if (*a==' ' || *a=='\t') {
                  has_space=1;
                  if (has_quote)
                      break;
              } else if (*a=='"') {
                  has_quote=1;
                  if (has_space)
                      break;
              }
              a++;
          }

          /* Now transfer it to the command line */
          if (has_space)
              *p++='"';
          if (has_quote) {
              int bcount;
              WCHAR* a;

              bcount=0;
              a=*arg;
              while (*a!='\0') {
                  if (*a=='\\') {
                      *p++=*a;
                      bcount++;
                  } else {
                      if (*a=='"') {
                          int i;

                          /* Double all the '\\' preceding this '"', plus one */
                          for (i=0;i<=bcount;i++)
                              *p++='\\';
                          *p++='"';
                      } else {
                          *p++=*a;
                      }
                      bcount=0;
                  }
                  a++;
              }
          } else {
              strcpyW(p,*arg);
              p+=strlenW(*arg);
          }
          if (has_space)
              *p++='"';
          *p++=' ';
      }
      if (p > cmd)
          p--;  /* remove last space */
      *p = '\0';

      WINE_TRACE("/c command line: '%s'\n", wine_dbgstr_w(cmd));

      /* strip first and last quote characters if opt_s; check for invalid
       * executable is done later */
      if (opt_s && *cmd=='\"')
          WCMD_opt_s_strip_quotes(cmd);
  }

  if (opt_c) {
      /* If we do a "wcmd /c command", we don't want to allocate a new
       * console since the command returns immediately. Rather, we use
       * the currently allocated input and output handles. This allows
       * us to pipe to and read from the command interpreter.
       */

      /* Parse the command string, without reading any more input */
      WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
      WCMD_process_commands(toExecute, FALSE, NULL, NULL);
      WCMD_free_commands(toExecute);
      toExecute = NULL;

      HeapFree(GetProcessHeap(), 0, cmd);
      return errorlevel;
  }

  SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_LINE_INPUT |
                 ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
  SetConsoleTitle(WCMD_LoadMessage(WCMD_CONSTITLE));

  /* Note: cmd.exe /c dir does not get a new color, /k dir does */
  if (opt_t) {
      if (!(((opt_t & 0xF0) >> 4) == (opt_t & 0x0F))) {
          defaultColor = opt_t & 0xFF;
          param1[0] = 0x00;
          WCMD_color();
      }
  } else {
      /* Check HKCU\Software\Microsoft\Command Processor
         Then  HKLM\Software\Microsoft\Command Processor
           for defaultcolour value
           Note  Can be supplied as DWORD or REG_SZ
           Note2 When supplied as REG_SZ it's in decimal!!! */
      HKEY key;
      DWORD type;
      DWORD value=0, size=4;
      static const WCHAR regKeyW[] = {'S','o','f','t','w','a','r','e','\\',
                                      'M','i','c','r','o','s','o','f','t','\\',
                                      'C','o','m','m','a','n','d',' ','P','r','o','c','e','s','s','o','r','\0'};
      static const WCHAR dfltColorW[] = {'D','e','f','a','u','l','t','C','o','l','o','r','\0'};

      if (RegOpenKeyEx(HKEY_CURRENT_USER, regKeyW,
                       0, KEY_READ, &key) == ERROR_SUCCESS) {
          WCHAR  strvalue[4];

          /* See if DWORD or REG_SZ */
          if (RegQueryValueEx(key, dfltColorW, NULL, &type,
                     NULL, NULL) == ERROR_SUCCESS) {
              if (type == REG_DWORD) {
                  size = sizeof(DWORD);
                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                  (LPBYTE)&value, &size);
              } else if (type == REG_SZ) {
                  size = sizeof(strvalue)/sizeof(WCHAR);
                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                  (LPBYTE)strvalue, &size);
                  value = strtoulW(strvalue, NULL, 10);
              }
          }
          RegCloseKey(key);
      }

      if (value == 0 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKeyW,
                       0, KEY_READ, &key) == ERROR_SUCCESS) {
          WCHAR  strvalue[4];

          /* See if DWORD or REG_SZ */
          if (RegQueryValueEx(key, dfltColorW, NULL, &type,
                     NULL, NULL) == ERROR_SUCCESS) {
              if (type == REG_DWORD) {
                  size = sizeof(DWORD);
                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                  (LPBYTE)&value, &size);
              } else if (type == REG_SZ) {
                  size = sizeof(strvalue)/sizeof(WCHAR);
                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                  (LPBYTE)strvalue, &size);
                  value = strtoulW(strvalue, NULL, 10);
              }
          }
          RegCloseKey(key);
      }

      /* If one found, set the screen to that colour */
      if (!(((value & 0xF0) >> 4) == (value & 0x0F))) {
          defaultColor = value & 0xFF;
          param1[0] = 0x00;
          WCMD_color();
      }

  }

  /* Save cwd into appropriate env var */
  GetCurrentDirectory(1024, string);
  if (IsCharAlpha(string[0]) && string[1] == ':') {
    static const WCHAR fmt[] = {'=','%','c',':','\0'};
    wsprintf(envvar, fmt, string[0]);
    SetEnvironmentVariable(envvar, string);
    WINE_TRACE("Set %s to %s\n", wine_dbgstr_w(envvar), wine_dbgstr_w(string));
  }

  if (opt_k) {
      /* Parse the command string, without reading any more input */
      WCMD_ReadAndParseLine(cmd, &toExecute, INVALID_HANDLE_VALUE);
      WCMD_process_commands(toExecute, FALSE, NULL, NULL);
      WCMD_free_commands(toExecute);
      toExecute = NULL;
      HeapFree(GetProcessHeap(), 0, cmd);
  }

/*
 *	If there is an AUTOEXEC.BAT file, try to execute it.
 */

  GetFullPathName (autoexec, sizeof(string)/sizeof(WCHAR), string, NULL);
  h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (h != INVALID_HANDLE_VALUE) {
    CloseHandle (h);
#if 0
    WCMD_batch (autoexec, autoexec, 0, NULL, INVALID_HANDLE_VALUE);
#endif
  }

/*
 *	Loop forever getting commands and executing them.
 */

  WCMD_version ();
  while (TRUE) {

    /* Read until EOF (which for std input is never, but if redirect
       in place, may occur                                          */
    WCMD_show_prompt ();
    if (WCMD_ReadAndParseLine(NULL, &toExecute,
                              GetStdHandle(STD_INPUT_HANDLE)) == NULL)
      break;
    WCMD_process_commands(toExecute, FALSE, NULL, NULL);
    WCMD_free_commands(toExecute);
    toExecute = NULL;
  }
  return 0;
}
