cmd.exe: Convert cmd to Unicode.
diff --git a/programs/cmd/Cs.rc b/programs/cmd/Cs.rc
index 82bf49b..302659f 100644
--- a/programs/cmd/Cs.rc
+++ b/programs/cmd/Cs.rc
@@ -263,4 +263,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/De.rc b/programs/cmd/De.rc
index 7f02f6a..55799ea 100644
--- a/programs/cmd/De.rc
+++ b/programs/cmd/De.rc
@@ -287,4 +287,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/En.rc b/programs/cmd/En.rc
index 132938a..6f384ca 100644
--- a/programs/cmd/En.rc
+++ b/programs/cmd/En.rc
@@ -267,4 +267,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Es.rc b/programs/cmd/Es.rc
index 7363f94..02bd865 100644
--- a/programs/cmd/Es.rc
+++ b/programs/cmd/Es.rc
@@ -284,4 +284,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Fr.rc b/programs/cmd/Fr.rc
index 78b39de..0e3dcc7 100644
--- a/programs/cmd/Fr.rc
+++ b/programs/cmd/Fr.rc
@@ -257,4 +257,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Ja.rc b/programs/cmd/Ja.rc
index 5cbd119..b09715a 100644
--- a/programs/cmd/Ja.rc
+++ b/programs/cmd/Ja.rc
@@ -261,4 +261,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Ko.rc b/programs/cmd/Ko.rc
index 43395b9..fd568d2 100644
--- a/programs/cmd/Ko.rc
+++ b/programs/cmd/Ko.rc
@@ -259,4 +259,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Makefile.in b/programs/cmd/Makefile.in
index 3a81838..c383344 100644
--- a/programs/cmd/Makefile.in
+++ b/programs/cmd/Makefile.in
@@ -4,6 +4,7 @@
 VPATH     = @srcdir@
 MODULE    = cmd.exe
 APPMODE   = -mconsole
+EXTRADEFS = -DUNICODE
 IMPORTS   = shell32 user32 advapi32 kernel32
 
 C_SRCS = \
diff --git a/programs/cmd/Nl.rc b/programs/cmd/Nl.rc
index 5a12123..b06651a 100644
--- a/programs/cmd/Nl.rc
+++ b/programs/cmd/Nl.rc
@@ -260,4 +260,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/No.rc b/programs/cmd/No.rc
index e4e7c5c..571cc47 100644
--- a/programs/cmd/No.rc
+++ b/programs/cmd/No.rc
@@ -265,4 +265,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Pl.rc b/programs/cmd/Pl.rc
index 67c659c..6d56af1 100644
--- a/programs/cmd/Pl.rc
+++ b/programs/cmd/Pl.rc
@@ -262,4 +262,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Pt.rc b/programs/cmd/Pt.rc
index 17090dd..808bd11 100644
--- a/programs/cmd/Pt.rc
+++ b/programs/cmd/Pt.rc
@@ -470,4 +470,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Ru.rc b/programs/cmd/Ru.rc
index d3860c4..852f9ff 100644
--- a/programs/cmd/Ru.rc
+++ b/programs/cmd/Ru.rc
@@ -273,4 +273,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Si.rc b/programs/cmd/Si.rc
index 8060fad..e2243f5 100644
--- a/programs/cmd/Si.rc
+++ b/programs/cmd/Si.rc
@@ -259,4 +259,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/Tr.rc b/programs/cmd/Tr.rc
index 69e707e..e14c2a7 100644
--- a/programs/cmd/Tr.rc
+++ b/programs/cmd/Tr.rc
@@ -261,4 +261,8 @@
   WCMD_ARGERR, "Parameter error\n"
   WCMD_VOLUMEDETAIL, "Volume in drive %c is %s\nVolume Serial Number is %04x-%04x\n\n"
   WCMD_VOLUMEPROMPT, "Volume label (11 characters, ENTER for none)?"
+  WCMD_NOPATH, "PATH not found\n"
+  WCMD_ANYKEY,"Press Return key to continue: "
+  WCMD_CONSTITLE,"Wine Command Prompt"
+  WCMD_VERSION,"CMD Version %s\n\n"
 }
diff --git a/programs/cmd/batch.c b/programs/cmd/batch.c
index 9824fe5..c301bcc 100644
--- a/programs/cmd/batch.c
+++ b/programs/cmd/batch.c
@@ -21,7 +21,7 @@
 #include "wcmd.h"
 
 extern int echo_mode;
-extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
+extern WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
 extern BATCH_CONTEXT *context;
 extern DWORD errorlevel;
 
@@ -41,30 +41,31 @@
  * a label to goto once opened.
  */
 
