update for HEAD-2003091401
[reactos.git] / subsys / system / cmd / cmd.c
index 54cf665..b1b9c1c 100644 (file)
@@ -144,6 +144,7 @@ DWORD dwChildProcessId = 0;
 OSVERSIONINFO osvi;
 HANDLE hIn;
 HANDLE hOut;
+HANDLE hConsole;
 
 #ifdef INCLUDE_CMD_COLOR
 WORD wColor;              /* current color */
@@ -179,7 +180,7 @@ Execute (LPTSTR first, LPTSTR rest)
        DWORD dwExitCode = 0;
 
 #ifdef _DEBUG
-       DebugPrintf ("Execute: \'%s\' \'%s\'\n", first, rest);
+       DebugPrintf (_T("Execute: \'%s\' \'%s\'\n"), first, rest);
 #endif
 
        /* check for a drive change */
@@ -191,8 +192,8 @@ Execute (LPTSTR first, LPTSTR rest)
                {
                        TCHAR str[4];
                        str[0]=first[0];
-                       str[1]=':';
-                       str[2]='\\';
+                       str[1]=_T(':');
+                       str[2]=_T('\\');
                        str[3]=0;
                        working = SetCurrentDirectory(str);
                }
@@ -219,7 +220,7 @@ Execute (LPTSTR first, LPTSTR rest)
                !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd")))
        {
 #ifdef _DEBUG
-               DebugPrintf ("[BATCH: %s %s]\n", szFullName, rest);
+               DebugPrintf (_T("[BATCH: %s %s]\n"), szFullName, rest);
 #endif
                Batch (szFullName, first, rest);
        }
@@ -231,7 +232,7 @@ Execute (LPTSTR first, LPTSTR rest)
                STARTUPINFO stui;
 
 #ifdef _DEBUG
-               DebugPrintf ("[EXEC: %s %s]\n", szFullName, rest);
+               DebugPrintf (_T("[EXEC: %s %s]\n"), szFullName, rest);
 #endif
                /* build command line for CreateProcess() */
                _tcscpy (szFullCmdLine, first);
@@ -266,7 +267,7 @@ Execute (LPTSTR first, LPTSTR rest)
                        WaitForSingleObject (prci.hProcess, INFINITE);
 
                        /* FIXME: Protect this with critical section */
-                       bChildProcessRunning = TRUE;
+                       bChildProcessRunning = FALSE;
 
                        GetExitCodeProcess (prci.hProcess, &dwExitCode);
                        nErrorLevel = (INT)dwExitCode;
@@ -276,7 +277,7 @@ Execute (LPTSTR first, LPTSTR rest)
                else
                {
                        ErrorMessage (GetLastError (),
-                                     "Error executing CreateProcess()!!\n");
+                                     _T("Error executing CreateProcess()!!\n"));
                }
                // restore console mode
                SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
@@ -301,7 +302,7 @@ Execute (LPTSTR first, LPTSTR rest)
 static VOID
 DoCommand (LPTSTR line)
 {
-       TCHAR com[MAX_PATH];  /* the first word in the command */
+       TCHAR com[CMDLINE_LENGTH];  /* the first word in the command */
        LPTSTR cp = com;
        LPTSTR cstart;
        LPTSTR rest = line;   /* pointer to the rest of the command line */
@@ -309,11 +310,11 @@ DoCommand (LPTSTR line)
        LPCOMMAND cmdptr;
 
 #ifdef _DEBUG
-       DebugPrintf ("DoCommand: (\'%s\')\n", line);
+       DebugPrintf (_T("DoCommand: (\'%s\')\n"), line);
 #endif /* DEBUG */
 
        /* Skip over initial white space */
-       while (isspace (*rest))
+       while (_istspace (*rest))
                rest++;
 
        cstart = rest;
@@ -339,6 +340,13 @@ DoCommand (LPTSTR line)
 
                /* Terminate first word */
                *cp = _T('\0');
+               
+               /* commands are limited to MAX_PATH */
+               if(_tcslen(com) > MAX_PATH)
+               {
+                 error_bad_command();
+                 return;
+               }
 
                /* Skip over whitespace to rest of line */
                while (_istspace (*rest))
@@ -399,11 +407,11 @@ VOID ParseCommandLine (LPTSTR cmd)
        TCHAR cmdline[CMDLINE_LENGTH];
        LPTSTR s;
 #ifdef FEATURE_REDIRECTION
-       TCHAR in[CMDLINE_LENGTH] = "";
-       TCHAR out[CMDLINE_LENGTH] = "";
-       TCHAR err[CMDLINE_LENGTH] = "";
+       TCHAR in[CMDLINE_LENGTH] = _T("");
+       TCHAR out[CMDLINE_LENGTH] = _T("");
+       TCHAR err[CMDLINE_LENGTH] = _T("");
        TCHAR szTempPath[MAX_PATH] = _T(".\\");
-       TCHAR szFileName[2][MAX_PATH] = {"", ""};
+       TCHAR szFileName[2][MAX_PATH] = {_T(""), _T("")};
        HANDLE hFile[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE};
        LPTSTR t = NULL;
        INT  num = 0;
@@ -418,7 +426,7 @@ VOID ParseCommandLine (LPTSTR cmd)
        s = &cmdline[0];
 
 #ifdef _DEBUG
-       DebugPrintf ("ParseCommandLine: (\'%s\')\n", s);
+       DebugPrintf (_T("ParseCommandLine: (\'%s\')\n"), s);
 #endif /* DEBUG */
 
 #ifdef FEATURE_ALIASES
@@ -464,13 +472,13 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf ("Can't redirect input from file %s\n", in);
+                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
                        return;
                }
 
                if (!SetStdHandle (STD_INPUT_HANDLE, hFile))
                {
-                       ConErrPrintf ("Can't redirect input from file %s\n", in);
+                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
                        return;
                }
 #ifdef _DEBUG
