[CMD]: Continue refactoring to lay out the way to using the CONUTILS library in CMD...
[reactos.git] / reactos / base / shell / cmd / cmd.c
index 6e01103..bc608f8 100644 (file)
@@ -81,7 +81,7 @@
  *        added showcmds function to show commands and options available
  *
  *    07-Aug-1998 (John P Price <linux-guru@gcfl.net>)
- *        Fixed carrage return output to better match MSDOS with echo
+ *        Fixed carriage return output to better match MSDOS with echo
  *        on or off. (marked with "JPP 19980708")
  *
  *    07-Dec-1998 (Eric Kohl)
  *
  *    06-jul-2005 (Magnus Olsen <magnus@greatlord.com>)
  *        translate '%errorlevel%' to the internal value.
- *        Add proper memmory alloc ProcessInput, the error
- *        handling for memmory handling need to be improve
+ *        Add proper memory alloc ProcessInput, the error
+ *        handling for memory handling need to be improve
  */
 
 #include "precomp.h"
 #include <reactos/buildno.h>
 #include <reactos/version.h>
 
-#ifndef NT_SUCCESS
-#define NT_SUCCESS(StatCode)  ((NTSTATUS)(StatCode) >= 0)
-#endif
-
 typedef NTSTATUS (WINAPI *NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS,
                                                           PVOID, ULONG, PULONG);
 typedef NTSTATUS (WINAPI *NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, ULONG, PULONG);
@@ -157,15 +153,16 @@ BOOL bExit = FALSE;       /* indicates EXIT was typed */
 BOOL bCanExit = TRUE;     /* indicates if this shell is exitable */
 BOOL bCtrlBreak = FALSE;  /* Ctrl-Break or Ctrl-C hit */
 BOOL bIgnoreEcho = FALSE; /* Set this to TRUE to prevent a newline, when executing a command */
+static BOOL bWaitForCommand = FALSE; /* When we are executing something passed on the commandline after /c or /k */
 INT  nErrorLevel = 0;     /* Errorlevel of last launched external program */
 CRITICAL_SECTION ChildProcessRunningLock;
 BOOL bUnicodeOutput = FALSE;
 BOOL bDisableBatchEcho = FALSE;
+BOOL bEnableExtensions = TRUE;
 BOOL bDelayedExpansion = FALSE;
+BOOL bTitleSet = FALSE;
 DWORD dwChildProcessId = 0;
-OSVERSIONINFO osvi;
 HANDLE hIn;
-HANDLE hOut;
 LPTSTR lpOriginalEnvironment;
 HANDLE CMD_ModuleHandle;
 
@@ -173,7 +170,7 @@ static NtQueryInformationProcessProc NtQueryInformationProcessPtr = NULL;
 static NtReadVirtualMemoryProc       NtReadVirtualMemoryPtr = NULL;
 
 #ifdef INCLUDE_CMD_COLOR
-WORD wDefColor;           /* default color */
+WORD wDefColor = 0;     /* Default color */
 #endif
 
 /*
@@ -182,7 +179,7 @@ WORD wDefColor;           /* default color */
  * insert commas into a number
  */
 INT
-ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator)
+ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeparator)
 {
     TCHAR temp[39];   /* maximum length with nNumberGroups == 1 */
     UINT  n, iTarget;
@@ -193,11 +190,11 @@ ConvertULargeInteger(ULONGLONG num, LPTSTR des, UINT len, BOOL bPutSeperator)
     n = 0;
     iTarget = nNumberGroups;
     if (!nNumberGroups)
-        bPutSeperator = FALSE;
+        bPutSeparator = FALSE;
 
     do
     {
-        if (iTarget == n && bPutSeperator)
+        if (iTarget == n && bPutSeparator)
         {
             iTarget += nNumberGroups + 1;
             temp[38 - n++] = cThousandSeparator;
@@ -314,7 +311,7 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
 {
     TCHAR szFullName[MAX_PATH];
     TCHAR *first, *rest, *dot;
-    TCHAR szWindowTitle[MAX_PATH];
+    TCHAR szWindowTitle[MAX_PATH], szNewTitle[MAX_PATH*2];
     DWORD dwExitCode = 0;
     TCHAR *FirstEnd;
     TCHAR szFullCmdLine [CMDLINE_LENGTH];
@@ -322,7 +319,7 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
     TRACE ("Execute: \'%s\' \'%s\'\n", debugstr_aw(First), debugstr_aw(Rest));
 
     /* Though it was already parsed once, we have a different set of rules
-       for parsing before we pass to CreateProccess */
+       for parsing before we pass to CreateProcess */
     if (First[0] == _T('/') || (First[0] && First[1] == _T(':')))
     {
         /* Use the entire first word as the program name (no change) */
@@ -377,7 +374,11 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
         return 1;
     }
 
-    GetConsoleTitle (szWindowTitle, MAX_PATH);
+    /* Save the original console title and build a new one */
+    GetConsoleTitle(szWindowTitle, ARRAYSIZE(szWindowTitle));
+    bTitleSet = FALSE;
+    _stprintf(szNewTitle, _T("%s - %s%s"), szWindowTitle, First, Rest);
+    ConSetTitle(szNewTitle);
 
     /* check if this is a .BAT or .CMD file */
     dot = _tcsrchr (szFullName, _T('.'));
@@ -397,13 +398,13 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
         /* build command line for CreateProcess(): FullName + " " + rest */
         BOOL quoted = !!_tcschr(First, ' ');
         _tcscpy(szFullCmdLine, quoted ? _T("\"") : _T(""));
-        _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
-        _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
+        _tcsncat(szFullCmdLine, First, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
+        _tcsncat(szFullCmdLine, quoted ? _T("\"") : _T(""), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
 
         if (*rest)
         {
-            _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine));
-            _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine));
+            _tcsncat(szFullCmdLine, _T(" "), CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
+            _tcsncat(szFullCmdLine, rest, CMDLINE_LENGTH - _tcslen(szFullCmdLine) - 1);
         }
 
         TRACE ("[EXEC: %s]\n", debugstr_aw(szFullCmdLine));
@@ -443,8 +444,9 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
 
         if (prci.hProcess != NULL)
         {
-            if (IsConsoleProcess(prci.hProcess))
+            if (bc != NULL || bWaitForCommand || IsConsoleProcess(prci.hProcess))
             {
+                /* when processing a batch file or starting console processes: execute synchronously */
                 EnterCriticalSection(&ChildProcessRunningLock);
                 dwChildProcessId = prci.dwProcessId;
 
@@ -474,7 +476,10 @@ Execute(LPTSTR Full, LPTSTR First, LPTSTR Rest, PARSED_COMMAND *Cmd)
     /* Get code page if it has been changed */
     InputCodePage= GetConsoleCP();
     OutputCodePage = GetConsoleOutputCP();
-    SetConsoleTitle(szWindowTitle);
+
+    /* Restore the original console title */
+    if (!bTitleSet)
+        ConSetTitle(szWindowTitle);
 
     return dwExitCode;
 }
@@ -558,7 +563,7 @@ DoCommand(LPTSTR first, LPTSTR rest, PARSED_COMMAND *Cmd)
  * process the command line and execute the appropriate functions
  * full input/output redirection and piping are supported
  */
-INT ParseCommandLine (LPTSTR cmd)
+INT ParseCommandLine(LPTSTR cmd)
 {
     INT Ret = 0;
     PARSED_COMMAND *Cmd = ParseCommand(cmd);
@@ -584,7 +589,7 @@ ExecuteAsync(PARSED_COMMAND *Cmd)
     PROCESS_INFORMATION prci;
 
     /* Get the path to cmd.exe */
-    GetModuleFileName(NULL, CmdPath, MAX_PATH);
+    GetModuleFileName(NULL, CmdPath, ARRAYSIZE(CmdPath));
 
     /* Build the parameter string to pass to cmd.exe */
     ParamsEnd = _stpcpy(CmdParams, _T("/S/D/C\""));
@@ -1407,7 +1412,7 @@ ReadLine(TCHAR *commandline, BOOL bMore)
 }
 
 static VOID
-ProcessInput()
+ProcessInput(VOID)
 {
     PARSED_COMMAND *Cmd;
 
@@ -1480,15 +1485,15 @@ BOOL WINAPI BreakHandler(DWORD dwCtrlType)
 }
 
 
-VOID AddBreakHandler (VOID)
+VOID AddBreakHandler(VOID)
 {
-    SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, TRUE);
+    SetConsoleCtrlHandler(BreakHandler, TRUE);
 }
 
 
-VOID RemoveBreakHandler (VOID)
+VOID RemoveBreakHandler(VOID)
 {
-    SetConsoleCtrlHandler ((PHANDLER_ROUTINE)BreakHandler, FALSE);
+    SetConsoleCtrlHandler(BreakHandler, FALSE);
 }
 
 
@@ -1498,7 +1503,7 @@ VOID RemoveBreakHandler (VOID)
  */
 #if 0
 static VOID
-ShowCommands (VOID)
+ShowCommands(VOID)
 {
     /* print command list */
     ConOutResPuts(STRING_CMD_HELP1);
@@ -1526,14 +1531,164 @@ ShowCommands (VOID)
 }
 #endif
 
+
 static VOID
-ExecuteAutoRunFile(HKEY hkeyRoot)
+LoadRegistrySettings(HKEY hKeyRoot)
+{
+    LONG lRet;
+    HKEY hKey;
+    /*
+     * Buffer big enough to hold the string L"4294967295",
+     * corresponding to the literal 0xFFFFFFFF (MAX_ULONG) in decimal.
+     */
+    DWORD Buffer[6];
+    DWORD dwType, len;
+
+    lRet = RegOpenKeyEx(hKeyRoot,
+                        _T("Software\\Microsoft\\Command Processor"),
+                        0,
+                        KEY_QUERY_VALUE,
+                        &hKey);
+    if (lRet != ERROR_SUCCESS)
+        return;
+
+#ifdef INCLUDE_CMD_COLOR
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("DefaultColor"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default attributes */
+        if (dwType == REG_DWORD)
+            wDefColor = (WORD)*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            wDefColor = (WORD)_tcstol((PTSTR)Buffer, NULL, 0);
+    }
+    // else, use the default attributes retrieved before.
+#endif
+
+#if 0
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("DisableUNCCheck"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default setting */
+        if (dwType == REG_DWORD)
+            bDisableUNCCheck = !!*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            bDisableUNCCheck = (_ttol((PTSTR)Buffer) == 1);
+    }
+    // else, use the default setting set globally.
+#endif
+
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("DelayedExpansion"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default setting */
+        if (dwType == REG_DWORD)
+            bDelayedExpansion = !!*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            bDelayedExpansion = (_ttol((PTSTR)Buffer) == 1);
+    }
+    // else, use the default setting set globally.
+
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("EnableExtensions"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default setting */
+        if (dwType == REG_DWORD)
+            bEnableExtensions = !!*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            bEnableExtensions = (_ttol((PTSTR)Buffer) == 1);
+    }
+    // else, use the default setting set globally.
+
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("CompletionChar"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default setting */
+        if (dwType == REG_DWORD)
+            AutoCompletionChar = (TCHAR)*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            AutoCompletionChar = (TCHAR)_tcstol((PTSTR)Buffer, NULL, 0);
+    }
+    // else, use the default setting set globally.
+
+    /* Validity check */
+    if (IS_COMPLETION_DISABLED(AutoCompletionChar))
+    {
+        /* Disable autocompletion */
+        AutoCompletionChar = 0x20;
+    }
+
+    len = sizeof(Buffer);
+    lRet = RegQueryValueEx(hKey,
+                           _T("PathCompletionChar"),
+                           NULL,
+                           &dwType,
+                           (LPBYTE)&Buffer,
+                           &len);
+    if (lRet == ERROR_SUCCESS)
+    {
+        /* Overwrite the default setting */
+        if (dwType == REG_DWORD)
+            PathCompletionChar = (TCHAR)*(PDWORD)Buffer;
+        else if (dwType == REG_SZ)
+            PathCompletionChar = (TCHAR)_tcstol((PTSTR)Buffer, NULL, 0);
+    }
+    // else, use the default setting set globally.
+
+    /* Validity check */
+    if (IS_COMPLETION_DISABLED(PathCompletionChar))
+    {
+        /* Disable autocompletion */
+        PathCompletionChar = 0x20;
+    }
+
+    /* Adjust completion chars */
+    if (PathCompletionChar >= 0x20 && AutoCompletionChar < 0x20)
+        PathCompletionChar = AutoCompletionChar;
+    else if (AutoCompletionChar >= 0x20 && PathCompletionChar < 0x20)
+        AutoCompletionChar = PathCompletionChar;
+
+    RegCloseKey(hKey);
+}
+
+static VOID
+ExecuteAutoRunFile(HKEY hKeyRoot)
 {
     TCHAR autorun[2048];
     DWORD len = sizeof autorun;
     HKEY hkey;
 
-    if (RegOpenKeyEx(hkeyRoot,
+    if (RegOpenKeyEx(hKeyRoot,
                      _T("SOFTWARE\\Microsoft\\Command Processor"),
                      0,
                      KEY_READ,
@@ -1606,26 +1761,53 @@ GetCmdLineCommand(TCHAR *commandline, TCHAR *ptr, BOOL AlwaysStrip)
     _tcscpy(commandline, ptr);
 }
 
+
+#ifdef INCLUDE_CMD_COLOR
+
+BOOL ConGetDefaultAttributes(PWORD pwDefAttr)
+{
+    BOOL Success;
+    HANDLE hConsole;
+    CONSOLE_SCREEN_BUFFER_INFO csbi;
+
+    /* Do not modify *pwDefAttr if we fail, in which case use default attributes */
+
+    hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
+                          FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
+                          OPEN_EXISTING, 0, NULL);
+    if (hConsole == INVALID_HANDLE_VALUE)
+        return FALSE; // No default console
+
+    Success = GetConsoleScreenBufferInfo(hConsole, &csbi);
+    if (Success)
+        *pwDefAttr = csbi.wAttributes;
+
+    CloseHandle(hConsole);
+    return Success;
+}
+
+#endif
+
+
 /*
- * set up global initializations and process parameters
+ * Set up global initializations and process parameters
  */
 static VOID
-Initialize()
+Initialize(VOID)
 {
     HMODULE NtDllModule;
     TCHAR commandline[CMDLINE_LENGTH];
     TCHAR ModuleName[_MAX_PATH + 1];
-    TCHAR lpBuffer[2];
     INT nExitCode;
 
-    //INT len;
+    HANDLE hOut;
+
     TCHAR *ptr, *cmdLine, option = 0;
     BOOL AlwaysStrip = FALSE;
     BOOL AutoRun = TRUE;
 
-    /* get version information */
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    GetVersionEx (&osvi);
+    /* Get version information */
+    InitOSVersion();
 
     /* Some people like to run ReactOS cmd.exe on Win98, it helps in the
      * build process. So don't link implicitly against ntdll.dll, load it
@@ -1637,31 +1819,32 @@ Initialize()
         NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
     }
 
+    /* Load the registry settings */
+    LoadRegistrySettings(HKEY_LOCAL_MACHINE);
+    LoadRegistrySettings(HKEY_CURRENT_USER);
+
+    /* Initialize our locale */
     InitLocale();
 
-    /* get default input and output console handles */
+    /* Get default input and output console handles */
     hOut = GetStdHandle(STD_OUTPUT_HANDLE);
     hIn  = GetStdHandle(STD_INPUT_HANDLE);
 
-    /* Set EnvironmentVariable PROMPT if it does not exists any env value.
-       for you can change the EnvirommentVariable for prompt before cmd start
-       this patch are not 100% right, if it does not exists a PROMPT value cmd should use
-       $P$G as defualt not set EnvirommentVariable PROMPT to $P$G if it does not exists */
-    if (GetEnvironmentVariable(_T("PROMPT"),lpBuffer, sizeof(lpBuffer) / sizeof(lpBuffer[0])) == 0)
-        SetEnvironmentVariable(_T("PROMPT"), _T("$P$G"));
+    /* Initialize prompt support */
+    InitPrompt();
 
 #ifdef FEATURE_DIR_STACK
-    /* initialize directory stack */
-    InitDirectoryStack ();
+    /* Initialize directory stack */
+    InitDirectoryStack();
 #endif
 
 #ifdef FEATURE_HISTORY
-    /*initialize history*/
+    /* Initialize history */
     InitHistory();
 #endif
 
     /* Set COMSPEC environment variable */
-    if (0 != GetModuleFileName (NULL, ModuleName, _MAX_PATH + 1))
+    if (GetModuleFileName(NULL, ModuleName, ARRAYSIZE(ModuleName)) != 0)
     {
         ModuleName[_MAX_PATH] = _T('\0');
         SetEnvironmentVariable (_T("COMSPEC"), ModuleName);
@@ -1731,9 +1914,8 @@ Initialize()
 #ifdef INCLUDE_CMD_COLOR
             else if (!_tcsnicmp(ptr, _T("/T:"), 3))
             {
-                /* process /T (color) argument */
+                /* Process /T (color) argument; overwrite any previous settings */
                 wDefColor = (WORD)_tcstoul(&ptr[3], &ptr, 16);
-                SetScreenColor(wDefColor, FALSE);
             }
 #endif
             else if (option == _T('U'))
@@ -1742,17 +1924,48 @@ Initialize()
             }
             else if (option == _T('V'))
             {
+                // FIXME: Check validity of the parameter given to V !
                 bDelayedExpansion = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
             }
+            else if (option == _T('E'))
+            {
+                // FIXME: Check validity of the parameter given to E !
+                bEnableExtensions = _tcsnicmp(&ptr[2], _T(":OFF"), 4);
+            }
+            else if (option == _T('X'))
+            {
+                /* '/X' is identical to '/E:ON' */
+                bEnableExtensions = TRUE;
+            }
+            else if (option == _T('Y'))
+            {
+                /* '/Y' is identical to '/E:OFF' */
+                bEnableExtensions = FALSE;
+            }
         }
     }
 
+#ifdef INCLUDE_CMD_COLOR
+    if (wDefColor == 0)
+    {
+        /*
+         * If we still do not have the console colour attribute set,
+         * retrieve the default one.
+         */
+        ConGetDefaultAttributes(&wDefColor);
+    }
+
+    if (wDefColor != 0)
+        ConSetScreenColor(GetStdHandle(STD_OUTPUT_HANDLE), wDefColor, TRUE);
+#endif
+
     if (!*ptr)
     {
         /* If neither /C or /K was given, display a simple version string */
+        ConOutChar(_T('\n'));
         ConOutResPrintf(STRING_REACTOS_VERSION,
-            _T(KERNEL_RELEASE_STR),
-            _T(KERNEL_VERSION_BUILD_STR));
+                        _T(KERNEL_VERSION_STR),
+                        _T(KERNEL_VERSION_BUILD_STR));
         ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n"));
     }
 
@@ -1766,7 +1979,9 @@ Initialize()
     {
         /* Do the /C or /K command */
         GetCmdLineCommand(commandline, &ptr[2], AlwaysStrip);
+        bWaitForCommand = TRUE;
         nExitCode = ParseCommandLine(commandline);
+        bWaitForCommand = FALSE;
         if (option != _T('K'))
         {
             nErrorLevel = nExitCode;
@@ -1776,31 +1991,31 @@ Initialize()
 }
 
 
-static VOID Cleanup()
+static VOID Cleanup(VOID)
 {
-    /* run cmdexit.bat */
-    if (IsExistingFile (_T("cmdexit.bat")))
+    /* Run cmdexit.bat */
+    if (IsExistingFile(_T("cmdexit.bat")))
     {
         ConErrResPuts(STRING_CMD_ERROR5);
 
-        ParseCommandLine (_T("cmdexit.bat"));
+        ParseCommandLine(_T("cmdexit.bat"));
     }
-    else if (IsExistingFile (_T("\\cmdexit.bat")))
+    else if (IsExistingFile(_T("\\cmdexit.bat")))
     {
-        ConErrResPuts (STRING_CMD_ERROR5);
-        ParseCommandLine (_T("\\cmdexit.bat"));
+        ConErrResPuts(STRING_CMD_ERROR5);
+        ParseCommandLine(_T("\\cmdexit.bat"));
     }
 
-#ifdef FEATURE_DIECTORY_STACK
-    /* destroy directory stack */
-    DestroyDirectoryStack ();
+#ifdef FEATURE_DIRECTORY_STACK
+    /* Destroy directory stack */
+    DestroyDirectoryStack();
 #endif
 
 #ifdef FEATURE_HISTORY
     CleanHistory();
 #endif
 
-    /* free GetEnvVar's buffer */
+    /* Free GetEnvVar's buffer */
     GetEnvVar(NULL);
 
     /* Remove ctrl break handler */
@@ -1820,51 +2035,33 @@ static VOID Cleanup()
  */
 int _tmain(int argc, const TCHAR *argv[])
 {
-    HANDLE hConsole;
     TCHAR startPath[MAX_PATH];
-    CONSOLE_SCREEN_BUFFER_INFO Info;
 
     InitializeCriticalSection(&ChildProcessRunningLock);
     lpOriginalEnvironment = DuplicateEnvironment();
 
-    GetCurrentDirectory(MAX_PATH,startPath);
+    GetCurrentDirectory(ARRAYSIZE(startPath), startPath);
     _tchdir(startPath);
 
     SetFileApisToOEM();
-    InputCodePage = 0;
-    OutputCodePage = 0;
-
-    hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
-                          OPEN_EXISTING, 0, NULL);
-    if (hConsole != INVALID_HANDLE_VALUE)
-    {
-        if (!GetConsoleScreenBufferInfo(hConsole, &Info))
-        {
-            ConErrFormatMessage(GetLastError());
-            return(1);
-        }
-        wDefColor = Info.wAttributes;
-        CloseHandle(hConsole);
-    }
-
     InputCodePage = GetConsoleCP();
     OutputCodePage = GetConsoleOutputCP();
+
     CMD_ModuleHandle = GetModuleHandle(NULL);
 
-    /* check switches on command-line */
+    /* Perform general initialization, parse switches on command-line */
     Initialize();
 
-    /* call prompt routine */
+    /* Call prompt routine */
     ProcessInput();
 
-    /* do the cleanup */
+    /* Do the cleanup */
     Cleanup();
 
     cmd_free(lpOriginalEnvironment);
 
     cmd_exit(nErrorLevel);
-    return(nErrorLevel);
+    return nErrorLevel;
 }
 
 /* EOF */