-void WCMD_batch (char *file, char *command, int called, char *startLabel, HANDLE pgmHandle) {
+void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HANDLE pgmHandle) {
 
 #define WCMD_BATCH_EXT_SIZE 5
 
   HANDLE h = INVALID_HANDLE_VALUE;
-  char string[MAXSTRING];
-  char extension_batch[][WCMD_BATCH_EXT_SIZE] = {".bat",".cmd"};
-  char extension_exe[WCMD_BATCH_EXT_SIZE] = ".exe";
+  WCHAR string[MAXSTRING];
+  static const WCHAR extension_batch[][WCMD_BATCH_EXT_SIZE] = {{'.','b','a','t','\0'},
+                                                               {'.','c','m','d','\0'}};
+  static const WCHAR extension_exe[WCMD_BATCH_EXT_SIZE] = {'.','e','x','e','\0'};
   unsigned int  i;
   BATCH_CONTEXT *prev_context;
 
   if (startLabel == NULL) {
-    for(i=0; (i<(sizeof(extension_batch)/WCMD_BATCH_EXT_SIZE)) &&
+    for(i=0; (i<((sizeof(extension_batch) * sizeof(WCHAR))/WCMD_BATCH_EXT_SIZE)) &&
              (h == INVALID_HANDLE_VALUE); i++) {
-    strcpy (string, file);
-    CharLower (string);
-      if (strstr (string, extension_batch[i]) == NULL) strcat (string, extension_batch[i]);
-    h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
-                    NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+      strcpyW (string, file);
+      CharLower (string);
+      if (strstrW (string, extension_batch[i]) == NULL) strcatW (string, extension_batch[i]);
+      h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
+                      NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
     }
     if (h == INVALID_HANDLE_VALUE) {
-      strcpy (string, file);
+      strcpyW (string, file);
       CharLower (string);
-      if (strstr (string, extension_exe) == NULL) strcat (string, extension_exe);
+      if (strstrW (string, extension_exe) == NULL) strcatW (string, extension_exe);
       h = CreateFile (string, GENERIC_READ, FILE_SHARE_READ,
                       NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
       if (h != INVALID_HANDLE_VALUE) {
@@ -95,7 +96,7 @@
 
   /* If processing a call :label, 'goto' the label in question */
   if (startLabel) {
-    strcpy(param1, startLabel);
+    strcpyW(param1, startLabel);
     WCMD_goto();
   }
 
@@ -105,7 +106,7 @@
  */
 
   while (context -> skip_rest == FALSE && WCMD_fgets (string, sizeof(string), h)) {
-      if (strlen(string) == MAXSTRING -1) {
+      if (strlenW(string) == MAXSTRING -1) {
           WCMD_output_asis( WCMD_LoadMessage(WCMD_TRUNCATEDLINE));
           WCMD_output_asis( string);
           WCMD_output_asis( newline);
@@ -141,11 +142,11 @@
  *	Also returns a pointer to the location of the parameter in the command line.
  */
 
-char *WCMD_parameter (char *s, int n, char **where) {
+WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where) {
 
   int i = 0;
-  static char param[MAX_PATH];
-  char *p;
+  static WCHAR param[MAX_PATH];
+  WCHAR *p;
 
   if (where != NULL) *where = NULL;
   p = param;
@@ -211,32 +212,32 @@
  * the LF (or CRLF) from the line.
  */
 
-char *WCMD_fgets (char *s, int n, HANDLE h) {
+WCHAR *WCMD_fgets (WCHAR *s, int noChars, HANDLE h) {
 
   DWORD bytes;
   BOOL status;
-  char *p;
+  WCHAR *p;
 
   p = s;
   do {
-    status = ReadFile (h, s, 1, &bytes, NULL);
+    status = WCMD_ReadFile (h, s, 1, &bytes, NULL);
     if ((status == 0) || ((bytes == 0) && (s == p))) return NULL;
     if (*s == '\n') bytes = 0;
     else if (*s != '\r') {
       s++;
-      n--;
+      noChars--;
     }
     *s = '\0';
-  } while ((bytes == 1) && (n > 1));
+  } while ((bytes == 1) && (noChars > 1));
   return p;
 }
 
 /* WCMD_splitpath - copied from winefile as no obvious way to use it otherwise */
-void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext)
+void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext)
 {
-        const CHAR* end; /* end of processed string */
-	const CHAR* p;	 /* search pointer */
-	const CHAR* s;	 /* copy pointer */
+        const WCHAR* end; /* end of processed string */
+	const WCHAR* p;	 /* search pointer */
+	const WCHAR* s;	 /* copy pointer */
 
 	/* extract drive name */
 	if (path[0] && path[1]==':') {
@@ -307,7 +308,7 @@
  *  To work out the length of the modifier:
  *
  *  Note: In the case of %0-9 knowing the end of the modifier is easy,
- *    but in a for loop, the for end character may also be a modifier
+ *    but in a for loop, the for end WCHARacter may also be a modifier
  *    eg. for %a in (c:\a.a) do echo XXX
  *             where XXX = %~a    (just ~)
  *                         %~aa   (~ and attributes)
@@ -317,22 +318,22 @@
  *  Hence search forwards until find an invalid modifier, and then
  *  backwards until find for variable or 0-9
  */
-void WCMD_HandleTildaModifiers(char **start, char *forVariable) {
+void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable) {
 
 #define NUMMODIFIERS 11
-  const char validmodifiers[NUMMODIFIERS] = {
+  static const WCHAR validmodifiers[NUMMODIFIERS] = {
         '~', 'f', 'd', 'p', 'n', 'x', 's', 'a', 't', 'z', '$'
   };
-  const char space[] = " ";
+  static const WCHAR space[] = {' ', '\0'};
 
   WIN32_FILE_ATTRIBUTE_DATA fileInfo;
-  char  outputparam[MAX_PATH];
-  char  finaloutput[MAX_PATH];
-  char  fullfilename[MAX_PATH];
-  char  thisoutput[MAX_PATH];
-  char  *pos            = *start+1;
-  char  *firstModifier  = pos;
-  char  *lastModifier   = NULL;
+  WCHAR  outputparam[MAX_PATH];
+  WCHAR  finaloutput[MAX_PATH];
+  WCHAR  fullfilename[MAX_PATH];
+  WCHAR  thisoutput[MAX_PATH];
+  WCHAR  *pos            = *start+1;
+  WCHAR  *firstModifier  = pos;
+  WCHAR  *lastModifier   = NULL;
   int   modifierLen     = 0;
   BOOL  finished        = FALSE;
   int   i               = 0;
@@ -340,10 +341,10 @@
   BOOL  skipFileParsing = FALSE;
   BOOL  doneModifier    = FALSE;
 
-  /* Search forwards until find invalid character modifier */
+  /* Search forwards until find invalid WCHARacter modifier */
   while (!finished) {
 
-    /* Work on the previous character */
+    /* Work on the previous WCHARacter */
     if (lastModifier != NULL) {
 
       for (i=0; i<NUMMODIFIERS; i++) {
@@ -374,10 +375,10 @@
   /* Now make sure the position we stopped at is a valid parameter */
   if (!(*lastModifier >= '0' || *lastModifier <= '9') &&
       (forVariable != NULL) &&
-      (toupper(*lastModifier) != toupper(*forVariable)))  {
+      (toupperW(*lastModifier) != toupperW(*forVariable)))  {
 
     /* Its not... Step backwards until it matches or we get to the start */
-    while (toupper(*lastModifier) != toupper(*forVariable) &&
+    while (toupperW(*lastModifier) != toupperW(*forVariable) &&
           lastModifier > firstModifier) {
       lastModifier--;
     }
@@ -386,7 +387,7 @@
 
   /* Extract the parameter to play with */
   if ((*lastModifier >= '0' && *lastModifier <= '9')) {
-    strcpy(outputparam, WCMD_parameter (context -> command,
+    strcpyW(outputparam, WCMD_parameter (context -> command,
                  *lastModifier-'0' + context -> shift_count[*lastModifier-'0'], NULL));
   } else {
     /* FIXME: Retrieve 'for' variable %c\n", *lastModifier); */
@@ -407,26 +408,26 @@
 
   /* 1. Handle '~' : Strip surrounding quotes */
   if (outputparam[0]=='"' &&
-      memchr(firstModifier, '~', modifierLen) != NULL) {
-    int len = strlen(outputparam);
+      memchrW(firstModifier, '~', modifierLen) != NULL) {
+    int len = strlenW(outputparam);
     if (outputparam[len-1] == '"') {
         outputparam[len-1]=0x00;
         len = len - 1;
     }
-    memmove(outputparam, &outputparam[1], len-1);
+    memmove(outputparam, &outputparam[1], (len * sizeof(WCHAR))-1);
   }
 
   /* 2. Handle the special case of a $ */
-  if (memchr(firstModifier, '$', modifierLen) != NULL) {
+  if (memchrW(firstModifier, '$', modifierLen) != NULL) {
     /* Special Case: Search envar specified in $[envvar] for outputparam
        Note both $ and : are guaranteed otherwise check above would fail */
-    char *start = strchr(firstModifier, '$') + 1;
-    char *end   = strchr(firstModifier, ':');
-    char env[MAX_PATH];
-    char fullpath[MAX_PATH];
+    WCHAR *start = strchrW(firstModifier, '$') + 1;
+    WCHAR *end   = strchrW(firstModifier, ':');
+    WCHAR env[MAX_PATH];
+    WCHAR fullpath[MAX_PATH];
 
     /* Extract the env var */
-    strncpy(env, start, (end-start));
+    memcpy(env, start, (end-start) * sizeof(WCHAR));
     env[(end-start)] = 0x00;
 
     /* If env var not found, return emptry string */
@@ -445,15 +446,16 @@
     if (GetFullPathName(outputparam, MAX_PATH, fullfilename, NULL) == 0)
       return;
 
-    exists = GetFileAttributesExA(fullfilename, GetFileExInfoStandard,
+    exists = GetFileAttributesExW(fullfilename, GetFileExInfoStandard,
                                   &fileInfo);
 
     /* 2. Handle 'a' : Output attributes */
     if (exists &&
-        memchr(firstModifier, 'a', modifierLen) != NULL) {
+        memchrW(firstModifier, 'a', modifierLen) != NULL) {
 
+      WCHAR defaults[] = {'-','-','-','-','-','-','-','-','-','\0'};
       doneModifier = TRUE;
-      strcpy(thisoutput, "---------");
+      strcpyW(thisoutput, defaults);
       if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
         thisoutput[0]='d';
       if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
@@ -469,114 +471,115 @@
       /* FIXME: What are 6 and 7? */
       if (fileInfo.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
         thisoutput[8]='l';
-      strcat(finaloutput, thisoutput);
+      strcatW(finaloutput, thisoutput);
     }
 
     /* 3. Handle 't' : Date+time */
     if (exists &&
-        memchr(firstModifier, 't', modifierLen) != NULL) {
+        memchrW(firstModifier, 't', modifierLen) != NULL) {
 
       SYSTEMTIME systime;
       int datelen;
 
       doneModifier = TRUE;
-      if (finaloutput[0] != 0x00) strcat(finaloutput, space);
+      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
 
       /* Format the time */
       FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &systime);
       GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systime,
                         NULL, thisoutput, MAX_PATH);
-      strcat(thisoutput, space);
-      datelen = strlen(thisoutput);
+      strcatW(thisoutput, space);
+      datelen = strlenW(thisoutput);
       GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &systime,
                         NULL, (thisoutput+datelen), MAX_PATH-datelen);
-      strcat(finaloutput, thisoutput);
+      strcatW(finaloutput, thisoutput);
     }
 
     /* 4. Handle 'z' : File length */
     if (exists &&
-        memchr(firstModifier, 'z', modifierLen) != NULL) {
+        memchrW(firstModifier, 'z', modifierLen) != NULL) {
       /* FIXME: Output full 64 bit size (sprintf does not support I64 here) */
       ULONG/*64*/ fullsize = /*(fileInfo.nFileSizeHigh << 32) +*/
                                   fileInfo.nFileSizeLow;
+      static const WCHAR fmt[] = {'%','u','\0'};
 
       doneModifier = TRUE;
-      if (finaloutput[0] != 0x00) strcat(finaloutput, space);
-      sprintf(thisoutput, "%u", fullsize);
-      strcat(finaloutput, thisoutput);
+      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
+      wsprintf(thisoutput, fmt, fullsize);
+      strcatW(finaloutput, thisoutput);
     }
 
     /* 4. Handle 's' : Use short paths (File doesn't have to exist) */
-    if (memchr(firstModifier, 's', modifierLen) != NULL) {
-      if (finaloutput[0] != 0x00) strcat(finaloutput, space);
+    if (memchrW(firstModifier, 's', modifierLen) != NULL) {
+      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
       /* Don't flag as doneModifier - %~s on its own is processed later */
       GetShortPathName(outputparam, outputparam, sizeof(outputparam));
     }
 
     /* 5. Handle 'f' : Fully qualified path (File doesn't have to exist) */
     /*      Note this overrides d,p,n,x                                 */
-    if (memchr(firstModifier, 'f', modifierLen) != NULL) {
+    if (memchrW(firstModifier, 'f', modifierLen) != NULL) {
       doneModifier = TRUE;
-      if (finaloutput[0] != 0x00) strcat(finaloutput, space);
-      strcat(finaloutput, fullfilename);
+      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
+      strcatW(finaloutput, fullfilename);
     } else {
 
-      char drive[10];
-      char dir[MAX_PATH];
-      char fname[MAX_PATH];
-      char ext[MAX_PATH];
+      WCHAR drive[10];
+      WCHAR dir[MAX_PATH];
+      WCHAR fname[MAX_PATH];
+      WCHAR ext[MAX_PATH];
       BOOL doneFileModifier = FALSE;
 
-      if (finaloutput[0] != 0x00) strcat(finaloutput, space);
+      if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
 
       /* Split into components */
       WCMD_splitpath(fullfilename, drive, dir, fname, ext);
 
       /* 5. Handle 'd' : Drive Letter */
-      if (memchr(firstModifier, 'd', modifierLen) != NULL) {
-        strcat(finaloutput, drive);
+      if (memchrW(firstModifier, 'd', modifierLen) != NULL) {
+        strcatW(finaloutput, drive);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
       }
 
       /* 6. Handle 'p' : Path */
-      if (memchr(firstModifier, 'p', modifierLen) != NULL) {
-        strcat(finaloutput, dir);
+      if (memchrW(firstModifier, 'p', modifierLen) != NULL) {
+        strcatW(finaloutput, dir);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
       }
 
       /* 7. Handle 'n' : Name */
-      if (memchr(firstModifier, 'n', modifierLen) != NULL) {
-        strcat(finaloutput, fname);
+      if (memchrW(firstModifier, 'n', modifierLen) != NULL) {
+        strcatW(finaloutput, fname);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
       }
 
       /* 8. Handle 'x' : Ext */
-      if (memchr(firstModifier, 'x', modifierLen) != NULL) {
-        strcat(finaloutput, ext);
+      if (memchrW(firstModifier, 'x', modifierLen) != NULL) {
+        strcatW(finaloutput, ext);
         doneModifier = TRUE;
         doneFileModifier = TRUE;
       }
 
       /* If 's' but no other parameter, dump the whole thing */
       if (!doneFileModifier &&
-          memchr(firstModifier, 's', modifierLen) != NULL) {
+          memchrW(firstModifier, 's', modifierLen) != NULL) {
         doneModifier = TRUE;
-        if (finaloutput[0] != 0x00) strcat(finaloutput, space);
-        strcat(finaloutput, outputparam);
+        if (finaloutput[0] != 0x00) strcatW(finaloutput, space);
+        strcatW(finaloutput, outputparam);
       }
     }
   }
 
   /* If No other modifier processed,  just add in parameter */
-  if (!doneModifier) strcpy(finaloutput, outputparam);
+  if (!doneModifier) strcpyW(finaloutput, outputparam);
 
   /* Finish by inserting the replacement into the string */
-  pos = strdup (lastModifier+1);
-  strcpy(*start, finaloutput);
-  strcat(*start, pos);
+  pos = WCMD_strdupW(lastModifier+1);
+  strcpyW(*start, finaloutput);
+  strcatW(*start, pos);
   free(pos);
 }
 
@@ -586,16 +589,16 @@
  *	If there is a leading ':', calls within this batch program
  *	otherwise launches another program.
  */
-void WCMD_call (char *command) {
+void WCMD_call (WCHAR *command) {
 
   /* Run other program if no leading ':' */
   if (*command != ':') {
     WCMD_run_program(command, 1);
   } else {
 
-    char gotoLabel[MAX_PATH];
+    WCHAR gotoLabel[MAX_PATH];
 
-    strcpy(gotoLabel, param1);
+    strcpyW(gotoLabel, param1);
 
     if (context) {
 
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 5c6510f..b73e318 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -40,19 +40,29 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(cmd);
 
-void WCMD_execute (char *orig_command, char *parameter, char *substitution);
+void WCMD_execute (WCHAR *orig_command, WCHAR *parameter, WCHAR *substitution);
 
 struct env_stack *saved_environment;
 struct env_stack *pushd_directories;
 
 extern HINSTANCE hinst;
-extern char *inbuilt[];
+extern WCHAR *inbuilt[];
 extern int echo_mode, verify_mode, defaultColor;
-extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
+extern WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
 extern BATCH_CONTEXT *context;
 extern DWORD errorlevel;
 
-
+static const WCHAR dotW[]    = {'.','\0'};
+static const WCHAR dotdotW[] = {'.','.','\0'};
+static const WCHAR slashW[]  = {'\\','\0'};
+static const WCHAR starW[]   = {'*','\0'};
+static const WCHAR equalW[]  = {'=','\0'};
+static const WCHAR fslashW[] = {'/','\0'};
+static const WCHAR onW[]  = {'O','N','\0'};
+static const WCHAR offW[] = {'O','F','F','\0'};
+static const WCHAR parmY[] = {'/','Y','\0'};
+static const WCHAR parmNoY[] = {'/','-','Y','\0'};
+static const WCHAR nullW[] = {'\0'};
 
 /****************************************************************************
  * WCMD_clear_screen
@@ -105,55 +115,56 @@
   WIN32_FIND_DATA fd;
   HANDLE hff;
   BOOL force, status;
-  char outpath[MAX_PATH], inpath[MAX_PATH], *infile, copycmd[3];
+  WCHAR outpath[MAX_PATH], inpath[MAX_PATH], *infile, copycmd[3];
   DWORD len;
+  static const WCHAR copyCmdW[] = {'C','O','P','Y','C','M','D','\0'};
 
   if (param1[0] == 0x00) {
     WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
     return;
   }
 
-  if ((strchr(param1,'*') != NULL) && (strchr(param1,'%') != NULL)) {
-    WCMD_output ("Wildcards not yet supported\n");
+  if ((strchrW(param1,'*') != NULL) && (strchrW(param1,'%') != NULL)) {
+    WCMD_output (WCMD_LoadMessage(WCMD_NYI));
     return;
   }
 
   /* If no destination supplied, assume current directory */
   if (param2[0] == 0x00) {
-      strcpy(param2, ".");
+      strcpyW(param2, dotW);
   }
 
-  GetFullPathName (param2, sizeof(outpath), outpath, NULL);
-  if (outpath[strlen(outpath) - 1] == '\\')
-      outpath[strlen(outpath) - 1] = '\0';
+  GetFullPathName (param2, sizeof(outpath)/sizeof(WCHAR), outpath, NULL);
+  if (outpath[strlenW(outpath) - 1] == '\\')
+      outpath[strlenW(outpath) - 1] = '\0';
   hff = FindFirstFile (outpath, &fd);
   if (hff != INVALID_HANDLE_VALUE) {
     if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-      GetFullPathName (param1, sizeof(inpath), inpath, &infile);
-      strcat (outpath, "\\");
-      strcat (outpath, infile);
+      GetFullPathName (param1, sizeof(inpath)/sizeof(WCHAR), inpath, &infile);
+      strcatW (outpath, slashW);
+      strcatW (outpath, infile);
     }
     FindClose (hff);
   }
 
   /* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
-  if (strstr (quals, "/-Y"))
+  if (strstrW (quals, parmNoY))
     force = FALSE;
-  else if (strstr (quals, "/Y"))
+  else if (strstrW (quals, parmY))
     force = TRUE;
   else {
-    len = GetEnvironmentVariable ("COPYCMD", copycmd, sizeof(copycmd));
-    force = (len && len < sizeof(copycmd) && ! lstrcmpi (copycmd, "/Y"));
+    len = GetEnvironmentVariable (copyCmdW, copycmd, sizeof(copycmd)/sizeof(WCHAR));
+    force = (len && len < (sizeof(copycmd)/sizeof(WCHAR)) && ! lstrcmpiW (copycmd, parmY));
   }
 
   if (!force) {
     hff = FindFirstFile (outpath, &fd);
     if (hff != INVALID_HANDLE_VALUE) {
-      char buffer[MAXSTRING];
+      WCHAR buffer[MAXSTRING];
 
       FindClose (hff);
 
-      sprintf(buffer, WCMD_LoadMessage(WCMD_OVERWRITE), outpath);
+      wsprintf(buffer, WCMD_LoadMessage(WCMD_OVERWRITE), outpath);
       force = WCMD_ask_confirm(buffer, FALSE, NULL);
     }
     else force = TRUE;
@@ -173,21 +184,21 @@
  * they do not already exist.
  */
 
-static BOOL create_full_path(CHAR* path)
+static BOOL create_full_path(WCHAR* path)
 {
     int len;
-    CHAR *new_path;
+    WCHAR *new_path;
     BOOL ret = TRUE;
 
-    new_path = HeapAlloc(GetProcessHeap(),0,strlen(path)+1);
-    strcpy(new_path,path);
+    new_path = HeapAlloc(GetProcessHeap(),0,(strlenW(path) * sizeof(WCHAR))+1);
+    strcpyW(new_path,path);
 
-    while ((len = strlen(new_path)) && new_path[len - 1] == '\\')
+    while ((len = strlenW(new_path)) && new_path[len - 1] == '\\')
         new_path[len - 1] = 0;
 
     while (!CreateDirectory(new_path,NULL))
     {
-        CHAR *slash;
+        WCHAR *slash;
         DWORD last_error = GetLastError();
         if (last_error == ERROR_ALREADY_EXISTS)
             break;
@@ -198,7 +209,7 @@
             break;
         }
 
-        if (!(slash = strrchr(new_path,'\\')) && ! (slash = strrchr(new_path,'/')))
+        if (!(slash = strrchrW(new_path,'\\')) && ! (slash = strrchrW(new_path,'/')))
         {
             ret = FALSE;
             break;
@@ -239,58 +250,66 @@
  *         non-hidden files
  */
 
-BOOL WCMD_delete (char *command, BOOL expectDir) {
+BOOL WCMD_delete (WCHAR *command, BOOL expectDir) {
 
     int   argno         = 0;
     int   argsProcessed = 0;
-    char *argN          = command;
+    WCHAR *argN          = command;
     BOOL  foundAny      = FALSE;
+    static const WCHAR parmA[] = {'/','A','\0'};
+    static const WCHAR parmQ[] = {'/','Q','\0'};
+    static const WCHAR parmP[] = {'/','P','\0'};
+    static const WCHAR parmS[] = {'/','S','\0'};
+    static const WCHAR parmF[] = {'/','F','\0'};
 
     /* If not recursing, clear error flag */
     if (expectDir) errorlevel = 0;
 
     /* Loop through all args */
     while (argN) {
-      char *thisArg = WCMD_parameter (command, argno++, &argN);
-      char argCopy[MAX_PATH];
+      WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
+      WCHAR argCopy[MAX_PATH];
 
       if (argN && argN[0] != '/') {
 
         WIN32_FIND_DATA fd;
         HANDLE hff;
-        char fpath[MAX_PATH];
-        char *p;
+        WCHAR fpath[MAX_PATH];
+        WCHAR *p;
         BOOL handleParm = TRUE;
         BOOL found = FALSE;
+        static const WCHAR anyExt[]= {'.','*','\0'};
 
-        strcpy(argCopy, thisArg);
-        WINE_TRACE("del: Processing arg %s (quals:%s)\n", argCopy, quals);
+        strcpyW(argCopy, thisArg);
+        WINE_TRACE("del: Processing arg %s (quals:%s)\n",
+                   wine_dbgstr_w(argCopy), wine_dbgstr_w(quals));
         argsProcessed++;
 
         /* If filename part of parameter is * or *.*, prompt unless
            /Q supplied.                                            */
-        if ((strstr (quals, "/Q") == NULL) && (strstr (quals, "/P") == NULL)) {
+        if ((strstrW (quals, parmQ) == NULL) && (strstrW (quals, parmP) == NULL)) {
 
-          char drive[10];
-          char dir[MAX_PATH];
-          char fname[MAX_PATH];
-          char ext[MAX_PATH];
+          WCHAR drive[10];
+          WCHAR dir[MAX_PATH];
+          WCHAR fname[MAX_PATH];
+          WCHAR ext[MAX_PATH];
 
           /* Convert path into actual directory spec */
-          GetFullPathName (argCopy, sizeof(fpath), fpath, NULL);
+          GetFullPathName (argCopy, sizeof(fpath)/sizeof(WCHAR), fpath, NULL);
           WCMD_splitpath(fpath, drive, dir, fname, ext);
 
           /* Only prompt for * and *.*, not *a, a*, *.a* etc */
-          if ((strcmp(fname, "*") == 0) &&
-              (*ext == 0x00 || (strcmp(ext, ".*") == 0))) {
+          if ((strcmpW(fname, starW) == 0) &&
+              (*ext == 0x00 || (strcmpW(ext, anyExt) == 0))) {
             BOOL  ok;
-            char  question[MAXSTRING];
+            WCHAR  question[MAXSTRING];
+            static const WCHAR fmt[] = {'%','s',' ','\0'};
 
             /* Note: Flag as found, to avoid file not found message */
             found = TRUE;
 
             /* Ask for confirmation */
-            sprintf(question, "%s, ", fpath);
+            wsprintf(question, fmt, fpath);
             ok = WCMD_ask_confirm(question, TRUE, NULL);
 
             /* Abort if answer is 'N' */
@@ -307,11 +326,13 @@
         }
 
         /* Support del <dirname> by just deleting all files dirname\* */
-        if (handleParm && (strchr(argCopy,'*') == NULL) && (strchr(argCopy,'?') == NULL)
+        if (handleParm && (strchrW(argCopy,'*') == NULL) && (strchrW(argCopy,'?') == NULL)
 		&& (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
-          char modifiedParm[MAX_PATH];
-          strcpy(modifiedParm, argCopy);
-          strcat(modifiedParm, "\\*");
+          WCHAR modifiedParm[MAX_PATH];
+          static const WCHAR slashStar[] = {'\\','*','\0'};
+
+          strcpyW(modifiedParm, argCopy);
+          strcatW(modifiedParm, slashStar);
           FindClose(hff);
           found = TRUE;
           WCMD_delete(modifiedParm, FALSE);
@@ -319,24 +340,24 @@
         } else if (handleParm) {
 
           /* Build the filename to delete as <supplied directory>\<findfirst filename> */
-          strcpy (fpath, argCopy);
+          strcpyW (fpath, argCopy);
           do {
-            p = strrchr (fpath, '\\');
+            p = strrchrW (fpath, '\\');
             if (p != NULL) {
               *++p = '\0';
-              strcat (fpath, fd.cFileName);
+              strcatW (fpath, fd.cFileName);
             }
-            else strcpy (fpath, fd.cFileName);
+            else strcpyW (fpath, fd.cFileName);
             if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
               BOOL  ok = TRUE;
-              char *nextA = strstr (quals, "/A");
+              WCHAR *nextA = strstrW (quals, parmA);
 
               /* Handle attribute matching (/A) */
               if (nextA != NULL) {
                 ok = FALSE;
                 while (nextA != NULL && !ok) {
 
-                  char *thisA = (nextA+2);
+                  WCHAR *thisA = (nextA+2);
                   BOOL  stillOK = TRUE;
 
                   /* Skip optional : */
@@ -383,16 +404,16 @@
                   ok = stillOK;
 
                   /* Step on to next /A set */
-                  nextA = strstr (nextA+1, "/A");
+                  nextA = strstrW (nextA+1, parmA);
                 }
               }
 
               /* /P means prompt for each file */
-              if (ok && strstr (quals, "/P") != NULL) {
-                char  question[MAXSTRING];
+              if (ok && strstrW (quals, parmP) != NULL) {
+                WCHAR  question[MAXSTRING];
 
                 /* Ask for confirmation */
-                sprintf(question, WCMD_LoadMessage(WCMD_DELPROMPT), fpath);
+                wsprintf(question, WCMD_LoadMessage(WCMD_DELPROMPT), fpath);
                 ok = WCMD_ask_confirm(question, FALSE, NULL);
               }
 
@@ -401,7 +422,7 @@
 
                 /* If file is read only, and /F supplied, delete it */
                 if (fd.dwFileAttributes & FILE_ATTRIBUTE_READONLY &&
-                    strstr (quals, "/F") != NULL) {
+                    strstrW (quals, parmF) != NULL) {
                     SetFileAttributes(fpath, fd.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
                 }
 
@@ -415,25 +436,25 @@
         }
 
         /* Now recurse into all subdirectories handling the parameter in the same way */
-        if (strstr (quals, "/S") != NULL) {
+        if (strstrW (quals, parmS) != NULL) {
 
-          char thisDir[MAX_PATH];
+          WCHAR thisDir[MAX_PATH];
           int cPos;
 
-          char drive[10];
-          char dir[MAX_PATH];
-          char fname[MAX_PATH];
-          char ext[MAX_PATH];
+          WCHAR drive[10];
+          WCHAR dir[MAX_PATH];
+          WCHAR fname[MAX_PATH];
+          WCHAR ext[MAX_PATH];
 
           /* Convert path into actual directory spec */
-          GetFullPathName (argCopy, sizeof(thisDir), thisDir, NULL);
+          GetFullPathName (argCopy, sizeof(thisDir)/sizeof(WCHAR), thisDir, NULL);
           WCMD_splitpath(thisDir, drive, dir, fname, ext);
 
-          strcpy(thisDir, drive);
-          strcat(thisDir, dir);
-          cPos = strlen(thisDir);
+          strcpyW(thisDir, drive);
+          strcatW(thisDir, dir);
+          cPos = strlenW(thisDir);
 
-          WINE_TRACE("Searching recursively in '%s'\n", thisDir);
+          WINE_TRACE("Searching recursively in '%s'\n", wine_dbgstr_w(thisDir));
 
           /* Append '*' to the directory */
           thisDir[cPos] = '*';
@@ -450,19 +471,19 @@
 
             do {
               if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
-                  (strcmp(fd.cFileName, "..") != 0) &&
-                  (strcmp(fd.cFileName, ".") != 0)) {
+                  (strcmpW(fd.cFileName, dotdotW) != 0) &&
+                  (strcmpW(fd.cFileName, dotW) != 0)) {
 
                 DIRECTORY_STACK *nextDir;
-                char subParm[MAX_PATH];
+                WCHAR subParm[MAX_PATH];
 
                 /* Work out search parameter in sub dir */
-                strcpy (subParm, thisDir);
-                strcat (subParm, fd.cFileName);
-                strcat (subParm, "\\");
-                strcat (subParm, fname);
-                strcat (subParm, ext);
-                WINE_TRACE("Recursive, Adding to search list '%s'\n", subParm);
+                strcpyW (subParm, thisDir);
+                strcatW (subParm, fd.cFileName);
+                strcatW (subParm, slashW);
+                strcatW (subParm, fname);
+                strcatW (subParm, ext);
+                WINE_TRACE("Recursive, Adding to search list '%s'\n", wine_dbgstr_w(subParm));
 
                 /* Allocate memory, add to list */
                 nextDir = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK));
@@ -470,8 +491,9 @@
                 if (lastEntry != NULL) lastEntry->next = nextDir;
                 lastEntry = nextDir;
                 nextDir->next = NULL;
-                nextDir->dirName = HeapAlloc(GetProcessHeap(),0,(strlen(subParm)+1));
-                strcpy(nextDir->dirName, subParm);
+                nextDir->dirName = HeapAlloc(GetProcessHeap(),0,
+                                             (strlenW(subParm)+1) * sizeof(WCHAR));
+                strcpyW(nextDir->dirName, subParm);
               }
             } while (FindNextFile(hff, &fd) != 0);
             FindClose (hff);
@@ -516,7 +538,7 @@
  * in DOS (try typing "ECHO ON AGAIN" for an example).
  */
 
-void WCMD_echo (const char *command) {
+void WCMD_echo (const WCHAR *command) {
 
   int count;
 
@@ -526,17 +548,17 @@
   }
   if (command[0]==' ')
     command++;
-  count = strlen(command);
+  count = strlenW(command);
   if (count == 0) {
-    if (echo_mode) WCMD_output (WCMD_LoadMessage(WCMD_ECHOPROMPT), "ON");
-    else WCMD_output (WCMD_LoadMessage(WCMD_ECHOPROMPT), "OFF");
+    if (echo_mode) WCMD_output (WCMD_LoadMessage(WCMD_ECHOPROMPT), onW);
+    else WCMD_output (WCMD_LoadMessage(WCMD_ECHOPROMPT), offW);
     return;
   }
-  if (lstrcmpi(command, "ON") == 0) {
+  if (lstrcmpiW(command, onW) == 0) {
     echo_mode = 1;
     return;
   }
-  if (lstrcmpi(command, "OFF") == 0) {
+  if (lstrcmpiW(command, offW) == 0) {
     echo_mode = 0;
     return;
   }
@@ -553,23 +575,25 @@
  * will probably work here, but the reverse is not necessarily the case...
  */
 
-void WCMD_for (char *p) {
+void WCMD_for (WCHAR *p) {
 
   WIN32_FIND_DATA fd;
   HANDLE hff;
-  char *cmd, *item;
-  char set[MAX_PATH], param[MAX_PATH];
+  WCHAR *cmd, *item;
+  WCHAR set[MAX_PATH], param[MAX_PATH];
   int i;
+  const WCHAR inW[] = {'i', 'n', '\0'};
+  const WCHAR doW[] = {'d', 'o', '\0'};
 
-  if (lstrcmpi (WCMD_parameter (p, 1, NULL), "in")
-	|| lstrcmpi (WCMD_parameter (p, 3, NULL), "do")
+  if (lstrcmpiW (WCMD_parameter (p, 1, NULL), inW)
+	|| lstrcmpiW (WCMD_parameter (p, 3, NULL), doW)
 	|| (param1[0] != '%')) {
     WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
     return;
   }
-  lstrcpyn (set, WCMD_parameter (p, 2, NULL), sizeof(set));
+  lstrcpynW (set, WCMD_parameter (p, 2, NULL), sizeof(set)/sizeof(WCHAR));
   WCMD_parameter (p, 4, &cmd);
-  lstrcpy (param, param1);
+  strcpyW (param, param1);
 
 /*
  *	If the parameter within the set has a wildcard then search for matching files
@@ -578,7 +602,8 @@
 
   i = 0;
   while (*(item = WCMD_parameter (set, i, NULL))) {
-    if (strpbrk (item, "*?")) {
+    static const WCHAR wildcards[] = {'*','?','\0'};
+    if (strpbrkW (item, wildcards)) {
       hff = FindFirstFile (item, &fd);
       if (hff == INVALID_HANDLE_VALUE) {
 	return;
@@ -601,24 +626,24 @@
  *	Execute a command after substituting variable text for the supplied parameter
  */
 
-void WCMD_execute (char *orig_cmd, char *param, char *subst) {
+void WCMD_execute (WCHAR *orig_cmd, WCHAR *param, WCHAR *subst) {
 
-  char *new_cmd, *p, *s, *dup;
+  WCHAR *new_cmd, *p, *s, *dup;
   int size;
 
-  size = lstrlen (orig_cmd);
-  new_cmd = (char *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size);
-  dup = s = strdup (orig_cmd);
+  size = strlenW (orig_cmd);
+  new_cmd = (WCHAR *) LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, size);
+  dup = s = WCMD_strdupW(orig_cmd);
 
-  while ((p = strstr (s, param))) {
+  while ((p = strstrW (s, param))) {
     *p = '\0';
-    size += lstrlen (subst);
-    new_cmd = (char *) LocalReAlloc ((HANDLE)new_cmd, size, 0);
-    strcat (new_cmd, s);
-    strcat (new_cmd, subst);
-    s = p + lstrlen (param);
+    size += strlenW (subst);
+    new_cmd = (WCHAR *) LocalReAlloc ((HANDLE)new_cmd, size, 0);
+    strcatW (new_cmd, s);
+    strcatW (new_cmd, subst);
+    s = p + strlenW (param);
   }
-  strcat (new_cmd, s);
+  strcatW (new_cmd, s);
   WCMD_process_command (new_cmd);
   free (dup);
   LocalFree ((HANDLE)new_cmd);
@@ -631,21 +656,21 @@
  *	Simple on-line help. Help text is stored in the resource file.
  */
 
-void WCMD_give_help (char *command) {
+void WCMD_give_help (WCHAR *command) {
 
   int i;
-  char buffer[2048];
+  WCHAR buffer[2048];
 
   command = WCMD_strtrim_leading_spaces(command);
-  if (lstrlen(command) == 0) {
-    LoadString (hinst, 1000, buffer, sizeof(buffer));
+  if (strlenW(command) == 0) {
+    LoadString (hinst, 1000, buffer, sizeof(buffer)/sizeof(WCHAR));
     WCMD_output_asis (buffer);
   }
   else {
     for (i=0; i<=WCMD_EXIT; i++) {
       if (CompareString (LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
 	  param1, -1, inbuilt[i], -1) == 2) {
-	LoadString (hinst, i, buffer, sizeof(buffer));
+	LoadString (hinst, i, buffer, sizeof(buffer)/sizeof(WCHAR));
 	WCMD_output_asis (buffer);
 	return;
       }
@@ -666,17 +691,18 @@
 
 void WCMD_goto (void) {
 
-  char string[MAX_PATH];
+  WCHAR string[MAX_PATH];
 
   if (param1[0] == 0x00) {
     WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
     return;
   }
   if (context != NULL) {
-    char *paramStart = param1;
+    WCHAR *paramStart = param1;
+    static const WCHAR eofW[] = {':','e','o','f','\0'};
 
     /* Handle special :EOF label */
-    if (lstrcmpi (":eof", param1) == 0) {
+    if (lstrcmpiW (eofW, param1) == 0) {
       context -> skip_rest = TRUE;
       return;
     }
@@ -685,8 +711,8 @@
     if (*paramStart == ':') paramStart++;
 
     SetFilePointer (context -> h, 0, NULL, FILE_BEGIN);
-    while (WCMD_fgets (string, sizeof(string), context -> h)) {
-      if ((string[0] == ':') && (lstrcmpi (&string[1], paramStart) == 0)) return;
+    while (WCMD_fgets (string, sizeof(string)/sizeof(WCHAR), context -> h)) {
+      if ((string[0] == ':') && (lstrcmpiW (&string[1], paramStart) == 0)) return;
     }
     WCMD_output (WCMD_LoadMessage(WCMD_NOTARGET));
   }
@@ -699,11 +725,12 @@
  *	Push a directory onto the stack
  */
 
-void WCMD_pushd (char *command) {
+void WCMD_pushd (WCHAR *command) {
     struct env_stack *curdir;
     WCHAR *thisdir;
+    static const WCHAR parmD[] = {'/','D','\0'};
 
-    if (strchr(command, '/') != NULL) {
+    if (strchrW(command, '/') != NULL) {
       SetLastError(ERROR_INVALID_PARAMETER);
       WCMD_print_error();
       return;
@@ -719,7 +746,7 @@
     }
 
     /* Change directory using CD code with /D parameter */
-    strcpy(quals, "/D");
+    strcpyW(quals, parmD);
     GetCurrentDirectoryW (1024, thisdir);
     errorlevel = 0;
     WCMD_setshow_default(command);
@@ -766,37 +793,42 @@
  * FIXME: Much more syntax checking needed!
  */
 
-void WCMD_if (char *p) {
+void WCMD_if (WCHAR *p) {
 
   int negate = 0, test = 0;
-  char condition[MAX_PATH], *command, *s;
+  WCHAR condition[MAX_PATH], *command, *s;
+  static const WCHAR notW[]    = {'n','o','t','\0'};
+  static const WCHAR errlvlW[] = {'e','r','r','o','r','l','e','v','e','l','\0'};
+  static const WCHAR existW[]  = {'e','x','i','s','t','\0'};
+  static const WCHAR defdW[]   = {'d','e','f','i','n','e','d','\0'};
+  static const WCHAR eqeqW[]   = {'=','=','\0'};
 
-  if (!lstrcmpi (param1, "not")) {
+  if (!lstrcmpiW (param1, notW)) {
     negate = 1;
-    lstrcpy (condition, param2);
+    strcpyW (condition, param2);
   }
   else {
-    lstrcpy (condition, param1);
+    strcpyW (condition, param1);
   }
-  if (!lstrcmpi (condition, "errorlevel")) {
-    if (errorlevel >= atoi(WCMD_parameter (p, 1+negate, NULL))) test = 1;
+  if (!lstrcmpiW (condition, errlvlW)) {
+    if (errorlevel >= atoiW(WCMD_parameter (p, 1+negate, NULL))) test = 1;
     WCMD_parameter (p, 2+negate, &command);
   }
-  else if (!lstrcmpi (condition, "exist")) {
-    if (GetFileAttributesA(WCMD_parameter (p, 1+negate, NULL)) != INVALID_FILE_ATTRIBUTES) {
+  else if (!lstrcmpiW (condition, existW)) {
+    if (GetFileAttributes(WCMD_parameter (p, 1+negate, NULL)) != INVALID_FILE_ATTRIBUTES) {
         test = 1;
     }
     WCMD_parameter (p, 2+negate, &command);
   }
-  else if (!lstrcmpi (condition, "defined")) {
-    if (GetEnvironmentVariableA(WCMD_parameter (p, 1+negate, NULL), NULL, 0) > 0) {
+  else if (!lstrcmpiW (condition, defdW)) {
+    if (GetEnvironmentVariable(WCMD_parameter (p, 1+negate, NULL), NULL, 0) > 0) {
         test = 1;
     }
     WCMD_parameter (p, 2+negate, &command);
   }
-  else if ((s = strstr (p, "=="))) {
+  else if ((s = strstrW (p, eqeqW))) {
     s += 2;
-    if (!lstrcmpi (condition, WCMD_parameter (s, 0, NULL))) test = 1;
+    if (!lstrcmpiW (condition, WCMD_parameter (s, 0, NULL))) test = 1;
     WCMD_parameter (s, 1, &command);
   }
   else {
@@ -804,7 +836,7 @@
     return;
   }
   if (test != negate) {
-    command = strdup (command);
+    command = WCMD_strdupW(command);
     WCMD_process_command (command);
     free (command);
   }
@@ -821,12 +853,12 @@
   int             status;
   WIN32_FIND_DATA fd;
   HANDLE          hff;
-  char            input[MAX_PATH];
-  char            output[MAX_PATH];
-  char            drive[10];
-  char            dir[MAX_PATH];
-  char            fname[MAX_PATH];
-  char            ext[MAX_PATH];
+  WCHAR            input[MAX_PATH];
+  WCHAR            output[MAX_PATH];
+  WCHAR            drive[10];
+  WCHAR            dir[MAX_PATH];
+  WCHAR            fname[MAX_PATH];
+  WCHAR            ext[MAX_PATH];
 
   if (param1[0] == 0x00) {
     WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
@@ -835,48 +867,49 @@
 
   /* If no destination supplied, assume current directory */
   if (param2[0] == 0x00) {
-      strcpy(param2, ".");
+      strcpyW(param2, dotW);
   }
 
   /* If 2nd parm is directory, then use original filename */
   /* Convert partial path to full path */
-  GetFullPathName (param1, sizeof(input), input, NULL);
-  GetFullPathName (param2, sizeof(output), output, NULL);
-  WINE_TRACE("Move from '%s'('%s') to '%s'\n", input, param1, output);
+  GetFullPathName (param1, sizeof(input)/sizeof(WCHAR), input, NULL);
+  GetFullPathName (param2, sizeof(output)/sizeof(WCHAR), output, NULL);
+  WINE_TRACE("Move from '%s'('%s') to '%s'\n", wine_dbgstr_w(input),
+             wine_dbgstr_w(param1), wine_dbgstr_w(output));
 
   /* Split into components */
   WCMD_splitpath(input, drive, dir, fname, ext);
 
   hff = FindFirstFile (input, &fd);
   while (hff != INVALID_HANDLE_VALUE) {
-    char  dest[MAX_PATH];
-    char  src[MAX_PATH];
+    WCHAR  dest[MAX_PATH];
+    WCHAR  src[MAX_PATH];
     DWORD attribs;
 
-    WINE_TRACE("Processing file '%s'\n", fd.cFileName);
+    WINE_TRACE("Processing file '%s'\n", wine_dbgstr_w(fd.cFileName));
 
     /* Build src & dest name */
-    strcpy(src, drive);
-    strcat(src, dir);
+    strcpyW(src, drive);
+    strcatW(src, dir);
 
     /* See if dest is an existing directory */
     attribs = GetFileAttributes(output);
     if (attribs != INVALID_FILE_ATTRIBUTES &&
        (attribs & FILE_ATTRIBUTE_DIRECTORY)) {
-      strcpy(dest, output);
-      strcat(dest, "\\");
-      strcat(dest, fd.cFileName);
+      strcpyW(dest, output);
+      strcatW(dest, slashW);
+      strcatW(dest, fd.cFileName);
     } else {
-      strcpy(dest, output);
+      strcpyW(dest, output);
     }
 
-    strcat(src, fd.cFileName);
+    strcatW(src, fd.cFileName);
 
-    WINE_TRACE("Source '%s'\n", src);
-    WINE_TRACE("Dest   '%s'\n", dest);
+    WINE_TRACE("Source '%s'\n", wine_dbgstr_w(src));
+    WINE_TRACE("Dest   '%s'\n", wine_dbgstr_w(dest));
 
     /* Check if file is read only, otherwise move it */
-    attribs = GetFileAttributesA(src);
+    attribs = GetFileAttributes(src);
     if ((attribs != INVALID_FILE_ATTRIBUTES) &&
         (attribs & FILE_ATTRIBUTE_READONLY)) {
       SetLastError(ERROR_ACCESS_DENIED);
@@ -885,30 +918,32 @@
       BOOL ok = TRUE;
 
       /* If destination exists, prompt unless /Y supplied */
-      if (GetFileAttributesA(dest) != INVALID_FILE_ATTRIBUTES) {
+      if (GetFileAttributes(dest) != INVALID_FILE_ATTRIBUTES) {
         BOOL force = FALSE;
-        char copycmd[MAXSTRING];
+        WCHAR copycmd[MAXSTRING];
         int len;
 
         /* /-Y has the highest priority, then /Y and finally the COPYCMD env. variable */
-        if (strstr (quals, "/-Y"))
+        if (strstrW (quals, parmNoY))
           force = FALSE;
-        else if (strstr (quals, "/Y"))
+        else if (strstrW (quals, parmY))
           force = TRUE;
         else {
-          len = GetEnvironmentVariable ("COPYCMD", copycmd, sizeof(copycmd));
-          force = (len && len < sizeof(copycmd) && ! lstrcmpi (copycmd, "/Y"));
+          const WCHAR copyCmdW[] = {'C','O','P','Y','C','M','D','\0'};
+          len = GetEnvironmentVariable (copyCmdW, copycmd, sizeof(copycmd)/sizeof(WCHAR));
+          force = (len && len < (sizeof(copycmd)/sizeof(WCHAR))
+                       && ! lstrcmpiW (copycmd, parmY));
         }
 
         /* Prompt if overwriting */
         if (!force) {
-          char  question[MAXSTRING];
-          char  yesChar[10];
+          WCHAR  question[MAXSTRING];
+          WCHAR  yesChar[10];
 
-          strcpy(yesChar, WCMD_LoadMessage(WCMD_YES));
+          strcpyW(yesChar, WCMD_LoadMessage(WCMD_YES));
 
           /* Ask for confirmation */
-          sprintf(question, WCMD_LoadMessage(WCMD_OVERWRITE), dest);
+          wsprintf(question, WCMD_LoadMessage(WCMD_OVERWRITE), dest);
           ok = WCMD_ask_confirm(question, FALSE, NULL);
 
           /* So delete the destination prior to the move */
@@ -952,10 +987,11 @@
 void WCMD_pause (void) {
 
   DWORD count;
-  char string[32];
+  WCHAR string[32];
 
   WCMD_output (anykey);
-  ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
+  WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
+                 sizeof(string)/sizeof(WCHAR), &count, NULL);
 }
 
 /****************************************************************************
@@ -964,22 +1000,25 @@
  * Delete a directory.
  */
 
-void WCMD_remove_dir (char *command) {
+void WCMD_remove_dir (WCHAR *command) {
 
   int   argno         = 0;
   int   argsProcessed = 0;
-  char *argN          = command;
+  WCHAR *argN          = command;
+  static const WCHAR parmS[] = {'/','S','\0'};
+  static const WCHAR parmQ[] = {'/','Q','\0'};
 
   /* Loop through all args */
   while (argN) {
-    char *thisArg = WCMD_parameter (command, argno++, &argN);
+    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
     if (argN && argN[0] != '/') {
-      WINE_TRACE("rd: Processing arg %s (quals:%s)\n", thisArg, quals);
+      WINE_TRACE("rd: Processing arg %s (quals:%s)\n", wine_dbgstr_w(thisArg),
+                 wine_dbgstr_w(quals));
       argsProcessed++;
 
       /* If subdirectory search not supplied, just try to remove
          and report error if it fails (eg if it contains a file) */
-      if (strstr (quals, "/S") == NULL) {
+      if (strstrW (quals, parmS) == NULL) {
         if (!RemoveDirectory (thisArg)) WCMD_print_error ();
 
       /* Otherwise use ShFileOp to recursively remove a directory */
@@ -988,12 +1027,13 @@
         SHFILEOPSTRUCT lpDir;
 
         /* Ask first */
-        if (strstr (quals, "/Q") == NULL) {
+        if (strstrW (quals, parmQ) == NULL) {
           BOOL  ok;
-          char  question[MAXSTRING];
+          WCHAR  question[MAXSTRING];
+          static const WCHAR fmt[] = {'%','s',' ','\0'};
 
           /* Ask for confirmation */
-          sprintf(question, "%s, ", thisArg);
+          wsprintf(question, fmt, thisArg);
           ok = WCMD_ask_confirm(question, TRUE, NULL);
 
           /* Abort if answer is 'N' */
@@ -1006,7 +1046,7 @@
         lpDir.pFrom  = thisArg;
         lpDir.fFlags = FOF_SILENT | FOF_NOCONFIRMATION | FOF_NOERRORUI;
         lpDir.wFunc  = FO_DELETE;
-        if (SHFileOperationA(&lpDir)) WCMD_print_error ();
+        if (SHFileOperation(&lpDir)) WCMD_print_error ();
       }
     }
   }
@@ -1030,12 +1070,12 @@
   int             status;
   HANDLE          hff;
   WIN32_FIND_DATA fd;
-  char            input[MAX_PATH];
-  char           *dotDst = NULL;
-  char            drive[10];
-  char            dir[MAX_PATH];
-  char            fname[MAX_PATH];
-  char            ext[MAX_PATH];
+  WCHAR            input[MAX_PATH];
+  WCHAR           *dotDst = NULL;
+  WCHAR            drive[10];
+  WCHAR            dir[MAX_PATH];
+  WCHAR            fname[MAX_PATH];
+  WCHAR            ext[MAX_PATH];
   DWORD           attribs;
 
   errorlevel = 0;
@@ -1048,7 +1088,7 @@
   }
 
   /* Destination cannot contain a drive letter or directory separator */
-  if ((strchr(param1,':') != NULL) || (strchr(param1,'\\') != NULL)) {
+  if ((strchrW(param1,':') != NULL) || (strchrW(param1,'\\') != NULL)) {
       SetLastError(ERROR_INVALID_PARAMETER);
       WCMD_print_error();
       errorlevel = 1;
@@ -1056,21 +1096,22 @@
   }
 
   /* Convert partial path to full path */
-  GetFullPathName (param1, sizeof(input), input, NULL);
-  WINE_TRACE("Rename from '%s'('%s') to '%s'\n", input, param1, param2);
-  dotDst = strchr(param2, '.');
+  GetFullPathName (param1, sizeof(input)/sizeof(WCHAR), input, NULL);
+  WINE_TRACE("Rename from '%s'('%s') to '%s'\n", wine_dbgstr_w(input),
+             wine_dbgstr_w(param1), wine_dbgstr_w(param2));
+  dotDst = strchrW(param2, '.');
 
   /* Split into components */
   WCMD_splitpath(input, drive, dir, fname, ext);
 
   hff = FindFirstFile (input, &fd);
   while (hff != INVALID_HANDLE_VALUE) {
-    char  dest[MAX_PATH];
-    char  src[MAX_PATH];
-    char *dotSrc = NULL;
+    WCHAR  dest[MAX_PATH];
+    WCHAR  src[MAX_PATH];
+    WCHAR *dotSrc = NULL;
     int   dirLen;
 
-    WINE_TRACE("Processing file '%s'\n", fd.cFileName);
+    WINE_TRACE("Processing file '%s'\n", wine_dbgstr_w(fd.cFileName));
 
     /* FIXME: If dest name or extension is *, replace with filename/ext
        part otherwise use supplied name. This supports:
@@ -1078,36 +1119,36 @@
           ren jim.* fred.* etc
        However, windows has a more complex algorithum supporting eg
           ?'s and *'s mid name                                         */
-    dotSrc = strchr(fd.cFileName, '.');
+    dotSrc = strchrW(fd.cFileName, '.');
 
     /* Build src & dest name */
-    strcpy(src, drive);
-    strcat(src, dir);
-    strcpy(dest, src);
-    dirLen = strlen(src);
-    strcat(src, fd.cFileName);
+    strcpyW(src, drive);
+    strcatW(src, dir);
+    strcpyW(dest, src);
+    dirLen = strlenW(src);
+    strcatW(src, fd.cFileName);
 
     /* Build name */
     if (param2[0] == '*') {
-      strcat(dest, fd.cFileName);
+      strcatW(dest, fd.cFileName);
       if (dotSrc) dest[dirLen + (dotSrc - fd.cFileName)] = 0x00;
     } else {
-      strcat(dest, param2);
+      strcatW(dest, param2);
       if (dotDst) dest[dirLen + (dotDst - param2)] = 0x00;
     }
 
     /* Build Extension */
     if (dotDst && (*(dotDst+1)=='*')) {
-      if (dotSrc) strcat(dest, dotSrc);
+      if (dotSrc) strcatW(dest, dotSrc);
     } else if (dotDst) {
-      if (dotDst) strcat(dest, dotDst);
+      if (dotDst) strcatW(dest, dotDst);
     }
 
-    WINE_TRACE("Source '%s'\n", src);
-    WINE_TRACE("Dest   '%s'\n", dest);
+    WINE_TRACE("Source '%s'\n", wine_dbgstr_w(src));
+    WINE_TRACE("Dest   '%s'\n", wine_dbgstr_w(dest));
 
     /* Check if file is read only, otherwise move it */
-    attribs = GetFileAttributesA(src);
+    attribs = GetFileAttributes(src);
     if ((attribs != INVALID_FILE_ATTRIBUTES) &&
         (attribs & FILE_ATTRIBUTE_READONLY)) {
       SetLastError(ERROR_ACCESS_DENIED);
@@ -1145,7 +1186,7 @@
 
   len = 0;
   while ( env[len] )
-    len += (lstrlenW(&env[len]) + 1);
+    len += (strlenW(&env[len]) + 1);
 
   env_copy = LocalAlloc (LMEM_FIXED, (len+1) * sizeof (WCHAR) );
   if (!env_copy)
@@ -1165,10 +1206,10 @@
  *  setlocal pushes the environment onto a stack
  *  Save the environment as unicode so we don't screw anything up.
  */
-void WCMD_setlocal (const char *s) {
+void WCMD_setlocal (const WCHAR *s) {
   WCHAR *env;
   struct env_stack *env_copy;
-  char cwd[MAX_PATH];
+  WCHAR cwd[MAX_PATH];
 
   /* DISABLEEXTENSIONS ignored */
 
@@ -1199,24 +1240,10 @@
 }
 
 /*****************************************************************************
- * WCMD_strchrW
- */
-static inline WCHAR *WCMD_strchrW(WCHAR *str, WCHAR ch)
-{
-   while(*str)
-   {
-     if(*str == ch)
-       return str;
-     str++;
-   }
-   return NULL;
-}
-
-/*****************************************************************************
  * WCMD_endlocal
  *
  *  endlocal pops the environment off a stack
- *  Note: When searching for '=', search from char position 1, to handle
+ *  Note: When searching for '=', search from WCHAR position 1, to handle
  *        special internal environment variables =C:, =D: etc
  */
 void WCMD_endlocal (void) {
@@ -1236,8 +1263,8 @@
   old = WCMD_dupenv (GetEnvironmentStringsW ());
   len = 0;
   while (old[len]) {
-    n = lstrlenW(&old[len]) + 1;
-    p = WCMD_strchrW(&old[len] + 1, '=');
+    n = strlenW(&old[len]) + 1;
+    p = strchrW(&old[len] + 1, '=');
     if (p)
     {
       *p++ = 0;
@@ -1252,8 +1279,8 @@
   env = temp->strings;
   len = 0;
   while (env[len]) {
-    n = lstrlenW(&env[len]) + 1;
-    p = WCMD_strchrW(&env[len] + 1, '=');
+    n = strlenW(&env[len]) + 1;
+    p = strchrW(&env[len] + 1, '=');
     if (p)
     {
       *p++ = 0;
@@ -1264,11 +1291,13 @@
 
   /* Restore current drive letter */
   if (IsCharAlpha(temp->u.cwd)) {
-    char envvar[4];
-    char cwd[MAX_PATH];
-    sprintf(envvar, "=%c:", temp->u.cwd);
+    WCHAR envvar[4];
+    WCHAR cwd[MAX_PATH];
+    static const WCHAR fmt[] = {'=','%','c',':','\0'};
+
+    wsprintf(envvar, fmt, temp->u.cwd);
     if (GetEnvironmentVariable(envvar, cwd, MAX_PATH)) {
-      WINE_TRACE("Resetting cwd to %s\n", cwd);
+      WINE_TRACE("Resetting cwd to %s\n", wine_dbgstr_w(cwd));
       SetCurrentDirectory(cwd);
     }
   }
@@ -1295,16 +1324,18 @@
   DWORD count;
   HANDLE hff;
   WIN32_FIND_DATA fd;
-  char flags[9] = {"        "};
+  WCHAR flags[9] = {' ',' ',' ',' ',' ',' ',' ',' ','\0'};
 
   if (param1[0] == '-') {
     WCMD_output (WCMD_LoadMessage(WCMD_NYI));
     return;
   }
 
-  if (lstrlen(param1) == 0) {
-    GetCurrentDirectory (sizeof(param1), param1);
-    strcat (param1, "\\*");
+  if (strlenW(param1) == 0) {
+    static const WCHAR slashStarW[]  = {'\\','*','\0'};
+
+    GetCurrentDirectory (sizeof(param1)/sizeof(WCHAR), param1);
+    strcatW (param1, slashStarW);
   }
 
   hff = FindFirstFile (param1, &fd);
@@ -1314,6 +1345,7 @@
   else {
     do {
       if (!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
+        static const WCHAR fmt[] = {'%','s',' ',' ',' ','%','s','\n','\0'};
         if (fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) {
 	  flags[0] = 'H';
 	}
@@ -1332,7 +1364,7 @@
         if (fd.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) {
 	  flags[5] = 'C';
 	}
-        WCMD_output ("%s   %s\n", flags, fd.cFileName);
+        WCMD_output (fmt, flags, fd.cFileName);
 	for (count=0; count < 8; count++) flags[count] = ' ';
       }
     } while (FindNextFile(hff, &fd) != 0);
@@ -1346,28 +1378,29 @@
  *	Set/Show the current default directory
  */
 
-void WCMD_setshow_default (char *command) {
+void WCMD_setshow_default (WCHAR *command) {
 
   BOOL status;
-  char string[1024];
-  char cwd[1024];
-  char *pos;
+  WCHAR string[1024];
+  WCHAR cwd[1024];
+  WCHAR *pos;
   WIN32_FIND_DATA fd;
   HANDLE hff;
+  static const WCHAR parmD[] = {'/','D','\0'};
 
-  WINE_TRACE("Request change to directory '%s'\n", command);
+  WINE_TRACE("Request change to directory '%s'\n", wine_dbgstr_w(command));
 
   /* Skip /D and trailing whitespace if on the front of the command line */
   if (CompareString (LOCALE_USER_DEFAULT,
                      NORM_IGNORECASE | SORT_STRINGSORT,
-                     command, 2, "/D", -1) == 2) {
+                     command, 2, parmD, -1) == 2) {
     command += 2;
     while (*command && *command==' ') command++;
   }
 
-  GetCurrentDirectory (sizeof(cwd), cwd);
-  if (strlen(command) == 0) {
-    strcat (cwd, newline);
+  GetCurrentDirectory (sizeof(cwd)/sizeof(WCHAR), cwd);
+  if (strlenW(command) == 0) {
+    strcatW (cwd, newline);
     WCMD_output (cwd);
   }
   else {
@@ -1381,22 +1414,23 @@
     *pos = 0x00;
 
     /* Search for approprate directory */
-    WINE_TRACE("Looking for directory '%s'\n", string);
+    WINE_TRACE("Looking for directory '%s'\n", wine_dbgstr_w(string));
     hff = FindFirstFile (string, &fd);
     while (hff != INVALID_HANDLE_VALUE) {
       if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-        char fpath[MAX_PATH];
-        char drive[10];
-        char dir[MAX_PATH];
-        char fname[MAX_PATH];
-        char ext[MAX_PATH];
+        WCHAR fpath[MAX_PATH];
+        WCHAR drive[10];
+        WCHAR dir[MAX_PATH];
+        WCHAR fname[MAX_PATH];
+        WCHAR ext[MAX_PATH];
+        static const WCHAR fmt[] = {'%','s','%','s','%','s','\0'};
 
         /* Convert path into actual directory spec */
-        GetFullPathName (string, sizeof(fpath), fpath, NULL);
+        GetFullPathName (string, sizeof(fpath)/sizeof(WCHAR), fpath, NULL);
         WCMD_splitpath(fpath, drive, dir, fname, ext);
 
         /* Rebuild path */
-        sprintf(string, "%s%s%s", drive, dir, fd.cFileName);
+        wsprintf(string, fmt, drive, dir, fd.cFileName);
 
         FindClose(hff);
         hff = INVALID_HANDLE_VALUE;
@@ -1412,7 +1446,7 @@
     }
 
     /* Change to that directory */
-    WINE_TRACE("Really changing to directory '%s'\n", string);
+    WINE_TRACE("Really changing to directory '%s'\n", wine_dbgstr_w(string));
 
     status = SetCurrentDirectory (string);
     if (!status) {
@@ -1423,7 +1457,7 @@
 
       /* Restore old directory if drive letter would change, and
            CD x:\directory /D (or pushd c:\directory) not supplied */
-      if ((strstr(quals, "/D") == NULL) &&
+      if ((strstrW(quals, parmD) == NULL) &&
           (param1[1] == ':') && (toupper(param1[0]) != toupper(cwd[0]))) {
         SetCurrentDirectory(cwd);
       }
@@ -1434,10 +1468,11 @@
        /D (allows changing drive letter when not resident on that
        drive                                                          */
     if ((string[1] == ':') && IsCharAlpha (string[0])) {
-      char env[4];
-      strcpy(env, "=");
-      strncpy(env+1, string, 2);
+      WCHAR env[4];
+      strcpyW(env, equalW);
+      memcpy(env+1, string, 2 * sizeof(WCHAR));
       env[3] = 0x00;
+      WINE_FIXME("Setting '%s' to '%s'\n", wine_dbgstr_w(env), wine_dbgstr_w(string));
       SetEnvironmentVariable(env, string);
     }
 
@@ -1454,16 +1489,18 @@
 
 void WCMD_setshow_date (void) {
 
-  char curdate[64], buffer[64];
+  WCHAR curdate[64], buffer[64];
   DWORD count;
+  static const WCHAR parmT[] = {'/','T','\0'};
 
-  if (lstrlen(param1) == 0) {
+  if (strlenW(param1) == 0) {
     if (GetDateFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL,
-  		curdate, sizeof(curdate))) {
+		curdate, sizeof(curdate)/sizeof(WCHAR))) {
       WCMD_output (WCMD_LoadMessage(WCMD_CURRENTDATE), curdate);
-      if (strstr (quals, "/T") == NULL) {
+      if (strstrW (quals, parmT) == NULL) {
         WCMD_output (WCMD_LoadMessage(WCMD_NEWDATE));
-        ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer, sizeof(buffer), &count, NULL);
+        WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE),
+                       buffer, sizeof(buffer)/sizeof(WCHAR), &count, NULL);
         if (count > 2) {
           WCMD_output (WCMD_LoadMessage(WCMD_NYI));
         }
@@ -1482,7 +1519,7 @@
 static int WCMD_compare( const void *a, const void *b )
 {
     int r;
-    const char * const *str_a = a, * const *str_b = b;
+    const WCHAR * const *str_a = a, * const *str_b = b;
     r = CompareString( LOCALE_USER_DEFAULT, NORM_IGNORECASE | SORT_STRINGSORT,
 	  *str_a, -1, *str_b, -1 );
     if( r == CSTR_LESS_THAN ) return -1;
@@ -1497,29 +1534,29 @@
  * Optionally only display those who start with a stub
  * returns the count displayed
  */
-static int WCMD_setshow_sortenv(const char *s, const char *stub)
+static int WCMD_setshow_sortenv(const WCHAR *s, const WCHAR *stub)
 {
   UINT count=0, len=0, i, displayedcount=0, stublen=0;
-  const char **str;
+  const WCHAR **str;
 
-  if (stub) stublen = strlen(stub);
+  if (stub) stublen = strlenW(stub);
 
   /* count the number of strings, and the total length */
   while ( s[len] ) {
-    len += (lstrlen(&s[len]) + 1);
+    len += (strlenW(&s[len]) + 1);
     count++;
   }
 
   /* add the strings to an array */
-  str = LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, count * sizeof (char*) );
+  str = LocalAlloc (LMEM_FIXED | LMEM_ZEROINIT, count * sizeof (WCHAR*) );
   if( !str )
     return 0;
   str[0] = s;
   for( i=1; i<count; i++ )
-    str[i] = str[i-1] + lstrlen(str[i-1]) + 1;
+    str[i] = str[i-1] + strlenW(str[i-1]) + 1;
 
   /* sort the array */
-  qsort( str, count, sizeof (char*), WCMD_compare );
+  qsort( str, count, sizeof (WCHAR*), WCMD_compare );
 
   /* print it */
   for( i=0; i<count; i++ ) {
@@ -1545,11 +1582,12 @@
  * Set/Show the environment variables
  */
 
-void WCMD_setshow_env (char *s) {
+void WCMD_setshow_env (WCHAR *s) {
 
   LPVOID env;
-  char *p;
+  WCHAR *p;
   int status;
+  static const WCHAR parmP[] = {'/','P','\0'};
 
   errorlevel = 0;
   if (param1[0] == 0x00 && quals[0] == 0x00) {
@@ -1561,35 +1599,37 @@
   /* See if /P supplied, and if so echo the prompt, and read in a reply */
   if (CompareString (LOCALE_USER_DEFAULT,
                      NORM_IGNORECASE | SORT_STRINGSORT,
-                     s, 2, "/P", -1) == 2) {
-    char string[MAXSTRING];
+                     s, 2, parmP, -1) == 2) {
+    WCHAR string[MAXSTRING];
     DWORD count;
 
     s += 2;
     while (*s && *s==' ') s++;
 
     /* If no parameter, or no '=' sign, return an error */
-    if (!(*s) || ((p = strchr (s, '=')) == NULL )) {
+    if (!(*s) || ((p = strchrW (s, '=')) == NULL )) {
       WCMD_output (WCMD_LoadMessage(WCMD_NOARG));
       return;
     }
 
     /* Output the prompt */
     *p++ = '\0';
-    if (strlen(p) != 0) WCMD_output(p);
+    if (strlenW(p) != 0) WCMD_output(p);
 
     /* Read the reply */
-    ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
+    WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
+                   sizeof(string)/sizeof(WCHAR), &count, NULL);
     if (count > 1) {
       string[count-1] = '\0'; /* ReadFile output is not null-terminated! */
       if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */
-      WINE_TRACE("set /p: Setting var '%s' to '%s'\n", s, string);
+      WINE_TRACE("set /p: Setting var '%s' to '%s'\n", wine_dbgstr_w(s),
+                 wine_dbgstr_w(string));
       status = SetEnvironmentVariable (s, string);
     }
 
   } else {
     DWORD gle;
-    p = strchr (s, '=');
+    p = strchrW (s, '=');
     if (p == NULL) {
       env = GetEnvironmentStrings ();
       if (WCMD_setshow_sortenv( env, s ) == 0) {
@@ -1600,7 +1640,7 @@
     }
     *p++ = '\0';
 
-    if (strlen(p) == 0) p = NULL;
+    if (strlenW(p) == 0) p = NULL;
     status = SetEnvironmentVariable (s, p);
     gle = GetLastError();
     if ((!status) & (gle == ERROR_ENVVAR_NOT_FOUND)) {
@@ -1615,25 +1655,27 @@
  * Set/Show the path environment variable
  */
 
-void WCMD_setshow_path (char *command) {
+void WCMD_setshow_path (WCHAR *command) {
 
-  char string[1024];
+  WCHAR string[1024];
   DWORD status;
+  static const WCHAR pathW[] = {'P','A','T','H','\0'};
+  static const WCHAR pathEqW[] = {'P','A','T','H','=','\0'};
 
-  if (strlen(param1) == 0) {
-    status = GetEnvironmentVariable ("PATH", string, sizeof(string));
+  if (strlenW(param1) == 0) {
+    status = GetEnvironmentVariable (pathW, string, sizeof(string)/sizeof(WCHAR));
     if (status != 0) {
-      WCMD_output_asis ( "PATH=");
+      WCMD_output_asis ( pathEqW);
       WCMD_output_asis ( string);
       WCMD_output_asis ( newline);
     }
     else {
-      WCMD_output ("PATH not found\n");
+      WCMD_output (WCMD_LoadMessage(WCMD_NOPATH));
     }
   }
   else {
     if (*command == '=') command++; /* Skip leading '=' */
-    status = SetEnvironmentVariable ("PATH", command);
+    status = SetEnvironmentVariable (pathW, command);
     if (!status) WCMD_print_error();
   }
 }
@@ -1646,18 +1688,19 @@
 
 void WCMD_setshow_prompt (void) {
 
-  char *s;
+  WCHAR *s;
+  static const WCHAR promptW[] = {'P','R','O','M','P','T','\0'};
 
-  if (strlen(param1) == 0) {
-    SetEnvironmentVariable ("PROMPT", NULL);
+  if (strlenW(param1) == 0) {
+    SetEnvironmentVariable (promptW, NULL);
   }
   else {
     s = param1;
     while ((*s == '=') || (*s == ' ')) s++;
-    if (strlen(s) == 0) {
-      SetEnvironmentVariable ("PROMPT", NULL);
+    if (strlenW(s) == 0) {
+      SetEnvironmentVariable (promptW, NULL);
     }
-    else SetEnvironmentVariable ("PROMPT", s);
+    else SetEnvironmentVariable (promptW, s);
   }
 }
 
@@ -1670,18 +1713,20 @@
 
 void WCMD_setshow_time (void) {
 
-  char curtime[64], buffer[64];
+  WCHAR curtime[64], buffer[64];
   DWORD count;
   SYSTEMTIME st;
+  static const WCHAR parmT[] = {'/','T','\0'};
 
-  if (strlen(param1) == 0) {
+  if (strlenW(param1) == 0) {
     GetLocalTime(&st);
     if (GetTimeFormat (LOCALE_USER_DEFAULT, 0, &st, NULL,
-  		curtime, sizeof(curtime))) {
+		curtime, sizeof(curtime)/sizeof(WCHAR))) {
       WCMD_output (WCMD_LoadMessage(WCMD_CURRENTDATE), curtime);
-      if (strstr (quals, "/T") == NULL) {
+      if (strstrW (quals, parmT) == NULL) {
         WCMD_output (WCMD_LoadMessage(WCMD_NEWTIME));
-        ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer, sizeof(buffer), &count, NULL);
+        WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer,
+                       sizeof(buffer)/sizeof(WCHAR), &count, NULL);
         if (count > 2) {
           WCMD_output (WCMD_LoadMessage(WCMD_NYI));
         }
@@ -1701,11 +1746,11 @@
  * Optional /n says where to start shifting (n=0-8)
  */
 
-void WCMD_shift (char *command) {
+void WCMD_shift (WCHAR *command) {
   int start;
 
   if (context != NULL) {
-    char *pos = strchr(command, '/');
+    WCHAR *pos = strchrW(command, '/');
     int   i;
 
     if (pos == NULL) {
@@ -1732,7 +1777,7 @@
  *
  * Set the console title
  */
-void WCMD_title (char *command) {
+void WCMD_title (WCHAR *command) {
   SetConsoleTitle(command);
 }
 
@@ -1742,10 +1787,10 @@
  * Copy a file to standard output.
  */
 
-void WCMD_type (char *command) {
+void WCMD_type (WCHAR *command) {
 
   int   argno         = 0;
-  char *argN          = command;
+  WCHAR *argN          = command;
   BOOL  writeHeaders  = FALSE;
 
   if (param1[0] == 0x00) {
@@ -1758,15 +1803,15 @@
   /* Loop through all args */
   errorlevel = 0;
   while (argN) {
-    char *thisArg = WCMD_parameter (command, argno++, &argN);
+    WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
 
     HANDLE h;
-    char buffer[512];
+    WCHAR buffer[512];
     DWORD count;
 
     if (!argN) break;
 
-    WINE_TRACE("type: Processing arg '%s'\n", thisArg);
+    WINE_TRACE("type: Processing arg '%s'\n", wine_dbgstr_w(thisArg));
     h = CreateFile (thisArg, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
 		FILE_ATTRIBUTE_NORMAL, NULL);
     if (h == INVALID_HANDLE_VALUE) {
@@ -1775,9 +1820,10 @@
       errorlevel = 1;
     } else {
       if (writeHeaders) {
-        WCMD_output("\n%s\n\n", thisArg);
+        static const WCHAR fmt[] = {'\n','%','s','\n','\n','\0'};
+        WCMD_output(fmt, thisArg);
       }
-      while (ReadFile (h, buffer, sizeof(buffer), &count, NULL)) {
+      while (WCMD_ReadFile (h, buffer, sizeof(buffer)/sizeof(WCHAR), &count, NULL)) {
         if (count == 0) break;	/* ReadFile reports success on EOF! */
         buffer[count] = 0;
         WCMD_output_asis (buffer);
@@ -1793,20 +1839,26 @@
  * Output either a file or stdin to screen in pages
  */
 
-void WCMD_more (char *command) {
+void WCMD_more (WCHAR *command) {
 
   int   argno         = 0;
-  char *argN          = command;
+  WCHAR *argN          = command;
   BOOL  useinput      = FALSE;
-  char  moreStr[100];
-  char  moreStrPage[100];
-  char  buffer[512];
+  WCHAR  moreStr[100];
+  WCHAR  moreStrPage[100];
+  WCHAR  buffer[512];
   DWORD count;
+  static const WCHAR moreStart[] = {'-','-',' ','\0'};
+  static const WCHAR moreFmt[]   = {'%','s',' ','-','-','\n','\0'};
+  static const WCHAR moreFmt2[]  = {'%','s',' ','(','%','2','.','2','d','%','%',
+                                    ')',' ','-','-','\n','\0'};
+  static const WCHAR conInW[]    = {'C','O','N','I','N','$','\0'};
 
   /* Prefix the NLS more with '-- ', then load the text */
   errorlevel = 0;
-  strcpy(moreStr, "-- ");
-  LoadString (hinst, WCMD_MORESTR, &moreStr[3], sizeof(moreStr)-3);
+  strcpyW(moreStr, moreStart);
+  LoadString (hinst, WCMD_MORESTR, &moreStr[3],
+              (sizeof(moreStr)/sizeof(WCHAR))-3);
 
   if (param1[0] == 0x00) {
 
@@ -1815,7 +1867,7 @@
        more are satistied by the next line from the input (file). To
        avoid this, ensure stdin is to the console                    */
     HANDLE hstdin  = GetStdHandle(STD_INPUT_HANDLE);
-    HANDLE hConIn = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
+    HANDLE hConIn = CreateFile(conInW, GENERIC_READ | GENERIC_WRITE,
                          FILE_SHARE_READ, NULL, OPEN_EXISTING,
                          FILE_ATTRIBUTE_NORMAL, 0);
     SetStdHandle(STD_INPUT_HANDLE, hConIn);
@@ -1823,10 +1875,10 @@
     /* Warning: No easy way of ending the stream (ctrl+z on windows) so
        once you get in this bit unless due to a pipe, its going to end badly...  */
     useinput = TRUE;
-    sprintf(moreStrPage, "%s --\n", moreStr);
+    wsprintf(moreStrPage, moreFmt, moreStr);
 
     WCMD_enter_paged_mode(moreStrPage);
-    while (ReadFile (hstdin, buffer, sizeof(buffer)-1, &count, NULL)) {
+    while (WCMD_ReadFile (hstdin, buffer, (sizeof(buffer)/sizeof(WCHAR))-1, &count, NULL)) {
       if (count == 0) break;	/* ReadFile reports success on EOF! */
       buffer[count] = 0;
       WCMD_output_asis (buffer);
@@ -1845,7 +1897,7 @@
     WCMD_enter_paged_mode(moreStrPage);
 
     while (argN) {
-      char *thisArg = WCMD_parameter (command, argno++, &argN);
+      WCHAR *thisArg = WCMD_parameter (command, argno++, &argN);
       HANDLE h;
 
       if (!argN) break;
@@ -1853,15 +1905,16 @@
       if (needsPause) {
 
         /* Wait */
-        sprintf(moreStrPage, "%s (100%%) --\n", moreStr);
+        wsprintf(moreStrPage, moreFmt2, moreStr, 100);
         WCMD_leave_paged_mode();
         WCMD_output_asis(moreStrPage);
-        ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer, sizeof(buffer), &count, NULL);
+        WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), buffer,
+                       sizeof(buffer)/sizeof(WCHAR), &count, NULL);
         WCMD_enter_paged_mode(moreStrPage);
       }
 
 
-      WINE_TRACE("more: Processing arg '%s'\n", thisArg);
+      WINE_TRACE("more: Processing arg '%s'\n", wine_dbgstr_w(thisArg));
       h = CreateFile (thisArg, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
 		FILE_ATTRIBUTE_NORMAL, NULL);
       if (h == INVALID_HANDLE_VALUE) {
@@ -1878,13 +1931,13 @@
         fileLen = (((ULONG64)fileInfo.nFileSizeHigh) << 32) + fileInfo.nFileSizeLow;
 
         needsPause = TRUE;
-        while (ReadFile (h, buffer, sizeof(buffer), &count, NULL)) {
+        while (WCMD_ReadFile (h, buffer, (sizeof(buffer)/sizeof(WCHAR))-1, &count, NULL)) {
           if (count == 0) break;	/* ReadFile reports success on EOF! */
           buffer[count] = 0;
           curPos += count;
 
           /* Update % count (would be used in WCMD_output_asis as prompt) */
-          sprintf(moreStrPage, "%s (%2.2d%%) --\n", moreStr, (int) min(99, (curPos * 100)/fileLen));
+          wsprintf(moreStrPage, moreFmt2, moreStr, (int) min(99, (curPos * 100)/fileLen));
 
           WCMD_output_asis (buffer);
         }
@@ -1904,21 +1957,21 @@
  * it...
  */
 
-void WCMD_verify (char *command) {
+void WCMD_verify (WCHAR *command) {
 
   int count;
 
-  count = strlen(command);
+  count = strlenW(command);
   if (count == 0) {
-    if (verify_mode) WCMD_output (WCMD_LoadMessage(WCMD_VERIFYPROMPT), "ON");
-    else WCMD_output (WCMD_LoadMessage(WCMD_VERIFYPROMPT), "OFF");
+    if (verify_mode) WCMD_output (WCMD_LoadMessage(WCMD_VERIFYPROMPT), onW);
+    else WCMD_output (WCMD_LoadMessage(WCMD_VERIFYPROMPT), offW);
     return;
   }
-  if (lstrcmpi(command, "ON") == 0) {
+  if (lstrcmpiW(command, onW) == 0) {
     verify_mode = 1;
     return;
   }
-  else if (lstrcmpi(command, "OFF") == 0) {
+  else if (lstrcmpiW(command, offW) == 0) {
     verify_mode = 0;
     return;
   }
@@ -1943,28 +1996,30 @@
  * Display volume info and/or set volume label. Returns 0 if error.
  */
 
-int WCMD_volume (int mode, char *path) {
+int WCMD_volume (int mode, WCHAR *path) {
 
   DWORD count, serial;
-  char string[MAX_PATH], label[MAX_PATH], curdir[MAX_PATH];
+  WCHAR string[MAX_PATH], label[MAX_PATH], curdir[MAX_PATH];
   BOOL status;
 
-  if (lstrlen(path) == 0) {
-    status = GetCurrentDirectory (sizeof(curdir), curdir);
+  if (strlenW(path) == 0) {
+    status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir);
     if (!status) {
       WCMD_print_error ();
       return 0;
     }
-    status = GetVolumeInformation (NULL, label, sizeof(label), &serial, NULL,
-    	NULL, NULL, 0);
+    status = GetVolumeInformation (NULL, label, sizeof(label)/sizeof(WCHAR),
+                                   &serial, NULL, NULL, NULL, 0);
   }
   else {
-    if ((path[1] != ':') || (lstrlen(path) != 2)) {
+    static const WCHAR fmt[] = {'%','s','\\','\0'};
+    if ((path[1] != ':') || (strlenW(path) != 2)) {
       WCMD_output (WCMD_LoadMessage(WCMD_SYNTAXERR));
       return 0;
     }
-    wsprintf (curdir, "%s\\", path);
-    status = GetVolumeInformation (curdir, label, sizeof(label), &serial, NULL,
+    wsprintf (curdir, fmt, path);
+    status = GetVolumeInformation (curdir, label, sizeof(label)/sizeof(WCHAR),
+                                   &serial, NULL,
     	NULL, NULL, 0);
   }
   if (!status) {
@@ -1975,12 +2030,13 @@
     	curdir[0], label, HIWORD(serial), LOWORD(serial));
   if (mode) {
     WCMD_output (WCMD_LoadMessage(WCMD_VOLUMEPROMPT));
-    ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
+    WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
+                   sizeof(string)/sizeof(WCHAR), &count, NULL);
     if (count > 1) {
       string[count-1] = '\0';		/* ReadFile output is not null-terminated! */
       if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */
     }
-    if (lstrlen(path) != 0) {
+    if (strlenW(path) != 0) {
       if (!SetVolumeLabel (curdir, string)) WCMD_print_error ();
     }
     else {
@@ -1999,9 +2055,10 @@
 
 void WCMD_exit (void) {
 
-    int rc = atoi(param1); /* Note: atoi of empty parameter is 0 */
+    static const WCHAR parmB[] = {'/','B','\0'};
+    int rc = atoiW(param1); /* Note: atoi of empty parameter is 0 */
 
-    if (context && lstrcmpi(quals, "/B") == 0) {
+    if (context && lstrcmpiW(quals, parmB) == 0) {
         errorlevel = rc;
         context -> skip_rest = TRUE;
     } else {
@@ -2020,38 +2077,41 @@
  *                   set to TRUE
  *
  */
-BOOL WCMD_ask_confirm (char *message, BOOL showSureText, BOOL *optionAll) {
+BOOL WCMD_ask_confirm (WCHAR *message, BOOL showSureText, BOOL *optionAll) {
 
-    char  msgbuffer[MAXSTRING];
-    char  Ybuffer[MAXSTRING];
-    char  Nbuffer[MAXSTRING];
-    char  Abuffer[MAXSTRING];
-    char  answer[MAX_PATH] = "";
+    WCHAR  msgbuffer[MAXSTRING];
+    WCHAR  Ybuffer[MAXSTRING];
+    WCHAR  Nbuffer[MAXSTRING];
+    WCHAR  Abuffer[MAXSTRING];
+    WCHAR  answer[MAX_PATH] = {'\0'};
     DWORD count = 0;
 
     /* Load the translated 'Are you sure', plus valid answers */
-    LoadString (hinst, WCMD_CONFIRM, msgbuffer, sizeof(msgbuffer));
-    LoadString (hinst, WCMD_YES, Ybuffer, sizeof(Ybuffer));
-    LoadString (hinst, WCMD_NO,  Nbuffer, sizeof(Nbuffer));
-    LoadString (hinst, WCMD_ALL, Abuffer, sizeof(Abuffer));
+    LoadString (hinst, WCMD_CONFIRM, msgbuffer, sizeof(msgbuffer)/sizeof(WCHAR));
+    LoadString (hinst, WCMD_YES, Ybuffer, sizeof(Ybuffer)/sizeof(WCHAR));
+    LoadString (hinst, WCMD_NO,  Nbuffer, sizeof(Nbuffer)/sizeof(WCHAR));
+    LoadString (hinst, WCMD_ALL, Abuffer, sizeof(Abuffer)/sizeof(WCHAR));
 
     /* Loop waiting on a Y or N */
     while (answer[0] != Ybuffer[0] && answer[0] != Nbuffer[0]) {
+      static const WCHAR startBkt[] = {' ','(','\0'};
+      static const WCHAR endBkt[]   = {')','?','\0'};
+
       WCMD_output_asis (message);
       if (showSureText) {
         WCMD_output_asis (msgbuffer);
       }
-      WCMD_output_asis (" (");
+      WCMD_output_asis (startBkt);
       WCMD_output_asis (Ybuffer);
-      WCMD_output_asis ("/");
+      WCMD_output_asis (fslashW);
       WCMD_output_asis (Nbuffer);
       if (optionAll) {
-          WCMD_output_asis ("/");
+          WCMD_output_asis (fslashW);
           WCMD_output_asis (Abuffer);
       }
-      WCMD_output_asis (")?");
-      ReadFile (GetStdHandle(STD_INPUT_HANDLE), answer, sizeof(answer),
-                &count, NULL);
+      WCMD_output_asis (endBkt);
+      WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), answer,
+                     sizeof(answer)/sizeof(WCHAR), &count, NULL);
       answer[0] = toupper(answer[0]);
     }
 
@@ -2066,24 +2126,25 @@
  *	Lists or sets file associations  (assoc = TRUE)
  *      Lists or sets file types         (assoc = FALSE)
  */
-void WCMD_assoc (char *command, BOOL assoc) {
+void WCMD_assoc (WCHAR *command, BOOL assoc) {
 
     HKEY    key;
     DWORD   accessOptions = KEY_READ;
-    char   *newValue;
+    WCHAR   *newValue;
     LONG    rc = ERROR_SUCCESS;
-    char    keyValue[MAXSTRING];
+    WCHAR    keyValue[MAXSTRING];
     DWORD   valueLen = MAXSTRING;
     HKEY    readKey;
-
+    static const WCHAR shOpCmdW[] = {'\\','S','h','e','l','l','\\',
+                                     'O','p','e','n','\\','C','o','m','m','a','n','d','\0'};
 
     /* See if parameter includes '=' */
     errorlevel = 0;
-    newValue = strchr(command, '=');
+    newValue = strchrW(command, '=');
     if (newValue) accessOptions |= KEY_WRITE;
 
     /* Open a key to HKEY_CLASSES_ROOT for enumerating */
-    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, "", 0,
+    if (RegOpenKeyEx(HKEY_CLASSES_ROOT, nullW, 0,
                      accessOptions, &key) != ERROR_SUCCESS) {
       WINE_FIXME("Unexpected failure opening HKCR key: %d\n", GetLastError());
       return;
@@ -2095,7 +2156,7 @@
 
       /* Enumerate all the keys */
       while (rc != ERROR_NO_MORE_ITEMS) {
-        char  keyName[MAXSTRING];
+        WCHAR  keyName[MAXSTRING];
         DWORD nameLen;
 
         /* Find the next value */
@@ -2111,18 +2172,18 @@
           if ((keyName[0] == '.' && assoc) ||
               (!(keyName[0] == '.') && (!assoc)))
           {
-            char subkey[MAXSTRING];
-            strcpy(subkey, keyName);
-            if (!assoc) strcat(subkey, "\\Shell\\Open\\Command");
+            WCHAR subkey[MAXSTRING];
+            strcpyW(subkey, keyName);
+            if (!assoc) strcatW(subkey, shOpCmdW);
 
             if (RegOpenKeyEx(key, subkey, 0,
                              accessOptions, &readKey) == ERROR_SUCCESS) {
 
-              valueLen = sizeof(keyValue);
+              valueLen = sizeof(keyValue)/sizeof(WCHAR);
               rc = RegQueryValueEx(readKey, NULL, NULL, NULL,
                                    (LPBYTE)keyValue, &valueLen);
               WCMD_output_asis(keyName);
-              WCMD_output_asis("=");
+              WCMD_output_asis(equalW);
               /* If no default value found, leave line empty after '=' */
               if (rc == ERROR_SUCCESS) {
                 WCMD_output_asis(keyValue);
@@ -2138,17 +2199,17 @@
 
       /* Parameter supplied - if no '=' on command line, its a query */
       if (newValue == NULL) {
-        char *space;
-        char subkey[MAXSTRING];
+        WCHAR *space;
+        WCHAR subkey[MAXSTRING];
 
         /* Query terminates the parameter at the first space */
-        strcpy(keyValue, command);
-        space = strchr(keyValue, ' ');
+        strcpyW(keyValue, command);
+        space = strchrW(keyValue, ' ');
         if (space) *space=0x00;
 
         /* Set up key name */
-        strcpy(subkey, keyValue);
-        if (!assoc) strcat(subkey, "\\Shell\\Open\\Command");
+        strcpyW(subkey, keyValue);
+        if (!assoc) strcatW(subkey, shOpCmdW);
 
         if (RegOpenKeyEx(key, subkey, 0,
                          accessOptions, &readKey) == ERROR_SUCCESS) {
@@ -2156,23 +2217,23 @@
           rc = RegQueryValueEx(readKey, NULL, NULL, NULL,
                                (LPBYTE)keyValue, &valueLen);
           WCMD_output_asis(command);
-          WCMD_output_asis("=");
+          WCMD_output_asis(equalW);
           /* If no default value found, leave line empty after '=' */
           if (rc == ERROR_SUCCESS) WCMD_output_asis(keyValue);
           WCMD_output_asis(newline);
           RegCloseKey(readKey);
 
         } else {
-          char  msgbuffer[MAXSTRING];
-          char  outbuffer[MAXSTRING];
+          WCHAR  msgbuffer[MAXSTRING];
+          WCHAR  outbuffer[MAXSTRING];
 
           /* Load the translated 'File association not found' */
           if (assoc) {
-            LoadString (hinst, WCMD_NOASSOC, msgbuffer, sizeof(msgbuffer));
+            LoadString (hinst, WCMD_NOASSOC, msgbuffer, sizeof(msgbuffer)/sizeof(WCHAR));
           } else {
-            LoadString (hinst, WCMD_NOFTYPE, msgbuffer, sizeof(msgbuffer));
+            LoadString (hinst, WCMD_NOFTYPE, msgbuffer, sizeof(msgbuffer)/sizeof(WCHAR));
           }
-          sprintf(outbuffer, msgbuffer, keyValue);
+          wsprintf(outbuffer, msgbuffer, keyValue);
           WCMD_output_asis(outbuffer);
           errorlevel = 2;
         }
@@ -2180,38 +2241,40 @@
       /* Not a query - its a set or clear of a value */
       } else {
 
-        char subkey[MAXSTRING];
+        WCHAR subkey[MAXSTRING];
 
         /* Get pointer to new value */
         *newValue = 0x00;
         newValue++;
 
         /* Set up key name */
-        strcpy(subkey, command);
-        if (!assoc) strcat(subkey, "\\Shell\\Open\\Command");
+        strcpyW(subkey, command);
+        if (!assoc) strcatW(subkey, shOpCmdW);
 
         /* If nothing after '=' then clear value - only valid for ASSOC */
         if (*newValue == 0x00) {
 
           if (assoc) rc = RegDeleteKey(key, command);
           if (assoc && rc == ERROR_SUCCESS) {
-            WINE_TRACE("HKCR Key '%s' deleted\n", command);
+            WINE_TRACE("HKCR Key '%s' deleted\n", wine_dbgstr_w(command));
 
           } else if (assoc && rc != ERROR_FILE_NOT_FOUND) {
             WCMD_print_error();
             errorlevel = 2;
 
           } else {
-            char  msgbuffer[MAXSTRING];
-            char  outbuffer[MAXSTRING];
+            WCHAR  msgbuffer[MAXSTRING];
+            WCHAR  outbuffer[MAXSTRING];
 
             /* Load the translated 'File association not found' */
             if (assoc) {
-              LoadString (hinst, WCMD_NOASSOC, msgbuffer, sizeof(msgbuffer));
+              LoadString (hinst, WCMD_NOASSOC, msgbuffer,
+                          sizeof(msgbuffer)/sizeof(WCHAR));
             } else {
-              LoadString (hinst, WCMD_NOFTYPE, msgbuffer, sizeof(msgbuffer));
+              LoadString (hinst, WCMD_NOFTYPE, msgbuffer,
+                          sizeof(msgbuffer)/sizeof(WCHAR));
             }
-            sprintf(outbuffer, msgbuffer, keyValue);
+            wsprintf(outbuffer, msgbuffer, keyValue);
             WCMD_output_asis(outbuffer);
             errorlevel = 2;
           }
@@ -2222,7 +2285,7 @@
                               accessOptions, NULL, &readKey, NULL);
           if (rc == ERROR_SUCCESS) {
             rc = RegSetValueEx(readKey, NULL, 0, REG_SZ,
-                                 (LPBYTE)newValue, strlen(newValue));
+                                 (LPBYTE)newValue, strlenW(newValue));
             RegCloseKey(readKey);
           }
 
@@ -2231,7 +2294,7 @@
             errorlevel = 2;
           } else {
             WCMD_output_asis(command);
-            WCMD_output_asis("=");
+            WCMD_output_asis(equalW);
             WCMD_output_asis(newValue);
             WCMD_output_asis(newline);
           }
@@ -2256,7 +2319,7 @@
   CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
   HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
 
-  if (param1[0] != 0x00 && strlen(param1) > 2) {
+  if (param1[0] != 0x00 && strlenW(param1) > 2) {
     WCMD_output (WCMD_LoadMessage(WCMD_ARGERR));
     return;
   }
@@ -2276,7 +2339,7 @@
       if (param1[0] == 0x00) {
         color = defaultColor;
       } else {
-        color = strtoul(param1, NULL, 16);
+        color = strtoulW(param1, NULL, 16);
       }
 
       /* Fail if fg == bg color */
diff --git a/programs/cmd/directory.c b/programs/cmd/directory.c
index 49c2c1a..e9c413a 100644
--- a/programs/cmd/directory.c
+++ b/programs/cmd/directory.c
@@ -33,13 +33,13 @@
 WINE_DEFAULT_DEBUG_CHANNEL(cmd);
 
 int WCMD_dir_sort (const void *a, const void *b);
-char * WCMD_filesize64 (ULONGLONG free);
-char * WCMD_strrev (char *buff);
-static void WCMD_getfileowner(char *filename, char *owner, int ownerlen);
-static void WCMD_dir_trailer(char drive);
+WCHAR * WCMD_filesize64 (ULONGLONG free);
+WCHAR * WCMD_strrev (WCHAR *buff);
+static void WCMD_getfileowner(WCHAR *filename, WCHAR *owner, int ownerlen);
+static void WCMD_dir_trailer(WCHAR drive);
 
 extern int echo_mode;
-extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
+extern WCHAR quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
 extern DWORD errorlevel;
 
 typedef enum _DISPLAYTIME
@@ -67,6 +67,12 @@
 static BOOL separator;
 static ULONG showattrs, attrsbits;
 
+static const WCHAR dotW[]    = {'.','\0'};
+static const WCHAR dotdotW[] = {'.','.','\0'};
+static const WCHAR starW[]   = {'*','\0'};
+static const WCHAR slashW[]  = {'\\','\0'};
+static const WCHAR emptyW[]  = {'\0'};
+
 /*****************************************************************************
  * WCMD_directory
  *
@@ -74,34 +80,35 @@
  *
  */
 
-void WCMD_directory (char *cmd) {
+void WCMD_directory (WCHAR *cmd) {
 
-  char path[MAX_PATH], cwd[MAX_PATH];
+  WCHAR path[MAX_PATH], cwd[MAX_PATH];
   int status, paged_mode;
   CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
-  char *p;
-  char string[MAXSTRING];
+  WCHAR *p;
+  WCHAR string[MAXSTRING];
   int   argno         = 0;
   int   argsProcessed = 0;
-  char *argN          = cmd;
-  char  lastDrive;
+  WCHAR *argN          = cmd;
+  WCHAR  lastDrive;
   BOOL  trailerReqd = FALSE;
   DIRECTORY_STACK *fullParms = NULL;
   DIRECTORY_STACK *prevEntry = NULL;
   DIRECTORY_STACK *thisEntry = NULL;
-  char drive[10];
-  char dir[MAX_PATH];
-  char fname[MAX_PATH];
-  char ext[MAX_PATH];
+  WCHAR drive[10];
+  WCHAR dir[MAX_PATH];
+  WCHAR fname[MAX_PATH];
+  WCHAR ext[MAX_PATH];
+  static const WCHAR dircmdW[] = {'D','I','R','C','M','D','\0'};
 
   errorlevel = 0;
 
   /* Prefill Quals with (uppercased) DIRCMD env var */
-  if (GetEnvironmentVariable ("DIRCMD", string, sizeof(string))) {
+  if (GetEnvironmentVariable (dircmdW, string, sizeof(string)/sizeof(WCHAR))) {
     p = string;
     while ( (*p = toupper(*p)) ) ++p;
-    strcat(string,quals);
-    strcpy(quals, string);
+    strcatW(string,quals);
+    strcpyW(quals, string);
   }
 
   byte_total = 0;
@@ -138,7 +145,7 @@
       p++;
     }
 
-    WINE_TRACE("Processing arg '%c' (in %s)\n", *p, quals);
+    WINE_TRACE("Processing arg '%c' (in %s)\n", *p, wine_dbgstr_w(quals));
     switch (*p) {
     case 'P': if (negate) paged_mode = !paged_mode;
               else paged_mode = TRUE;
@@ -188,7 +195,7 @@
     case 'O': p = p + 1;
               if (*p==':') p++;  /* Skip optional : */
               while (*p && *p != '/') {
-                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, quals);
+                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, wine_dbgstr_w(quals));
                 switch (*p) {
                 case 'N': dirOrder = Name;       break;
                 case 'E': dirOrder = Extension;  break;
@@ -222,7 +229,7 @@
                   p++;
                 }
 
-                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, quals);
+                WINE_TRACE("Processing subparm '%c' (in %s)\n", *p, wine_dbgstr_w(quals));
                 switch (*p) {
                 case 'D': mask = FILE_ATTRIBUTE_DIRECTORY; break;
                 case 'H': mask = FILE_ATTRIBUTE_HIDDEN;    break;
@@ -276,62 +283,64 @@
   argno         = 0;
   argsProcessed = 0;
   argN          = cmd;
-  GetCurrentDirectory (1024, cwd);
-  strcat(cwd, "\\");
+  GetCurrentDirectory (MAX_PATH, cwd);
+  strcatW(cwd, slashW);
 
   /* Loop through all args, calculating full effective directory */
   fullParms = NULL;
   prevEntry = NULL;
   while (argN) {
-    char fullname[MAXSTRING];
-    char *thisArg = WCMD_parameter (cmd, argno++, &argN);
+    WCHAR fullname[MAXSTRING];
+    WCHAR *thisArg = WCMD_parameter (cmd, argno++, &argN);
     if (argN && argN[0] != '/') {
 
-      WINE_TRACE("Found parm '%s'\n", thisArg);
+      WINE_TRACE("Found parm '%s'\n", wine_dbgstr_w(thisArg));
       if (thisArg[1] == ':' && thisArg[2] == '\\') {
-        strcpy(fullname, thisArg);
+        strcpyW(fullname, thisArg);
       } else if (thisArg[1] == ':' && thisArg[2] != '\\') {
-        char envvar[4];
-        sprintf(envvar, "=%c:", thisArg[0]);
+        WCHAR envvar[4];
+        static const WCHAR envFmt[] = {'=','%','c',':','\0'};
+        wsprintf(envvar, envFmt, thisArg[0]);
         if (!GetEnvironmentVariable(envvar, fullname, MAX_PATH)) {
-          sprintf(fullname, "%c:", thisArg[0]);
+          static const WCHAR noEnvFmt[] = {'%','c',':','\0'};
+          wsprintf(fullname, noEnvFmt, thisArg[0]);
         }
-        strcat(fullname, "\\");
-        strcat(fullname, &thisArg[2]);
+        strcatW(fullname, slashW);
+        strcatW(fullname, &thisArg[2]);
       } else if (thisArg[0] == '\\') {
-        strncpy(fullname, cwd, 2);
-        fullname[2] = 0x00;
-        strcat((fullname+2), thisArg);
+        memcpy(fullname, cwd, 2 * sizeof(WCHAR));
+        strcpyW(fullname+2, thisArg);
       } else {
-        strcpy(fullname, cwd);
-        strcat(fullname, thisArg);
+        strcpyW(fullname, cwd);
+        strcatW(fullname, thisArg);
       }
-      WINE_TRACE("Using location '%s'\n", fullname);
+      WINE_TRACE("Using location '%s'\n", wine_dbgstr_w(fullname));
 
-      status = GetFullPathName (fullname, sizeof(path), path, NULL);
+      status = GetFullPathName (fullname, sizeof(path)/sizeof(WCHAR), path, NULL);
 
       /*
        *  If the path supplied does not include a wildcard, and the endpoint of the
        *  path references a directory, we need to list the *contents* of that
        *  directory not the directory file itself.
        */
-      if ((strchr(path, '*') == NULL) && (strchr(path, '%') == NULL)) {
+      if ((strchrW(path, '*') == NULL) && (strchrW(path, '%') == NULL)) {
         status = GetFileAttributes (path);
         if ((status != INVALID_FILE_ATTRIBUTES) && (status & FILE_ATTRIBUTE_DIRECTORY)) {
-          if (path[strlen(path)-1] == '\\') {
-            strcat (path, "*");
+          if (path[strlenW(path)-1] == '\\') {
+            strcatW (path, starW);
           }
           else {
-            strcat (path, "\\*");
+            const WCHAR slashStarW[]  = {'\\','*','\0'};
+            strcatW (path, slashStarW);
           }
         }
       } else {
         /* Special case wildcard search with no extension (ie parameters ending in '.') as
            GetFullPathName strips off the additional '.'                                  */
-        if (fullname[strlen(fullname)-1] == '.') strcat(path, ".");
+        if (fullname[strlenW(fullname)-1] == '.') strcatW(path, dotW);
       }
 
-      WINE_TRACE("Using path '%s'\n", path);
+      WINE_TRACE("Using path '%s'\n", wine_dbgstr_w(path));
       thisEntry = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK));
       if (fullParms == NULL) fullParms = thisEntry;
       if (prevEntry != NULL) prevEntry->next = thisEntry;
@@ -341,15 +350,18 @@
       /* Split into components */
       WCMD_splitpath(path, drive, dir, fname, ext);
       WINE_TRACE("Path Parts: drive: '%s' dir: '%s' name: '%s' ext:'%s'\n",
-                 drive, dir, fname, ext);
+                 wine_dbgstr_w(drive), wine_dbgstr_w(dir),
+                 wine_dbgstr_w(fname), wine_dbgstr_w(ext));
 
-      thisEntry->dirName = HeapAlloc(GetProcessHeap(),0,strlen(drive)+strlen(dir)+1);
-      strcpy(thisEntry->dirName, drive);
-      strcat(thisEntry->dirName, dir);
+      thisEntry->dirName = HeapAlloc(GetProcessHeap(),0,
+                                     sizeof(WCHAR) * (strlenW(drive)+strlenW(dir)+1));
+      strcpyW(thisEntry->dirName, drive);
+      strcatW(thisEntry->dirName, dir);
 
-      thisEntry->fileName = HeapAlloc(GetProcessHeap(),0,strlen(fname)+strlen(ext)+1);
-      strcpy(thisEntry->fileName, fname);
-      strcat(thisEntry->fileName, ext);
+      thisEntry->fileName = HeapAlloc(GetProcessHeap(),0,
+                                     sizeof(WCHAR) * (strlenW(fname)+strlenW(ext)+1));
+      strcpyW(thisEntry->fileName, fname);
+      strcatW(thisEntry->fileName, ext);
 
     }
   }
@@ -359,10 +371,10 @@
     WINE_TRACE("Inserting default '*'\n");
     fullParms = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0, sizeof(DIRECTORY_STACK));
     fullParms->next = NULL;
-    fullParms->dirName = HeapAlloc(GetProcessHeap(),0,(strlen(cwd)+1));
-    strcpy(fullParms->dirName, cwd);
-    fullParms->fileName = HeapAlloc(GetProcessHeap(),0,2);
-    strcpy(fullParms->fileName, "*");
+    fullParms->dirName = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR) * (strlenW(cwd)+1));
+    strcpyW(fullParms->dirName, cwd);
+    fullParms->fileName = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR) * 2);
+    strcpyW(fullParms->fileName, starW);
   }
 
   lastDrive = '?';
@@ -385,10 +397,10 @@
       lastDrive = toupper(thisEntry->dirName[0]);
 
       if (!bare) {
-         char drive[3];
+         WCHAR drive[3];
 
          WINE_TRACE("Writing volume for '%c:'\n", thisEntry->dirName[0]);
-         strncpy(drive, thisEntry->dirName, 2);
+         memcpy(drive, thisEntry->dirName, 2 * sizeof(WCHAR));
          drive[2] = 0x00;
          status = WCMD_volume (0, drive);
          trailerReqd = TRUE;
@@ -398,7 +410,8 @@
          }
       }
     } else {
-      if (!bare) WCMD_output ("\n\n");
+      static const WCHAR newLine2[] = {'\n','\n','\0'};
+      if (!bare) WCMD_output (newLine2);
     }
 
     /* Clear any errors from previous invocations, and process it */
@@ -436,8 +449,8 @@
 
 static DIRECTORY_STACK *WCMD_list_directory (DIRECTORY_STACK *inputparms, int level) {
 
-  char string[1024], datestring[32], timestring[32];
-  char real_path[MAX_PATH];
+  WCHAR string[1024], datestring[32], timestring[32];
+  WCHAR real_path[MAX_PATH];
   WIN32_FIND_DATA *fd;
   FILETIME ft;
   SYSTEMTIME st;
@@ -450,6 +463,14 @@
   int concurrentDirs = 0;
   BOOL done_header = FALSE;
 
+  static const WCHAR fmtDir[]  = {'%','1','0','s',' ',' ','%','8','s',' ',' ',
+                                  '<','D','I','R','>',' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'};
+  static const WCHAR fmtFile[] = {'%','1','0','s',' ',' ','%','8','s',' ',' ',
+                                  ' ',' ','%','1','0','s',' ',' ','\0'};
+  static const WCHAR fmt2[]  = {'%','-','1','3','s','\0'};
+  static const WCHAR fmt3[]  = {'%','-','2','3','s','\0'};
+  static const WCHAR fmt4[]  = {'%','s','\0'};
+  static const WCHAR fmt5[]  = {'%','s','%','s','\0'};
 
   dir_count = 0;
   file_count = 0;
@@ -463,15 +484,15 @@
      mirrors what windows does                                            */
   parms = inputparms;
   fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATA));
-  while (parms && strcmp(inputparms->dirName, parms->dirName) == 0) {
+  while (parms && strcmpW(inputparms->dirName, parms->dirName) == 0) {
     concurrentDirs++;
 
     /* Work out the full path + filename */
-    strcpy(real_path, parms->dirName);
-    strcat(real_path, parms->fileName);
+    strcpyW(real_path, parms->dirName);
+    strcatW(real_path, parms->fileName);
 
     /* Load all files into an in memory structure */
-    WINE_TRACE("Looking for matches to '%s'\n", real_path);
+    WINE_TRACE("Looking for matches to '%s'\n", wine_dbgstr_w(real_path));
     hff = FindFirstFile (real_path, (fd+entry_count));
     if (hff != INVALID_HANDLE_VALUE) {
       do {
@@ -482,7 +503,7 @@
 
         /* Keep running track of longest filename for wide output */
         if (wide || orderByCol) {
-           int tmpLen = strlen((fd+(entry_count-1))->cFileName) + 3;
+           int tmpLen = strlenW((fd+(entry_count-1))->cFileName) + 3;
            if ((fd+(entry_count-1))->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) tmpLen = tmpLen + 2;
            if (tmpLen > widest) widest = tmpLen;
         }
@@ -499,14 +520,16 @@
     }
 
     /* Work out the actual current directory name without a trailing \ */
-    strcpy(real_path, parms->dirName);
-    real_path[strlen(parms->dirName)-1] = 0x00;
+    strcpyW(real_path, parms->dirName);
+    real_path[strlenW(parms->dirName)-1] = 0x00;
 
     /* Output the results */
     if (!bare) {
        if (level != 0 && (entry_count > 0)) WCMD_output (newline);
        if (!recurse || ((entry_count > 0) && done_header==FALSE)) {
-           WCMD_output ("Directory of %s\n\n", real_path);
+           static const WCHAR headerW[] = {'D','i','r','e','c','t','o','r','y',' ','o','f',
+                                           ' ','%','s','\n','\n','\0'};
+           WCMD_output (headerW, real_path);
            done_header = TRUE;
        }
     }
@@ -536,7 +559,7 @@
     for (rows=0; rows<numRows; rows++) {
      BOOL addNewLine = TRUE;
      for (cols=0; cols<numCols; cols++) {
-      char username[24];
+      WCHAR username[24];
 
       /* Work out the index of the entry being pointed to */
       if (orderByCol) {
@@ -549,15 +572,15 @@
 
       /* /L convers all names to lower case */
       if (lower) {
-          char *p = (fd+i)->cFileName;
+          WCHAR *p = (fd+i)->cFileName;
           while ( (*p = tolower(*p)) ) ++p;
       }
 
       /* /Q gets file ownership information */
       if (usernames) {
-          lstrcpy (string, inputparms->dirName);
-          lstrcat (string, (fd+i)->cFileName);
-          WCMD_getfileowner(string, username, sizeof(username));
+          strcpyW (string, inputparms->dirName);
+          strcatW (string, (fd+i)->cFileName);
+          WCMD_getfileowner(string, username, sizeof(username)/sizeof(WCHAR));
       }
 
       if (dirTime == Written) {
@@ -569,20 +592,22 @@
       }
       FileTimeToSystemTime (&ft, &st);
       GetDateFormat (0, DATE_SHORTDATE, &st, NULL, datestring,
-			sizeof(datestring));
+			sizeof(datestring)/sizeof(WCHAR));
       GetTimeFormat (0, TIME_NOSECONDS, &st,
-			NULL, timestring, sizeof(timestring));
+			NULL, timestring, sizeof(timestring)/sizeof(WCHAR));
 
       if (wide) {
 
         tmp_width = cur_width;
         if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
-            WCMD_output ("[%s]", (fd+i)->cFileName);
+            static const WCHAR fmt[] = {'[','%','s',']','\0'};
+            WCMD_output (fmt, (fd+i)->cFileName);
             dir_count++;
-            tmp_width = tmp_width + strlen((fd+i)->cFileName) + 2;
+            tmp_width = tmp_width + strlenW((fd+i)->cFileName) + 2;
         } else {
-            WCMD_output ("%s", (fd+i)->cFileName);
-            tmp_width = tmp_width + strlen((fd+i)->cFileName) ;
+            static const WCHAR fmt[] = {'%','s','\0'};
+            WCMD_output (fmt, (fd+i)->cFileName);
+            tmp_width = tmp_width + strlenW((fd+i)->cFileName) ;
             file_count++;
             file_size.u.LowPart = (fd+i)->nFileSizeLow;
             file_size.u.HighPart = (fd+i)->nFileSizeHigh;
@@ -593,21 +618,22 @@
         if ((cur_width + widest) > max_width) {
             cur_width = 0;
         } else {
-            WCMD_output ("%*.s", (tmp_width - cur_width) ,"");
+            static const WCHAR fmt[]  = {'%','*','.','s','\0'};
+            WCMD_output (fmt, (tmp_width - cur_width), emptyW);
         }
 
       } else if ((fd+i)->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
         dir_count++;
 
         if (!bare) {
-           WCMD_output ("%10s  %8s  <DIR>         ", datestring, timestring);
-           if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
-           if (usernames) WCMD_output ("%-23s", username);
-           WCMD_output("%s",(fd+i)->cFileName);
+           WCMD_output (fmtDir, datestring, timestring);
+           if (shortname) WCMD_output (fmt2, (fd+i)->cAlternateFileName);
+           if (usernames) WCMD_output (fmt3, username);
+           WCMD_output(fmt4,(fd+i)->cFileName);
         } else {
-           if (!((strcmp((fd+i)->cFileName, ".") == 0) ||
-                 (strcmp((fd+i)->cFileName, "..") == 0))) {
-              WCMD_output ("%s%s", recurse?inputparms->dirName:"", (fd+i)->cFileName);
+           if (!((strcmpW((fd+i)->cFileName, dotW) == 0) ||
+                 (strcmpW((fd+i)->cFileName, dotdotW) == 0))) {
+              WCMD_output (fmt5, recurse?inputparms->dirName:emptyW, (fd+i)->cFileName);
            } else {
               addNewLine = FALSE;
            }
@@ -619,13 +645,13 @@
         file_size.u.HighPart = (fd+i)->nFileSizeHigh;
         byte_count.QuadPart += file_size.QuadPart;
         if (!bare) {
-           WCMD_output ("%10s  %8s    %10s  ", datestring, timestring,
+           WCMD_output (fmtFile, datestring, timestring,
                         WCMD_filesize64(file_size.QuadPart));
-           if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
-           if (usernames) WCMD_output ("%-23s", username);
-           WCMD_output("%s",(fd+i)->cFileName);
+           if (shortname) WCMD_output (fmt2, (fd+i)->cAlternateFileName);
+           if (usernames) WCMD_output (fmt3, username);
+           WCMD_output(fmt4,(fd+i)->cFileName);
         } else {
-           WCMD_output ("%s%s", recurse?inputparms->dirName:"", (fd+i)->cFileName);
+           WCMD_output (fmt5, recurse?inputparms->dirName:emptyW, (fd+i)->cFileName);
         }
       }
      }
@@ -635,10 +661,14 @@
 
     if (!bare) {
        if (file_count == 1) {
-         WCMD_output ("       1 file %25s bytes\n", WCMD_filesize64 (byte_count.QuadPart));
+         static const WCHAR fmt[] = {' ',' ',' ',' ',' ',' ',' ','1',' ','f','i','l','e',' ',
+                                     '%','2','5','s',' ','b','y','t','e','s','\n','\0'};
+         WCMD_output (fmt, WCMD_filesize64 (byte_count.QuadPart));
        }
        else {
-         WCMD_output ("%8d files %24s bytes\n", file_count, WCMD_filesize64 (byte_count.QuadPart));
+         static const WCHAR fmt[] = {'%','8','d',' ','f','i','l','e','s',' ','%','2','4','s',
+                                     ' ','b','y','t','e','s','\n','\0'};
+         WCMD_output (fmt, file_count, WCMD_filesize64 (byte_count.QuadPart));
        }
     }
     byte_total = byte_total + byte_count.QuadPart;
@@ -646,8 +676,15 @@
     dir_total = dir_total + dir_count;
 
     if (!bare && !recurse) {
-       if (dir_count == 1) WCMD_output ("%8d directory         ", 1);
-       else WCMD_output ("%8d directories", dir_count);
+       if (dir_count == 1) {
+           static const WCHAR fmt[] = {'%','8','d',' ','d','i','r','e','c','t','o','r','y',
+                                       ' ',' ',' ',' ',' ',' ',' ',' ',' ','\0'};
+           WCMD_output (fmt, 1);
+       } else {
+           static const WCHAR fmt[] = {'%','8','d',' ','d','i','r','e','c','t','o','r','i',
+                                       'e','s','\0'};
+           WCMD_output (fmt, dir_count);
+       }
     }
   }
   HeapFree(GetProcessHeap(),0,fd);
@@ -659,16 +696,16 @@
     WIN32_FIND_DATA finddata;
 
     /* Build path to search */
-    strcpy(string, inputparms->dirName);
-    strcat(string, "*");
+    strcpyW(string, inputparms->dirName);
+    strcatW(string, starW);
 
-    WINE_TRACE("Recursive, looking for '%s'\n", string);
+    WINE_TRACE("Recursive, looking for '%s'\n", wine_dbgstr_w(string));
     hff = FindFirstFile (string, &finddata);
     if (hff != INVALID_HANDLE_VALUE) {
       do {
         if ((finddata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
-            (strcmp(finddata.cFileName, "..") != 0) &&
-            (strcmp(finddata.cFileName, ".") != 0)) {
+            (strcmpW(finddata.cFileName, dotdotW) != 0) &&
+            (strcmpW(finddata.cFileName, dotW) != 0)) {
 
           DIRECTORY_STACK *thisDir;
           int              dirsToCopy = concurrentDirs;
@@ -679,10 +716,10 @@
             dirsToCopy--;
 
             /* Work out search parameter in sub dir */
-            strcpy (string, inputparms->dirName);
-            strcat (string, finddata.cFileName);
-            strcat (string, "\\");
-            WINE_TRACE("Recursive, Adding to search list '%s'\n", string);
+            strcpyW (string, inputparms->dirName);
+            strcatW (string, finddata.cFileName);
+            strcatW (string, slashW);
+            WINE_TRACE("Recursive, Adding to search list '%s'\n", wine_dbgstr_w(string));
 
             /* Allocate memory, add to list */
             thisDir = (DIRECTORY_STACK *) HeapAlloc(GetProcessHeap(),0,sizeof(DIRECTORY_STACK));
@@ -690,10 +727,12 @@
             if (lastEntry != NULL) lastEntry->next = thisDir;
             lastEntry = thisDir;
             thisDir->next = NULL;
-            thisDir->dirName = HeapAlloc(GetProcessHeap(),0,(strlen(string)+1));
-            strcpy(thisDir->dirName, string);
-            thisDir->fileName = HeapAlloc(GetProcessHeap(),0,(strlen(parms->fileName)+1));
-            strcpy(thisDir->fileName, parms->fileName);
+            thisDir->dirName = HeapAlloc(GetProcessHeap(),0,
+                                         sizeof(WCHAR) * (strlenW(string)+1));
+            strcpyW(thisDir->dirName, string);
+            thisDir->fileName = HeapAlloc(GetProcessHeap(),0,
+                                          sizeof(WCHAR) * (strlenW(parms->fileName)+1));
+            strcpyW(thisDir->fileName, parms->fileName);
             parms = parms->next;
           }
         }
@@ -727,17 +766,17 @@
 /*****************************************************************************
  * WCMD_filesize64
  *
- * Convert a 64-bit number into a character string, with commas every three digits.
+ * Convert a 64-bit number into a WCHARacter string, with commas every three digits.
  * Result is returned in a static string overwritten with each call.
  * FIXME: There must be a better algorithm!
  */
 
-char * WCMD_filesize64 (ULONGLONG n) {
+WCHAR * WCMD_filesize64 (ULONGLONG n) {
 
   ULONGLONG q;
   unsigned int r, i;
-  char *p;
-  static char buff[32];
+  WCHAR *p;
+  static WCHAR buff[32];
 
   p = buff;
   i = -3;
@@ -756,15 +795,15 @@
 /*****************************************************************************
  * WCMD_strrev
  *
- * Reverse a character string in-place (strrev() is not available under unixen :-( ).
+ * Reverse a WCHARacter string in-place (strrev() is not available under unixen :-( ).
  */
 
-char * WCMD_strrev (char *buff) {
+WCHAR * WCMD_strrev (WCHAR *buff) {
 
   int r, i;
-  char b;
+  WCHAR b;
 
-  r = lstrlen (buff);
+  r = strlenW (buff);
   for (i=0; i<r/2; i++) {
     b = buff[i];
     buff[i] = buff[r-i-1];
@@ -799,7 +838,7 @@
 
   /* Order by Name: */
   } else if (dirOrder == Name) {
-    result = lstrcmpi(filea->cFileName, fileb->cFileName);
+    result = lstrcmpiW(filea->cFileName, fileb->cFileName);
 
   /* Order by Size: */
   } else if (dirOrder == Size) {
@@ -837,16 +876,16 @@
 
   /* Order by Extension: (Takes into account which date (/T option) */
   } else if (dirOrder == Extension) {
-      char drive[10];
-      char dir[MAX_PATH];
-      char fname[MAX_PATH];
-      char extA[MAX_PATH];
-      char extB[MAX_PATH];
+      WCHAR drive[10];
+      WCHAR dir[MAX_PATH];
+      WCHAR fname[MAX_PATH];
+      WCHAR extA[MAX_PATH];
+      WCHAR extB[MAX_PATH];
 
       /* Split into components */
       WCMD_splitpath(filea->cFileName, drive, dir, fname, extA);
       WCMD_splitpath(fileb->cFileName, drive, dir, fname, extB);
-      result = lstrcmpi(extA, extB);
+      result = lstrcmpiW(extA, extB);
   }
 
   if (orderReverse) result = -result;
@@ -856,14 +895,14 @@
 /*****************************************************************************
  * WCMD_getfileowner
  *
- * Reverse a character string in-place (strrev() is not available under unixen :-( ).
+ * Reverse a WCHARacter string in-place (strrev() is not available under unixen :-( ).
  */
-void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
+void WCMD_getfileowner(WCHAR *filename, WCHAR *owner, int ownerlen) {
 
     ULONG sizeNeeded = 0;
     DWORD rc;
-    char name[MAXSTRING];
-    char domain[MAXSTRING];
+    WCHAR name[MAXSTRING];
+    WCHAR domain[MAXSTRING];
 
     /* In case of error, return empty string */
     *owner = 0x00;
@@ -899,7 +938,8 @@
 
         /* Convert to a username */
         if (LookupAccountSid(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) {
-            snprintf(owner, ownerlen, "%s%c%s", domain, '\\', name);
+            static const WCHAR fmt[]  = {'%','s','%','c','%','s','\0'};
+            snprintfW(owner, ownerlen, fmt, domain, '\\', name);
         }
         HeapFree(GetProcessHeap(),0,secBuffer);
     }
@@ -911,23 +951,30 @@
  *
  * Print out the trailer for the supplied drive letter
  */
-static void WCMD_dir_trailer(char drive) {
+static void WCMD_dir_trailer(WCHAR drive) {
     ULARGE_INTEGER avail, total, freebytes;
     DWORD status;
-    char driveName[4] = "c:\\";
+    WCHAR driveName[4] = {'c',':','\\','\0'};
 
     driveName[0] = drive;
     status = GetDiskFreeSpaceEx (driveName, &avail, &total, &freebytes);
-    WINE_TRACE("Writing trailer for '%s' gave %d(%d)\n", driveName, status, GetLastError());
+    WINE_TRACE("Writing trailer for '%s' gave %d(%d)\n", wine_dbgstr_w(driveName),
+               status, GetLastError());
 
     if (errorlevel==0 && !bare) {
       if (recurse) {
-        WCMD_output ("\n     Total files listed:\n%8d files%25s bytes\n",
-             file_total, WCMD_filesize64 (byte_total));
-        WCMD_output ("%8d directories %18s bytes free\n\n",
-             dir_total, WCMD_filesize64 (freebytes.QuadPart));
+        static const WCHAR fmt1[] = {'\n',' ',' ',' ',' ',' ','T','o','t','a','l',' ','f','i','l','e','s',
+                                     ' ','l','i','s','t','e','d',':','\n','%','8','d',' ','f','i','l','e',
+                                     's','%','2','5','s',' ','b','y','t','e','s','\n','\0'};
+        static const WCHAR fmt2[] = {'%','8','d',' ','d','i','r','e','c','t','o','r','i','e','s',' ','%',
+                                     '1','8','s',' ','b','y','t','e','s',' ','f','r','e','e','\n','\n',
+                                     '\0'};
+        WCMD_output (fmt1, file_total, WCMD_filesize64 (byte_total));
+        WCMD_output (fmt2, dir_total, WCMD_filesize64 (freebytes.QuadPart));
       } else {
-        WCMD_output (" %18s bytes free\n\n", WCMD_filesize64 (freebytes.QuadPart));
+        static const WCHAR fmt[] = {' ','%','1','8','s',' ','b','y','t','e','s',' ','f','r','e','e',
+                                    '\n','\n','\0'};
+        WCMD_output (fmt, WCMD_filesize64 (freebytes.QuadPart));
       }
     }
 }
diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h
index ab13595..9fe729d 100644
--- a/programs/cmd/wcmd.h
+++ b/programs/cmd/wcmd.h
@@ -28,71 +28,74 @@
 #include <ctype.h>
 #include <wine/unicode.h>
 
-void WCMD_assoc (char *, BOOL);
-void WCMD_batch (char *, char *, int, char *, HANDLE);
-void WCMD_call (char *command);
+void WCMD_assoc (WCHAR *, BOOL);
+void WCMD_batch (WCHAR *, WCHAR *, int, WCHAR *, HANDLE);
+void WCMD_call (WCHAR *command);
 void WCMD_change_tty (void);
 void WCMD_clear_screen (void);
 void WCMD_color (void);
 void WCMD_copy (void);
 void WCMD_create_dir (void);
-BOOL WCMD_delete (char *, BOOL);
-void WCMD_directory (char *);
-void WCMD_echo (const char *);
+BOOL WCMD_delete (WCHAR *, BOOL);
+void WCMD_directory (WCHAR *);
+void WCMD_echo (const WCHAR *);
 void WCMD_endlocal (void);
-void WCMD_enter_paged_mode(const char *);
+void WCMD_enter_paged_mode(const WCHAR *);
 void WCMD_exit (void);
-void WCMD_for (char *);
-void WCMD_give_help (char *command);
+void WCMD_for (WCHAR *);
+void WCMD_give_help (WCHAR *command);
 void WCMD_goto (void);
-void WCMD_if (char *);
+void WCMD_if (WCHAR *);
 void WCMD_leave_paged_mode(void);
-void WCMD_more (char *);
+void WCMD_more (WCHAR *);
 void WCMD_move (void);
-void WCMD_output (const char *format, ...);
-void WCMD_output_asis (const char *message);
-void WCMD_parse (char *s, char *q, char *p1, char *p2);
+void WCMD_output (const WCHAR *format, ...);
+void WCMD_output_asis (const WCHAR *message);
+void WCMD_parse (WCHAR *s, WCHAR *q, WCHAR *p1, WCHAR *p2);
 void WCMD_pause (void);
-void WCMD_pipe (char *command);
+void WCMD_pipe (WCHAR *command);
 void WCMD_popd (void);
 void WCMD_print_error (void);
-void WCMD_process_command (char *command);
-void WCMD_pushd (char *);
-int  WCMD_read_console (char *string, int str_len);
-void WCMD_remove_dir (char *command);
+void WCMD_process_command (WCHAR *command);
+void WCMD_pushd (WCHAR *);
+int  WCMD_read_console (WCHAR *string, int str_len);
+void WCMD_remove_dir (WCHAR *command);
 void WCMD_rename (void);
-void WCMD_run_program (char *command, int called);
-void WCMD_setlocal (const char *command);
+void WCMD_run_program (WCHAR *command, int called);
+void WCMD_setlocal (const WCHAR *command);
 void WCMD_setshow_attrib (void);
 void WCMD_setshow_date (void);
-void WCMD_setshow_default (char *command);
-void WCMD_setshow_env (char *command);
-void WCMD_setshow_path (char *command);
+void WCMD_setshow_default (WCHAR *command);
+void WCMD_setshow_env (WCHAR *command);
+void WCMD_setshow_path (WCHAR *command);
 void WCMD_setshow_prompt (void);
 void WCMD_setshow_time (void);
-void WCMD_shift (char *command);
+void WCMD_shift (WCHAR *command);
 void WCMD_show_prompt (void);
-void WCMD_title (char *);
-void WCMD_type (char *);
-void WCMD_verify (char *command);
+void WCMD_title (WCHAR *);
+void WCMD_type (WCHAR *);
+void WCMD_verify (WCHAR *command);
 void WCMD_version (void);
-int  WCMD_volume (int mode, char *command);
+int  WCMD_volume (int mode, WCHAR *command);
 
-char *WCMD_fgets (char *s, int n, HANDLE stream);
-char *WCMD_parameter (char *s, int n, char **where);
-char *WCMD_strtrim_leading_spaces (char *string);
-void WCMD_strtrim_trailing_spaces (char *string);
-void WCMD_opt_s_strip_quotes(char *cmd);
-void WCMD_HandleTildaModifiers(char **start, char *forVariable);
-BOOL WCMD_ask_confirm (char *message, BOOL showSureText, BOOL *optionAll);
+WCHAR *WCMD_fgets (WCHAR *s, int n, HANDLE stream);
+WCHAR *WCMD_parameter (WCHAR *s, int n, WCHAR **where);
+WCHAR *WCMD_strtrim_leading_spaces (WCHAR *string);
+void WCMD_strtrim_trailing_spaces (WCHAR *string);
+void WCMD_opt_s_strip_quotes(WCHAR *cmd);
+void WCMD_HandleTildaModifiers(WCHAR **start, WCHAR *forVariable);
+BOOL WCMD_ask_confirm (WCHAR *message, BOOL showSureText, BOOL *optionAll);
 
-void WCMD_splitpath(const CHAR* path, CHAR* drv, CHAR* dir, CHAR* name, CHAR* ext);
-char *WCMD_LoadMessage(UINT id);
+void WCMD_splitpath(const WCHAR* path, WCHAR* drv, WCHAR* dir, WCHAR* name, WCHAR* ext);
+WCHAR *WCMD_LoadMessage(UINT id);
+WCHAR *WCMD_strdupW(WCHAR *input);
+BOOL WCMD_ReadFile(const HANDLE hIn, WCHAR *intoBuf, const DWORD maxChars,
+                   LPDWORD charsRead, const LPOVERLAPPED unused);
 
 /*	Data structure to hold context when executing batch files */
 
 typedef struct {
-  char *command;	/* The command which invoked the batch file */
+  WCHAR *command;	/* The command which invoked the batch file */
   HANDLE h;             /* Handle to the open batch file */
   int shift_count[10];	/* Offset in terms of shifts for %0 - %9 */
   void *prev_context;	/* Pointer to the previous context block */
@@ -106,7 +109,7 @@
   struct env_stack *next;
   union {
     int    stackdepth;       /* Only used for pushd and popd */
-    char   cwd;              /* Only used for set/endlocal   */
+    WCHAR   cwd;              /* Only used for set/endlocal   */
   } u;
   WCHAR *strings;
 };
@@ -116,8 +119,8 @@
 typedef struct _DIRECTORY_STACK
 {
   struct _DIRECTORY_STACK *next;
-  char  *dirName;
-  char  *fileName;
+  WCHAR  *dirName;
+  WCHAR  *fileName;
 } DIRECTORY_STACK;
 
 #endif /* !RC_INVOKED */
@@ -181,9 +184,9 @@
 #define WCMD_EXIT   44
 
 /* Some standard messages */
-extern const char newline[];
-extern const char version_string[];
-extern const char anykey[];
+extern const WCHAR newline[];
+extern WCHAR anykey[];
+extern WCHAR version_string[];
 
 /* Translated messages */
 #define WCMD_CONFIRM          1001
@@ -215,6 +218,11 @@
 #define WCMD_ARGERR           1027
 #define WCMD_VOLUMEDETAIL     1028
 #define WCMD_VOLUMEPROMPT     1029
+#define WCMD_NOPATH           1030
+#define WCMD_ANYKEY           1031
+#define WCMD_CONSTITLE        1032
+#define WCMD_VERSION          1033
+
 
 /* msdn specified max for Win XP */
 #define MAXSTRING 8192
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 85fe005..ae27415 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -30,27 +30,70 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(cmd);
 
-const char * const inbuilt[] = {"ATTRIB", "CALL", "CD", "CHDIR", "CLS", "COPY", "CTTY",
-		"DATE", "DEL", "DIR", "ECHO", "ERASE", "FOR", "GOTO",
-		"HELP", "IF", "LABEL", "MD", "MKDIR", "MOVE", "PATH", "PAUSE",
-		"PROMPT", "REM", "REN", "RENAME", "RD", "RMDIR", "SET", "SHIFT",
-                "TIME", "TITLE", "TYPE", "VERIFY", "VER", "VOL",
-                "ENDLOCAL", "SETLOCAL", "PUSHD", "POPD", "ASSOC", "COLOR", "FTYPE",
-                "MORE", "EXIT" };
+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 char newline[] = "\n";
-const char version_string[] = "CMD Version " PACKAGE_VERSION "\n\n";
-const char anykey[] = "Press Return key to continue: ";
-char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
+const WCHAR newline[] = {'\n','\0'};
+static const WCHAR equalsW[] = {'=','\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 char *pagedMessage = NULL;
+static const WCHAR *pagedMessage = NULL;
+static char  *output_bufA = NULL;
+#define MAX_WRITECONSOLE_SIZE 65535
 
-static char *WCMD_expand_envvar(char *start);
+static WCHAR *WCMD_expand_envvar(WCHAR *start);
 
 /*****************************************************************************
  * Main entry point. This is a console application so we have a main() not a
@@ -61,14 +104,22 @@
 {
   LPWSTR *argvW = NULL;
   int     args;
-  WCHAR  *cmdW  = NULL;
-  char string[1024];
-  char envvar[4];
-  char* cmd=NULL;
+  WCHAR  *cmd   = NULL;
+  WCHAR string[1024];
+  WCHAR envvar[4];
   DWORD count;
   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];
+
+  /* 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));
 
   /* Get a Unicode command line */
   argvW = CommandLineToArgvW( GetCommandLineW(), &argc );
@@ -114,7 +165,8 @@
   }
 
   if (opt_q) {
-    WCMD_echo("OFF");
+    const WCHAR eoff[] = {'O','F','F','\0'};
+    WCMD_echo(eoff);
   }
 
   if (opt_c || opt_k) {
@@ -185,11 +237,11 @@
           }
       }
 
-      cmdW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
-      if (!cmdW)
+      cmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+      if (!cmd)
           exit(1);
 
-      p = cmdW;
+      p = cmd;
       argsLeft = args;
       for (arg = argvW; argsLeft>0; arg++,argsLeft--)
       {
@@ -249,19 +301,11 @@
               *p++='"';
           *p++=' ';
       }
-      if (p > cmdW)
+      if (p > cmd)
           p--;  /* remove last space */
       *p = '\0';
 
-      /* FIXME: Convert back to ansi until more is in unicode */
-      cmd = HeapAlloc(GetProcessHeap(), 0, len);
-      if (!cmd) {
-        exit(1);
-      } else {
-        WideCharToMultiByte(CP_ACP, 0, cmdW, len, cmd, len, NULL, NULL);
-      }
-      WINE_TRACE("Input (U): '%s'\n", wine_dbgstr_w(cmdW));
-      WINE_TRACE("Input (A): '%s'\n", cmd);
+      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 */
@@ -275,18 +319,17 @@
        * the currently allocated input and output handles. This allows
        * us to pipe to and read from the command interpreter.
        */
-      if (strchr(cmd,'|') != NULL)
+      if (strchrW(cmd,'|') != NULL)
           WCMD_pipe(cmd);
       else
           WCMD_process_command(cmd);
       HeapFree(GetProcessHeap(), 0, cmd);
-      HeapFree(GetProcessHeap(), 0, cmdW);
       return errorlevel;
   }
 
   SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_LINE_INPUT |
                  ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT);
-  SetConsoleTitle("Wine Command Prompt");
+  SetConsoleTitle(WCMD_LoadMessage(WCMD_CONSTITLE));
 
   /* Note: cmd.exe /c dir does not get a new color, /k dir does */
   if (opt_t) {
@@ -304,44 +347,47 @@
       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, "Software\\Microsoft\\Command Processor",
+      if (RegOpenKeyEx(HKEY_CURRENT_USER, regKeyW,
                        0, KEY_READ, &key) == ERROR_SUCCESS) {
-          char  strvalue[4];
+          WCHAR  strvalue[4];
 
           /* See if DWORD or REG_SZ */
-          if (RegQueryValueEx(key, "DefaultColor", NULL, &type,
+          if (RegQueryValueEx(key, dfltColorW, NULL, &type,
                      NULL, NULL) == ERROR_SUCCESS) {
               if (type == REG_DWORD) {
                   size = sizeof(DWORD);
-                  RegQueryValueEx(key, "DefaultColor", NULL, NULL,
+                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                   (LPBYTE)&value, &size);
               } else if (type == REG_SZ) {
-                  size = sizeof(strvalue);
-                  RegQueryValueEx(key, "DefaultColor", NULL, NULL,
+                  size = sizeof(strvalue)/sizeof(WCHAR);
+                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                   (LPBYTE)strvalue, &size);
-                  value = strtoul(strvalue, NULL, 10);
+                  value = strtoulW(strvalue, NULL, 10);
               }
           }
       }
 
-      if (value == 0 && RegOpenKeyEx(HKEY_LOCAL_MACHINE,
-                       "Software\\Microsoft\\Command Processor",
+      if (value == 0 && RegOpenKeyEx(HKEY_LOCAL_MACHINE, regKeyW,
                        0, KEY_READ, &key) == ERROR_SUCCESS) {
-          char  strvalue[4];
+          WCHAR  strvalue[4];
 
           /* See if DWORD or REG_SZ */
-          if (RegQueryValueEx(key, "DefaultColor", NULL, &type,
+          if (RegQueryValueEx(key, dfltColorW, NULL, &type,
                      NULL, NULL) == ERROR_SUCCESS) {
               if (type == REG_DWORD) {
                   size = sizeof(DWORD);
-                  RegQueryValueEx(key, "DefaultColor", NULL, NULL,
+                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                   (LPBYTE)&value, &size);
               } else if (type == REG_SZ) {
-                  size = sizeof(strvalue);
-                  RegQueryValueEx(key, "DefaultColor", NULL, NULL,
+                  size = sizeof(strvalue)/sizeof(WCHAR);
+                  RegQueryValueEx(key, dfltColorW, NULL, NULL,
                                   (LPBYTE)strvalue, &size);
-                  value = strtoul(strvalue, NULL, 10);
+                  value = strtoulW(strvalue, NULL, 10);
               }
           }
       }
@@ -358,26 +404,26 @@
   /* Save cwd into appropriate env var */
   GetCurrentDirectory(1024, string);
   if (IsCharAlpha(string[0]) && string[1] == ':') {
-    sprintf(envvar, "=%c:", string[0]);
+    static const WCHAR fmt[] = {'=','%','c',':','\0'};
+    wsprintf(envvar, fmt, string[0]);
     SetEnvironmentVariable(envvar, string);
   }
 
   if (opt_k) {
       WCMD_process_command(cmd);
       HeapFree(GetProcessHeap(), 0, cmd);
-      HeapFree(GetProcessHeap(), 0, cmdW);
   }
 
 /*
  *	If there is an AUTOEXEC.BAT file, try to execute it.
  */
 
-  GetFullPathName ("\\autoexec.bat", sizeof(string), string, NULL);
+  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 ((char *)"\\autoexec.bat", (char *)"\\autoexec.bat", 0, NULL, INVALID_HANDLE_VALUE);
+    WCMD_batch (autoexec, autoexec, 0, NULL, INVALID_HANDLE_VALUE);
 #endif
   }
 
@@ -388,12 +434,13 @@
   WCMD_version ();
   while (TRUE) {
     WCMD_show_prompt ();
-    ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
+    WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
+                   sizeof(string)/sizeof(WCHAR), &count, NULL);
     if (count > 1) {
       string[count-1] = '\0'; /* ReadFile output is not null-terminated! */
       if (string[count-2] == '\r') string[count-2] = '\0'; /* Under Windoze we get CRLF! */
-      if (lstrlen (string) != 0) {
-        if (strchr(string,'|') != NULL) {
+      if (strlenW (string) != 0) {
+        if (strchrW(string,'|') != NULL) {
           WCMD_pipe (string);
         }
         else {
@@ -411,16 +458,16 @@
  */
 
 
-void WCMD_process_command (char *command)
+void WCMD_process_command (WCHAR *command)
 {
-    char *cmd, *p, *s, *t, *redir;
+    WCHAR *cmd, *p, *s, *t, *redir;
     int status, i;
     DWORD count, creationDisposition;
     HANDLE h;
-    char *whichcmd;
+    WCHAR *whichcmd;
     SECURITY_ATTRIBUTES sa;
-    char *new_cmd;
-    char *first_redir = NULL;
+    WCHAR *new_cmd;
+    WCHAR *first_redir = NULL;
     HANDLE old_stdhandles[3] = {INVALID_HANDLE_VALUE,
                                 INVALID_HANDLE_VALUE,
                                 INVALID_HANDLE_VALUE};
@@ -429,8 +476,8 @@
                                 STD_ERROR_HANDLE};
 
     /* Move copy of the command onto the heap so it can be expanded */
-    new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING );
-    strcpy(new_cmd, command);
+    new_cmd = HeapAlloc( GetProcessHeap(), 0, MAXSTRING * sizeof(WCHAR));
+    strcpyW(new_cmd, command);
 
     /* For commands in a context (batch program):                  */
     /*   Expand environment variables in a batch file %{0-9} first */
@@ -442,7 +489,7 @@
     /*   manual expansion of environment variables here            */
 
     p = new_cmd;
-    while ((p = strchr(p, '%'))) {
+    while ((p = strchrW(p, '%'))) {
       i = *(p+1) - '0';
 
       /* Replace %~ modifications if in batch program */
@@ -452,20 +499,20 @@
 
       /* Replace use of %0...%9 if in batch program*/
       } else if (context && (i >= 0) && (i <= 9)) {
-        s = strdup (p+2);
+        s = WCMD_strdupW(p+2);
         t = WCMD_parameter (context -> command, i + context -> shift_count[i], NULL);
-        strcpy (p, t);
-        strcat (p, s);
+        strcpyW (p, t);
+        strcatW (p, s);
         free (s);
 
       /* Replace use of %* if in batch program*/
       } else if (context && *(p+1)=='*') {
-        char *startOfParms = NULL;
-        s = strdup (p+2);
+        WCHAR *startOfParms = NULL;
+        s = WCMD_strdupW(p+2);
         t = WCMD_parameter (context -> command, 1, &startOfParms);
-        if (startOfParms != NULL) strcpy (p, startOfParms);
+        if (startOfParms != NULL) strcpyW (p, startOfParms);
         else *p = 0x00;
-        strcat (p, s);
+        strcatW (p, s);
         free (s);
 
       } else {
@@ -478,13 +525,13 @@
     /* so remove any remaining %var%                                */
     if (context) {
       p = cmd;
-      while ((p = strchr(p, '%'))) {
-        s = strchr(p+1, '%');
+      while ((p = strchrW(p, '%'))) {
+        s = strchrW(p+1, '%');
         if (!s) {
           *p=0x00;
         } else {
-          t = strdup(s+1);
-          strcpy(p, t);
+          t = WCMD_strdupW(s+1);
+          strcpyW(p, t);
           free(t);
         }
       }
@@ -501,17 +548,18 @@
  *	Changing default drive has to be handled as a special case.
  */
 
-    if ((cmd[1] == ':') && IsCharAlpha (cmd[0]) && (strlen(cmd) == 2)) {
-      char envvar[5];
-      char dir[MAX_PATH];
+    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             */
-      strcpy(envvar, "=");
-      strcat(envvar, cmd);
+      strcpyW(envvar, equalsW);
+      strcatW(envvar, cmd);
       if (GetEnvironmentVariable(envvar, dir, MAX_PATH) == 0) {
-        sprintf(cmd, "%s\\", cmd);
+        static const WCHAR fmt[] = {'%','s','\\','\0'};
+        wsprintf(cmd, fmt, cmd);
       }
       status = SetCurrentDirectory (cmd);
       if (!status) WCMD_print_error ();
@@ -527,7 +575,7 @@
  *	Redirect stdin, stdout and/or stderr if required.
  */
 
-    if ((p = strchr(cmd,'<')) != NULL) {
+    if ((p = strchrW(cmd,'<')) != NULL) {
       if (first_redir == NULL) first_redir = p;
       h = CreateFile (WCMD_parameter (++p, 0, NULL), GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING,
 		FILE_ATTRIBUTE_NORMAL, NULL);
@@ -542,7 +590,7 @@
 
     /* Scan the whole command looking for > and 2> */
     redir = cmd;
-    while (redir != NULL && ((p = strchr(redir,'>')) != NULL)) {
+    while (redir != NULL && ((p = strchrW(redir,'>')) != NULL)) {
       int handle = 0;
 
       if (*(p-1)!='2') {
@@ -577,7 +625,7 @@
         WINE_TRACE("Redirect %d (%p) to %d (%p)\n", handle, GetStdHandle(idx_stdhandles[idx]), idx, h);
 
       } else {
-        char *param = WCMD_parameter (p, 0, NULL);
+        WCHAR *param = WCMD_parameter (p, 0, NULL);
         h = CreateFile (param, GENERIC_WRITE, 0, &sa, creationDisposition,
                         FILE_ATTRIBUTE_NORMAL, NULL);
         if (h == INVALID_HANDLE_VALUE) {
@@ -589,7 +637,7 @@
               INVALID_SET_FILE_POINTER) {
           WCMD_print_error ();
         }
-        WINE_TRACE("Redirect %d to '%s' (%p)\n", handle, param, h);
+        WINE_TRACE("Redirect %d to '%s' (%p)\n", handle, wine_dbgstr_w(param), h);
       }
 
       old_stdhandles[handle] = GetStdHandle (idx_stdhandles[handle]);
@@ -603,7 +651,7 @@
  * Strip leading whitespaces, and a '@' if supplied
  */
     whichcmd = WCMD_strtrim_leading_spaces(cmd);
-    WINE_TRACE("Command: '%s'\n", cmd);
+    WINE_TRACE("Command: '%s'\n", wine_dbgstr_w(cmd));
     if (whichcmd[0] == '@') whichcmd++;
 
 /*
@@ -712,7 +760,7 @@
         WCMD_setshow_time ();
         break;
       case WCMD_TITLE:
-        if (strlen(&whichcmd[count]) > 0)
+        if (strlenW(&whichcmd[count]) > 0)
           WCMD_title(&whichcmd[count+1]);
         break;
       case WCMD_TYPE:
@@ -778,13 +826,13 @@
          * 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);
+        size_t sz = max(sizeof(unsigned) + (sizeof(WCHAR) + 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));
+            WCHAR* flags = (WCHAR*)(ptr + sizeof(unsigned));
+            HANDLE* handles = (HANDLE*)(flags + num * sizeof(WCHAR));
 
             memcpy(ptr, st_p.lpReserved2, st_p.cbReserved2);
             st->cbReserved2 = sz;
@@ -834,81 +882,91 @@
  *          findexecutable to acheive this which is left untouched.
  */
 
-void WCMD_run_program (char *command, int called) {
+void WCMD_run_program (WCHAR *command, int called) {
 
-  char  temp[MAX_PATH];
-  char  pathtosearch[MAXSTRING];
-  char *pathposn;
-  char  stemofsearch[MAX_PATH];
-  char *lastSlash;
-  char  pathext[MAXSTRING];
+  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 (strpbrk (param1, "/\\:") == NULL) {  /* No explicit path given, search path */
-    strcpy(pathtosearch,".;");
-    len = GetEnvironmentVariable ("PATH", &pathtosearch[2], sizeof(pathtosearch)-2);
-    if ((len == 0) || (len >= sizeof(pathtosearch) - 2)) {
-      lstrcpy (pathtosearch, ".");
+  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 (strchr(param1, '.') != NULL) extensionsupplied = TRUE;
-    strcpy(stemofsearch, param1);
+    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), pathtosearch, NULL);
-    lastSlash = strrchr(pathtosearch, '\\');
-    if (lastSlash && strchr(lastSlash, '.') != NULL) extensionsupplied = TRUE;
+    GetFullPathName(param1, sizeof(pathtosearch)/sizeof(WCHAR), pathtosearch, NULL);
+    lastSlash = strrchrW(pathtosearch, '\\');
+    if (lastSlash && strchrW(lastSlash, '.') != NULL) extensionsupplied = TRUE;
     if (lastSlash) *lastSlash = 0x00;
-    strcpy(stemofsearch, lastSlash+1);
+    strcpyW(stemofsearch, lastSlash+1);
   }
 
   /* Now extract PATHEXT */
-  len = GetEnvironmentVariable ("PATHEXT", pathext, sizeof(pathext));
-  if ((len == 0) || (len >= sizeof(pathext))) {
-    lstrcpy (pathext, ".bat;.com;.cmd;.exe");
+  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", pathtosearch, stemofsearch);
+  WINE_TRACE("Searching in '%s' for '%s'\n", wine_dbgstr_w(pathtosearch),
+             wine_dbgstr_w(stemofsearch));
   while (!launched && pathposn) {
 
-    char  thisDir[MAX_PATH] = "";
-    char *pos               = NULL;
+    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 = strchr(pathposn, ';');
+    pos = strchrW(pathposn, ';');
     if (pos) {
-      strncpy(thisDir, pathposn, (pos-pathposn));
+      memcpy(thisDir, pathposn, (pos-pathposn) * sizeof(WCHAR));
       thisDir[(pos-pathposn)] = 0x00;
       pathposn = pos+1;
 
     } else {
-      strcpy(thisDir, pathposn);
+      strcpyW(thisDir, pathposn);
       pathposn = NULL;
     }
 
     /* Since you can have eg. ..\.. on the path, need to expand
        to full information                                      */
-    strcpy(temp, thisDir);
+    strcpyW(temp, thisDir);
     GetFullPathName(temp, MAX_PATH, thisDir, NULL);
 
     /* 1. If extension supplied, see if that file exists */
-    strcat(thisDir, "\\");
-    strcat(thisDir, stemofsearch);
-    pos = &thisDir[strlen(thisDir)]; /* Pos = end of name */
+    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) {
@@ -921,24 +979,25 @@
     if (!found) {
       HANDLE          h;
       WIN32_FIND_DATA finddata;
+      static const WCHAR allFiles[] = {'.','*','\0'};
 
-      strcat(thisDir,".*");
+      strcatW(thisDir,allFiles);
       h = FindFirstFile(thisDir, &finddata);
       FindClose(h);
       if (h != INVALID_HANDLE_VALUE) {
 
-        char *thisExt = pathext;
+        WCHAR *thisExt = pathext;
 
         /* 3. Yes - Try each path ext */
         while (thisExt) {
-          char *nextExt = strchr(thisExt, ';');
+          WCHAR *nextExt = strchrW(thisExt, ';');
 
           if (nextExt) {
-            strncpy(pos, thisExt, (nextExt-thisExt));
+            memcpy(pos, thisExt, (nextExt-thisExt) * sizeof(WCHAR));
             pos[(nextExt-thisExt)] = 0x00;
             thisExt = nextExt+1;
           } else {
-            strcpy(pos, thisExt);
+            strcpyW(pos, thisExt);
             thisExt = NULL;
           }
 
@@ -959,7 +1018,7 @@
         WINE_TRACE("ASSUMING INTERNAL\n");
         assumeInternal = TRUE;
     } else {
-        WINE_TRACE("Found as %s\n", thisDir);
+        WINE_TRACE("Found as %s\n", wine_dbgstr_w(thisDir));
     }
 
     /* Once found, launch it */
@@ -969,14 +1028,17 @@
       SHFILEINFO psfi;
       DWORD console;
       HINSTANCE hinst;
-      char *ext = strrchr( thisDir, '.' );
+      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 && !strcasecmp(ext, ".bat")) {
+      if (ext && !strcmpiW(ext, batExt)) {
         WCMD_batch (thisDir, command, called, NULL, INVALID_HANDLE_VALUE);
         return;
-      } else if (ext && !strcasecmp(ext, ".cmd")) {
+      } else if (ext && !strcmpiW(ext, cmdExt)) {
         WCMD_batch (thisDir, command, called, NULL, INVALID_HANDLE_VALUE);
         return;
       } else {
@@ -999,7 +1061,7 @@
                                 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 characters and try again */
+          /* strip first and last quote WCHARacters and try again */
           WCMD_opt_s_strip_quotes(command);
           opt_s=1;
           WCMD_run_program(command, called);
@@ -1047,13 +1109,16 @@
 void WCMD_show_prompt (void) {
 
   int status;
-  char out_string[MAX_PATH], curdir[MAX_PATH], prompt_string[MAX_PATH];
-  char *p, *q;
+  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 ("PROMPT", prompt_string, sizeof(prompt_string));
-  if ((len == 0) || (len >= sizeof(prompt_string))) {
-    lstrcpy (prompt_string, "$P$G");
+  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;
@@ -1098,15 +1163,15 @@
 	  *q++ = '<';
 	  break;
 	case 'N':
-          status = GetCurrentDirectory (sizeof(curdir), curdir);
+          status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir);
 	  if (status) {
 	    *q++ = curdir[0];
 	  }
 	  break;
 	case 'P':
-          status = GetCurrentDirectory (sizeof(curdir), curdir);
+          status = GetCurrentDirectory (sizeof(curdir)/sizeof(WCHAR), curdir);
 	  if (status) {
-	    lstrcat (q, curdir);
+	    strcatW (q, curdir);
 	    while (*q) q++;
 	  }
 	  break;
@@ -1120,8 +1185,8 @@
 	  GetTimeFormat (LOCALE_USER_DEFAULT, 0, NULL, NULL, q, MAX_PATH);
 	  while (*q) q++;
 	  break;
-	case 'V':
-	  lstrcat (q, version_string);
+        case 'V':
+	  strcatW (q, version_string);
 	  while (*q) q++;
           break;
 	case '_':
@@ -1175,7 +1240,7 @@
  *	Parameters in quotes are handled.
  */
 
-void WCMD_parse (char *s, char *q, char *p1, char *p2) {
+void WCMD_parse (WCHAR *s, WCHAR *q, WCHAR *p1, WCHAR *p2) {
 
 int p = 0;
 
@@ -1222,12 +1287,47 @@
 
 /*******************************************************************
  * WCMD_output_asis_len - send output to current standard output
- *        device without formatting eg. when message contains '%'
- *        of a supplied length.
+ *
+ * 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 char *message, int len) {
-  DWORD count;
-  WriteFile (GetStdHandle(STD_OUTPUT_HANDLE), message, len, &count, NULL);
+static void WCMD_output_asis_len(const WCHAR *message, int len) {
+
+    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(GetStdHandle(STD_OUTPUT_HANDLE),
+                        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;
+
+      /*
+       * 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(GetStdHandle(STD_OUTPUT_HANDLE), output_bufA, convertedChars,
+                &nOut, FALSE);
+    }
+    return;
 }
 
 /*******************************************************************
@@ -1235,38 +1335,44 @@
  *
  */
 
-void WCMD_output (const char *format, ...) {
+void WCMD_output (const WCHAR *format, ...) {
 
   va_list ap;
-  char string[1024];
+  WCHAR string[1024];
   int ret;
 
   va_start(ap,format);
-  ret = vsnprintf (string, sizeof( string), format, ap);
-  va_end(ap);
-  if( ret >= sizeof( string)) {
+  ret = wvsprintf (string, format, ap);
+  if( ret >= (sizeof(string)/sizeof(WCHAR))) {
        WINE_ERR("Output truncated in WCMD_output\n" );
-       ret = sizeof(string) - 1;
+       ret = (sizeof(string)/sizeof(WCHAR)) - 1;
        string[ret] = '\0';
   }
+  va_end(ap);
   WCMD_output_asis_len(string, ret);
 }
 
 
 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 char *msg)
+void WCMD_enter_paged_mode(const WCHAR *msg)
 {
   CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
 
-  if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
+  if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) {
     max_height = consoleInfo.dwSize.Y;
-  else
+    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;
 }
 
@@ -1281,28 +1387,36 @@
  *        without formatting eg. when message contains '%'
  */
 
-void WCMD_output_asis (const char *message) {
+void WCMD_output_asis (const WCHAR *message) {
   DWORD count;
-  char* ptr;
-  char string[1024];
+  const WCHAR* ptr;
+  WCHAR string[1024];
 
   if (paged_mode) {
     do {
-      if ((ptr = strchr(message, '\n')) != NULL) ptr++;
-      WCMD_output_asis_len(message, (ptr) ? ptr - message : lstrlen(message));
+      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));
       if (ptr) {
+        numChars = 0;
         if (++line_count >= max_height - 1) {
-          line_count = 1;
-          WCMD_output_asis_len(pagedMessage, lstrlen(pagedMessage));
-          ReadFile (GetStdHandle(STD_INPUT_HANDLE), string, sizeof(string), &count, NULL);
+          line_count = 0;
+          WCMD_output_asis_len(pagedMessage, strlenW(pagedMessage));
+          WCMD_ReadFile (GetStdHandle(STD_INPUT_HANDLE), string,
+                         sizeof(string)/sizeof(WCHAR), &count, NULL);
         }
       }
-    } while ((message = ptr) != NULL);
+    } while (((message = ptr) != NULL) && (*ptr));
   } else {
     WCMD_output_asis_len(message, lstrlen(message));
   }
 }
 
+
 /***************************************************************************
  * WCMD_strtrim_leading_spaces
  *
@@ -1310,9 +1424,9 @@
  *	non-space character. Does not modify the input string
  */
 
-char *WCMD_strtrim_leading_spaces (char *string) {
+WCHAR *WCMD_strtrim_leading_spaces (WCHAR *string) {
 
-  char *ptr;
+  WCHAR *ptr;
 
   ptr = string;
   while (*ptr == ' ') ptr++;
@@ -1323,14 +1437,14 @@
  * WCMD_strtrim_trailing_spaces
  *
  *	Remove trailing spaces from a string. This routine modifies the input
- *	string by placing a null after the last non-space character
+ *	string by placing a null after the last non-space WCHARacter
  */
 
-void WCMD_strtrim_trailing_spaces (char *string) {
+void WCMD_strtrim_trailing_spaces (WCHAR *string) {
 
-  char *ptr;
+  WCHAR *ptr;
 
-  ptr = string + lstrlen (string) - 1;
+  ptr = string + strlenW (string) - 1;
   while ((*ptr == ' ') && (ptr >= string)) {
     *ptr = '\0';
     ptr--;
@@ -1340,11 +1454,11 @@
 /*************************************************************************
  * WCMD_opt_s_strip_quotes
  *
- *	Remove first and last quote characters, preserving all other text
+ *	Remove first and last quote WCHARacters, preserving all other text
  */
 
-void WCMD_opt_s_strip_quotes(char *cmd) {
-  char *src = cmd + 1, *dest = cmd, *lastq = NULL;
+void WCMD_opt_s_strip_quotes(WCHAR *cmd) {
+  WCHAR *src = cmd + 1, *dest = cmd, *lastq = NULL;
   while((*dest=*src) != '\0') {
       if (*src=='\"')
           lastq=dest;
@@ -1363,28 +1477,33 @@
  *	Handle pipes within a command - the DOS way using temporary files.
  */
 
-void WCMD_pipe (char *command) {
+void WCMD_pipe (WCHAR *command) {
 
-  char *p;
-  char temp_path[MAX_PATH], temp_file[MAX_PATH], temp_file2[MAX_PATH], temp_cmd[1024];
+  WCHAR *p;
+  WCHAR temp_path[MAX_PATH], temp_file[MAX_PATH], temp_file2[MAX_PATH], temp_cmd[1024];
+  static const WCHAR redirOut[] = {'%','s',' ','>',' ','%','s','\0'};
+  static const WCHAR redirIn[]  = {'%','s',' ','<',' ','%','s','\0'};
+  static const WCHAR redirBoth[]= {'%','s',' ','<',' ','%','s',' ','>','%','s','\0'};
+  static const WCHAR cmdW[]     = {'C','M','D','\0'};
 
-  GetTempPath (sizeof(temp_path), temp_path);
-  GetTempFileName (temp_path, "CMD", 0, temp_file);
-  p = strchr(command, '|');
+
+  GetTempPath (sizeof(temp_path)/sizeof(WCHAR), temp_path);
+  GetTempFileName (temp_path, cmdW, 0, temp_file);
+  p = strchrW(command, '|');
   *p++ = '\0';
-  wsprintf (temp_cmd, "%s > %s", command, temp_file);
+  wsprintf (temp_cmd, redirOut, command, temp_file);
   WCMD_process_command (temp_cmd);
   command = p;
-  while ((p = strchr(command, '|'))) {
+  while ((p = strchrW(command, '|'))) {
     *p++ = '\0';
-    GetTempFileName (temp_path, "CMD", 0, temp_file2);
-    wsprintf (temp_cmd, "%s < %s > %s", command, temp_file, temp_file2);
+    GetTempFileName (temp_path, cmdW, 0, temp_file2);
+    wsprintf (temp_cmd, redirBoth, command, temp_file, temp_file2);
     WCMD_process_command (temp_cmd);
     DeleteFile (temp_file);
-    lstrcpy (temp_file, temp_file2);
+    strcpyW (temp_file, temp_file2);
     command = p;
   }
-  wsprintf (temp_cmd, "%s < %s", command, temp_file);
+  wsprintf (temp_cmd, redirIn, command, temp_file);
   WCMD_process_command (temp_cmd);
   DeleteFile (temp_file);
 }
@@ -1392,26 +1511,37 @@
 /*************************************************************************
  * WCMD_expand_envvar
  *
- *	Expands environment variables, allowing for character substitution
+ *	Expands environment variables, allowing for WCHARacter substitution
  */
-static char *WCMD_expand_envvar(char *start) {
-    char *endOfVar = NULL, *s;
-    char *colonpos = NULL;
-    char thisVar[MAXSTRING];
-    char thisVarContents[MAXSTRING];
-    char savedchar = 0x00;
+static WCHAR *WCMD_expand_envvar(WCHAR *start) {
+    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'};
+
     /* Find the end of the environment variable, and extract name */
-    endOfVar = strchr(start+1, '%');
+    endOfVar = strchrW(start+1, '%');
     if (endOfVar == NULL) {
-      /* FIXME: Some special conditions here depending opn whether
+      /* FIXME: Some special conditions here depending on whether
          in batch, complex or not, and whether env var exists or not! */
       return start+1;
     }
-    strncpy(thisVar, start, (endOfVar - start)+1);
+    memcpy(thisVar, start, ((endOfVar - start) + 1) * sizeof(WCHAR));
     thisVar[(endOfVar - start)+1] = 0x00;
-    colonpos = strchr(thisVar+1, ':');
+    colonpos = strchrW(thisVar+1, ':');
 
     /* If there's complex substitution, just need %var% for now
        to get the expanded data to play with                    */
@@ -1421,56 +1551,60 @@
         *(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, "%ERRORLEVEL%", -1) == 2) &&
-                (GetEnvironmentVariable("ERRORLEVEL", thisVarContents, 1) == 0) &&
+                        thisVar, 12, ErrorLvlP, -1) == 2) &&
+                (GetEnvironmentVariable(ErrorLvl, thisVarContents, 1) == 0) &&
                 (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
-      sprintf(thisVarContents, "%d", errorlevel);
-      len = strlen(thisVarContents);
+      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, "%DATE%", -1) == 2) &&
-                (GetEnvironmentVariable("DATE", thisVarContents, 1) == 0) &&
+                               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 = strlen(thisVarContents);
+      len = strlenW(thisVarContents);
 
     } else if ((CompareString (LOCALE_USER_DEFAULT,
                                NORM_IGNORECASE | SORT_STRINGSORT,
-                               thisVar, 6, "%TIME%", -1) == 2) &&
-                (GetEnvironmentVariable("TIME", thisVarContents, 1) == 0) &&
+                               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 = strlen(thisVarContents);
+      len = strlenW(thisVarContents);
 
     } else if ((CompareString (LOCALE_USER_DEFAULT,
                                NORM_IGNORECASE | SORT_STRINGSORT,
-                               thisVar, 4, "%CD%", -1) == 2) &&
-                (GetEnvironmentVariable("CD", thisVarContents, 1) == 0) &&
+                               thisVar, 4, CdP, -1) == 2) &&
+                (GetEnvironmentVariable(Cd, thisVarContents, 1) == 0) &&
                 (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
       GetCurrentDirectory (MAXSTRING, thisVarContents);
-      len = strlen(thisVarContents);
+      len = strlenW(thisVarContents);
 
     } else if ((CompareString (LOCALE_USER_DEFAULT,
                                NORM_IGNORECASE | SORT_STRINGSORT,
-                               thisVar, 8, "%RANDOM%", -1) == 2) &&
-                (GetEnvironmentVariable("RANDOM", thisVarContents, 1) == 0) &&
+                               thisVar, 8, RandomP, -1) == 2) &&
+                (GetEnvironmentVariable(Random, thisVarContents, 1) == 0) &&
                 (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
-      sprintf(thisVarContents, "%d", rand() % 32768);
-      len = strlen(thisVarContents);
+      static const WCHAR fmt[] = {'%','d','\0'};
+      wsprintf(thisVarContents, fmt, rand() % 32768);
+      len = strlenW(thisVarContents);
 
     } else {
 
       len = ExpandEnvironmentStrings(thisVar, thisVarContents,
-                                      sizeof(thisVarContents));
+                               sizeof(thisVarContents)/sizeof(WCHAR));
     }
 
     if (len == 0)
@@ -1480,7 +1614,7 @@
          note syntax %garbage:1,3% results in anything after the ':'
          except the %
        From the command line, you just get back what you entered      */
-    if (lstrcmpi(thisVar, thisVarContents) == 0) {
+    if (lstrcmpiW(thisVar, thisVarContents) == 0) {
 
       /* Restore the complex part after the compare */
       if (colonpos) {
@@ -1488,25 +1622,25 @@
         *(colonpos+1) = savedchar;
       }
 
-      s = strdup (endOfVar + 1);
+      s = WCMD_strdupW(endOfVar + 1);
 
       /* Command line - just ignore this */
       if (context == NULL) return endOfVar+1;
 
       /* Batch - replace unknown env var with nothing */
       if (colonpos == NULL) {
-        strcpy (start, s);
+        strcpyW (start, s);
 
       } else {
-        len = strlen(thisVar);
+        len = strlenW(thisVar);
         thisVar[len-1] = 0x00;
         /* If %:...% supplied, : is retained */
         if (colonpos == thisVar+1) {
-          strcpy (start, colonpos);
+          strcpyW (start, colonpos);
         } else {
-          strcpy (start, colonpos+1);
+          strcpyW (start, colonpos+1);
         }
-        strcat (start, s);
+        strcatW (start, s);
       }
       free (s);
       return start;
@@ -1516,9 +1650,9 @@
     /* See if we need to do complex substitution (any ':'s), if not
        then our work here is done                                  */
     if (colonpos == NULL) {
-      s = strdup (endOfVar + 1);
-      strcpy (start, thisVarContents);
-      strcat (start, s);
+      s = WCMD_strdupW(endOfVar + 1);
+      strcpyW (start, thisVarContents);
+      strcatW (start, s);
       free(s);
       return start;
     }
@@ -1531,23 +1665,23 @@
         Handle complex substitutions:
            xxx=yyy    (replace xxx with yyy)
            *xxx=yyy   (replace up to and including xxx with yyy)
-           ~x         (from x chars in)
-           ~-x        (from x chars from the end)
-           ~x,y       (from x chars in for y characters)
-           ~x,-y      (from x chars in until y characters from the end)
+           ~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;
-      char *commapos = strchr(colonpos+2, ',');
-      char *startCopy;
+      WCHAR *commapos = strchrW(colonpos+2, ',');
+      WCHAR *startCopy;
 
-      substrposition = atol(colonpos+2);
-      if (commapos) substrlength = atol(commapos+1);
+      substrposition = atolW(colonpos+2);
+      if (commapos) substrlength = atolW(commapos+1);
 
-      s = strdup (endOfVar + 1);
+      s = WCMD_strdupW(endOfVar + 1);
 
       /* Check bounds */
       if (substrposition >= 0) {
@@ -1557,81 +1691,80 @@
       }
 
       if (commapos == NULL) {
-        strcpy (start, startCopy); /* Copy the lot */
+        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;
-        strncpy (start, startCopy, copybytes); /* Copy the lot */
+        memcpy (start, startCopy, copybytes * sizeof(WCHAR)); /* Copy the lot */
         start[copybytes] = 0x00;
       } else {
-        strncpy (start, startCopy, substrlength); /* Copy the lot */
+        memcpy (start, startCopy, substrlength * sizeof(WCHAR)); /* Copy the lot */
         start[substrlength] = 0x00;
       }
 
-      strcat (start, s);
+      strcatW (start, s);
       free(s);
       return start;
 
     /* search and replace manipulation */
     } else {
-      char *equalspos = strstr(colonpos, "=");
-      char *replacewith = equalspos+1;
-      char *found       = NULL;
-      char *searchIn;
-      char *searchFor;
+      WCHAR *equalspos = strstrW(colonpos, equalsW);
+      WCHAR *replacewith = equalspos+1;
+      WCHAR *found       = NULL;
+      WCHAR *searchIn;
+      WCHAR *searchFor;
 
-      s = strdup (endOfVar + 1);
+      s = WCMD_strdupW(endOfVar + 1);
       if (equalspos == NULL) return start+1;
 
       /* Null terminate both strings */
-      thisVar[strlen(thisVar)-1] = 0x00;
+      thisVar[strlenW(thisVar)-1] = 0x00;
       *equalspos = 0x00;
 
       /* Since we need to be case insensitive, copy the 2 buffers */
-      searchIn  = strdup(thisVarContents);
-      CharUpperBuff(searchIn, strlen(thisVarContents));
-      searchFor = strdup(colonpos+1);
-      CharUpperBuff(searchFor, strlen(colonpos+1));
+      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 = strstr(searchIn, searchFor+1);
+        found = strstrW(searchIn, searchFor+1);
 
         if (found) {
           /* Do replacement */
-          strcpy(start, replacewith);
-          strcat(start, thisVarContents + (found-searchIn) + strlen(searchFor+1));
-          strcat(start, s);
+          strcpyW(start, replacewith);
+          strcatW(start, thisVarContents + (found-searchIn) + strlenW(searchFor+1));
+          strcatW(start, s);
           free(s);
         } else {
           /* Copy as it */
-          strcpy(start, thisVarContents);
-          strcat(start, s);
+          strcpyW(start, thisVarContents);
+          strcatW(start, s);
         }
 
       } else {
         /* Loop replacing all instances */
-        char *lastFound = searchIn;
-        char *outputposn = start;
+        WCHAR *lastFound = searchIn;
+        WCHAR *outputposn = start;
 
         *start = 0x00;
-        while ((found = strstr(lastFound, searchFor))) {
-            strncpy(outputposn,
+        while ((found = strstrW(lastFound, searchFor))) {
+            lstrcpynW(outputposn,
                     thisVarContents + (lastFound-searchIn),
-                    (found - lastFound));
+                    (found - lastFound)+1);
             outputposn  = outputposn + (found - lastFound);
-            *outputposn = 0x00;
-            strcat(outputposn, replacewith);
-            outputposn = outputposn + strlen(replacewith);
-            lastFound = found + strlen(searchFor);
+            strcatW(outputposn, replacewith);
+            outputposn = outputposn + strlenW(replacewith);
+            lastFound = found + strlenW(searchFor);
         }
-        strcat(outputposn,
+        strcatW(outputposn,
                 thisVarContents + (lastFound-searchIn));
-        strcat(outputposn, s);
+        strcatW(outputposn, s);
       }
       free(searchIn);
       free(searchFor);
@@ -1645,13 +1778,65 @@
  *    Load a string from the resource file, handling any error
  *    Returns string retrieved from resource file
  */
-char *WCMD_LoadMessage(UINT id) {
-    static char msg[2048];
-    const char failedMsg[]  = "Failed!";
+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))) {
+    if (!LoadString(GetModuleHandle(NULL), id, msg, sizeof(msg)/sizeof(WCHAR))) {
        WINE_FIXME("LoadString failed with %d\n", GetLastError());
-       lstrcpy(msg, failedMsg);
+       strcpyW(msg, failedMsg);
     }
     return msg;
 }
+
+/*************************************************************************
+ * 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_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;
+}