@@ -479,7 +487,7 @@ VOID ParseCommandLine (LPTSTR cmd)
        }
 
        /* Now do all but the last pipe command */
-       *szFileName[0] = '\0';
+       *szFileName[0] = _T('\0');
        hFile[0] = INVALID_HANDLE_VALUE;
 
        while (num-- > 1)
@@ -487,7 +495,7 @@ VOID ParseCommandLine (LPTSTR cmd)
                SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
 
                /* Create unique temporary file name */
-               GetTempFileName (szTempPath, "CMD", 0, szFileName[1]);
+               GetTempFileName (szTempPath, _T("CMD"), 0, szFileName[1]);
 
                /* Set current stdout to temporary file */
                hFile[1] = CreateFile (szFileName[1], GENERIC_WRITE, 0, &sa,
@@ -540,13 +548,13 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf ("Can't redirect to file %s\n", out);
+                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
                        return;
                }
 
                if (!SetStdHandle (STD_OUTPUT_HANDLE, hFile))
                {
-                       ConErrPrintf ("Can't redirect to file %s\n", out);
+                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
                        return;
                }
 
@@ -599,13 +607,13 @@ VOID ParseCommandLine (LPTSTR cmd)
                                            NULL);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
-                               ConErrPrintf ("Can't redirect to file %s\n", err);
+                               ConErrPrintf (_T("Can't redirect to file %s\n"), err);
                                return;
                        }
                }
                if (!SetStdHandle (STD_ERROR_HANDLE, hFile))
                {
-                       ConErrPrintf ("Can't redirect to file %s\n", err);
+                       ConErrPrintf (_T("Can't redirect to file %s\n"), err);
                        return;
                }
 
@@ -789,7 +797,7 @@ ProcessInput (BOOL bFlag)
                                                if ((tp != NULL) &&
                                                    (tp <= _tcschr(ip, _T(' ')) - 1))
                                                {
-                                                       char evar[512];
+                                                       TCHAR evar[512];
                                                        *tp = _T('\0');
 
                                                        /* FIXME: This is just a quick hack!! */
@@ -845,7 +853,7 @@ ProcessInput (BOOL bFlag)
 /*
  * control-break handler.
  */
-BOOL BreakHandler (DWORD dwCtrlType)
+BOOL WINAPI BreakHandler (DWORD dwCtrlType)
 {
        if ((dwCtrlType != CTRL_C_EVENT) &&
            (dwCtrlType != CTRL_BREAK_EVENT))
@@ -869,18 +877,13 @@ BOOL BreakHandler (DWORD dwCtrlType)
 
 VOID AddBreakHandler (VOID)
 {
-#ifndef __REACTOS__
-       SetConsoleCtrlHandler ((PHANDLER_ROUTINE)&BreakHandler,
-                              TRUE);
-#endif
+       SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE);
 }
 
 
 VOID RemoveBreakHandler (VOID)
 {
-#ifndef __REACTOS__
-       SetConsoleCtrlHandler (NULL, FALSE);
-#endif
+       SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE);
 }
 
 
@@ -888,6 +891,7 @@ VOID RemoveBreakHandler (VOID)
  * show commands and options that are available.
  *
  */
+#if 0
 static VOID
 ShowCommands (VOID)
 {
@@ -896,25 +900,25 @@ ShowCommands (VOID)
        PrintCommandList ();
 
        /* print feature list */
-       ConOutPuts ("\nFeatures available:");
+       ConOutPuts (_T("\nFeatures available:"));
 #ifdef FEATURE_ALIASES
-       ConOutPuts ("  [aliases]");
+       ConOutPuts (_T("  [aliases]"));
 #endif
 #ifdef FEATURE_HISTORY
-       ConOutPuts ("  [history]");
+       ConOutPuts (_T("  [history]"));
 #endif
 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
-       ConOutPuts ("  [unix filename completion]");
+       ConOutPuts (_T("  [unix filename completion]"));
 #endif
 #ifdef FEATURE_DIRECTORY_STACK
-       ConOutPuts ("  [directory stack]");
+       ConOutPuts (_T("  [directory stack]"));
 #endif
 #ifdef FEATURE_REDIRECTION
-       ConOutPuts ("  [redirections and piping]");
+       ConOutPuts (_T("  [redirections and piping]"));
 #endif
-       ConOutChar ('\n');
+       ConOutChar (_T('\n'));
 }
-
+#endif
 
 /*
  * set up global initializations and process parameters
@@ -924,21 +928,24 @@ ShowCommands (VOID)
  *
  */
 static VOID
-Initialize (int argc, char *argv[])
+Initialize (int argc, TCHAR* argv[])
 {
        TCHAR commandline[CMDLINE_LENGTH];
        TCHAR ModuleName[_MAX_PATH + 1];
        INT i;
+       //INT len;
+       //TCHAR *ptr, *cmdLine;
+
 
 #ifdef _DEBUG
        INT x;
 
-       DebugPrintf ("[command args:\n");
+       DebugPrintf (_T("[command args:\n"));
        for (x = 0; x < argc; x++)
        {
-               DebugPrintf ("%d. %s\n", x, argv[x]);
+               DebugPrintf (_T("%d. %s\n"), x, argv[x]);
        }
-       DebugPrintf ("]\n");
+       DebugPrintf (_T("]\n"));
 #endif
 
        /* get version information */
@@ -984,10 +991,10 @@ Initialize (int argc, char *argv[])
                                if (!IsValidFileName (_T("\\autoexec.bat")))
                                {
 #ifdef INCLUDE_CMD_DATE
-                                       cmd_date ("", "");
+                                       cmd_date (_T(""), _T(""));
 #endif
 #ifdef INCLUDE_CMD_TIME
-                                       cmd_time ("", "");
+                                       cmd_time (_T(""), _T(""));
 #endif
                                }
                                else
@@ -1000,12 +1007,12 @@ Initialize (int argc, char *argv[])
                        {
                                /* This just runs a program and exits */
                                ++i;
-                               if (argv[i])
+                               if (i < argc)
                                {
                                        _tcscpy (commandline, argv[i]);
-                                       while (argv[++i])
+                                       while (++i < argc)
                                        {
-                                               _tcscat (commandline, " ");
+                                               _tcscat (commandline, _T(" "));
                                                _tcscat (commandline, argv[i]);
                                        }
 
@@ -1021,12 +1028,12 @@ Initialize (int argc, char *argv[])
                        {
                                /* This just runs a program and remains */
                                ++i;
-                               if (argv[i])
+                               if (i < argc)
                                {
                                        _tcscpy (commandline, argv[i]);
-                                       while (argv[++i])
+                                       while (++i < argc)
                                        {
-                                               _tcscat (commandline, " ");
+                                               _tcscat (commandline, _T(" "));
                                                _tcscat (commandline, argv[i]);
                                        }
 
@@ -1037,7 +1044,7 @@ Initialize (int argc, char *argv[])
                        else if (!_tcsnicmp (argv[i], _T("/t:"), 3))
                        {
                                /* process /t (color) argument */
-                               wDefColor = (WORD)strtoul (&argv[i][3], NULL, 16);
+                               wDefColor = (WORD)_tcstoul (&argv[i][3], NULL, 16);
                                wColor = wDefColor;
                                SetScreenColor (wColor, TRUE);
                        }
@@ -1066,7 +1073,7 @@ Initialize (int argc, char *argv[])
 
                if (IsValidFileName (_T("commandline")))
                {
-                       ConErrPrintf ("Running %s...\n", commandline);
+                       ConErrPrintf (_T("Running %s...\n", commandline));
                        ParseCommandLine (commandline);
                }
        }
@@ -1095,17 +1102,17 @@ Initialize (int argc, char *argv[])
 }
 
 
-static VOID Cleanup (int argc, char *argv[])
+static VOID Cleanup (int argc, TCHAR *argv[])
 {
        /* run cmdexit.bat */
        if (IsValidFileName (_T("cmdexit.bat")))
        {
-               ConErrPrintf ("Running cmdexit.bat...\n");
+               ConErrPrintf (_T("Running cmdexit.bat...\n"));
                ParseCommandLine (_T("cmdexit.bat"));
        }
        else if (IsValidFileName (_T("\\cmdexit.bat")))
        {
-               ConErrPrintf ("Running \\cmdexit.bat...\n");
+               ConErrPrintf (_T("Running \\cmdexit.bat...\n"));
                ParseCommandLine (_T("\\cmdexit.bat"));
        }
 #ifndef __REACTOS__
@@ -1121,7 +1128,7 @@ static VOID Cleanup (int argc, char *argv[])
 
                if (IsValidFileName (_T("commandline")))
                {
-                       ConErrPrintf ("Running %s...\n", commandline);
+                       ConErrPrintf (_T("Running %s...\n"), commandline);
                        ParseCommandLine (commandline);
                }
        }
@@ -1151,26 +1158,86 @@ static VOID Cleanup (int argc, char *argv[])
                        ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
 }
 
+#ifdef __REACTOS__
+#ifdef _UNICODE
+PWCHAR * _CommandLineToArgvW(PWCHAR lpCmdLine, int *pNumArgs)
+{
+   PWCHAR * argvw = NULL;
+   PWCHAR ptr = lpCmdLine;
+   PWCHAR str;
+   int len;
+   int NumArgs;
+
+   NumArgs = 0;
+
+   while(lpCmdLine && *lpCmdLine)
+   {
+       while (iswspace(*lpCmdLine)) lpCmdLine++;
+       if (*lpCmdLine)
+       {
+          if ((NumArgs % 10)==0)
+          {
+               PWCHAR * old_argvw = argvw;
+              argvw = malloc((NumArgs + 10) * sizeof(PWCHAR));
+              memcpy(argvw, old_argvw, NumArgs * sizeof(PWCHAR));
+              free(old_argvw);
+          }
+          ptr = wcschr(lpCmdLine, L' ');
+          if (ptr)
+          {
+              len = ptr - lpCmdLine;
+          }
+          else
+          {
+              len = wcslen(lpCmdLine);
+          }
+          str = malloc((len + 1) * sizeof(WCHAR));
+          memcpy(str, lpCmdLine, len * sizeof(WCHAR));
+          str[len] = 0;
+          argvw[NumArgs]=str;
+          NumArgs++;
+          lpCmdLine = ptr;
+       }
+   }
+   *pNumArgs = NumArgs;
+   return argvw;
+}
+#endif
+#endif
 
 /*
  * main function
  */
+#ifdef _UNICODE
+int main(void)
+#else
 int main (int argc, char *argv[])
+#endif
 {
   CONSOLE_SCREEN_BUFFER_INFO Info;
   INT nExitCode;
+#ifdef _UNICODE
+  PWCHAR * argv;
+  int argc=0;
+#ifdef __REACTOS__
+  argv = _CommandLineToArgvW(GetCommandLineW(), &argc);
+#else
+  argv = CommandLineToArgvW(GetCommandLineW(), &argc);
+#endif
+#endif
 
   SetFileApisToOEM();
 
   AllocConsole();
-  if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &Info) == FALSE)
+
+
+  hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, 
+                        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 
+                       OPEN_EXISTING, 0, NULL);
+  if (GetConsoleScreenBufferInfo(hConsole, &Info) == FALSE)
     {
-      fprintf(stderr, "GetConsoleScreenBufferInfo: Error: %ld\n", GetLastError());
-#ifndef __REACTOS__
-      /* On ReactOS GetConsoleScreenBufferInfo returns an error if the stdin 
-         handle is redirected to a pipe or file. This stops windres from working. */
+      ConErrPrintf (_T("GetConsoleScreenBufferInfo: Error: %ld\n"), GetLastError());
       return(1);
-#endif
     }
   wColor = Info.wAttributes;
   wDefColor = wColor;