Various improvements by Carl Nettelblad.
[reactos.git] / rosapps / cmd / cmd.c
index 4ace3a3..7d5c8c6 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id: cmd.c,v 1.24 2001/02/28 22:33:23 ekohl Exp $
+ *
  *  CMD.C - command-line interface.
  *
  *
  *
  *    27-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        Replaced spawnl() by CreateProcess().
+ *
+ *    22-Oct-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
+ *        Added break handler.
+ *
+ *    15-Dec-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
+ *        Fixed current directory
+ *
+ *    28-Dec-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
+ *        Restore window title after program/batch execution
+ *
+ *    03-Feb-2001 (Eric Kohl <ekohl@rz-online.de>)
+ *        Workaround because argc[0] is NULL under ReactOS
+ *
+ *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
+ *        %envvar% replacement conflicted with for.
  */
 
 #include "config.h"
 #include "batch.h"
 
 
-#define CMDLINE_LENGTH  512
-
-
 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; /* Ignore 'newline' before 'cls' */
 INT  nErrorLevel = 0;     /* Errorlevel of last launched external program */
+BOOL bChildProcessRunning = FALSE;
+DWORD dwChildProcessId = 0;
 OSVERSIONINFO osvi;
 HANDLE hIn;
 HANDLE hOut;
 
 #ifdef INCLUDE_CMD_COLOR
-WORD wColor = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN; /* current color */
-WORD wDefColor = FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_GREEN; /* default color */
+WORD wColor;              /* current color */
+WORD wDefColor;           /* default color */
 #endif
 
 
-extern COMMAND cmds[];         /* The internal command table */
-
-
 /*
  *  is character a delimeter when used on first word?
  *
@@ -161,14 +173,49 @@ static VOID
 Execute (LPTSTR first, LPTSTR rest)
 {
        TCHAR szFullName[MAX_PATH];
+#ifndef __REACTOS__
+       TCHAR szWindowTitle[MAX_PATH];
+#endif
+       DWORD dwExitCode = 0;
+
+#ifdef _DEBUG
+       DebugPrintf ("Execute: \'%s\' \'%s\'\n", first, rest);
+#endif
 
        /* check for a drive change */
-       if (!_tcscmp (first + 1, _T(":")) && _istalpha (*first))
+       if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
        {
                TCHAR szPath[MAX_PATH];
+               TCHAR szVar[5];
+
+#ifdef _DEBUG
+               DebugPrintf ("Drive change to drive %s\n", first);
+#endif
+               /* save curent directory in environment variable */
+               GetCurrentDirectory (MAX_PATH, szPath);
+
+               _tcscpy (szVar, _T("=A:"));
+               szVar[1] = _totupper (szPath[0]);
 
-               _tcscpy (szPath, _T("A:"));
-               szPath[0] = _totupper (*first);
+               SetEnvironmentVariable (szVar, szPath);
+
+
+               /* check for current directory of new drive */
+               _tcscpy (szVar, _T("=A:"));
+               szVar[1] = _totupper (*first);
+
+               if (GetEnvironmentVariable (szVar, szPath, MAX_PATH) == 0)
+               {
+                       /* no environment variable found */
+                       _tcscpy (szPath, _T("A:\\"));
+                       szPath[0] = _totupper (*first);
+               }
+
+#ifdef _DEBUG
+               DebugPrintf ("Drive change to drive %s\n", szPath);
+#endif
+
+               /* set new current directory */
                SetCurrentDirectory (szPath);
                GetCurrentDirectory (MAX_PATH, szPath);
                if (szPath[0] != (TCHAR)_totupper (*first))
@@ -185,6 +232,10 @@ Execute (LPTSTR first, LPTSTR rest)
                return;
        }
 
+#ifndef __REACTOS__
+       GetConsoleTitle (szWindowTitle, MAX_PATH);
+#endif
+
        /* check if this is a .BAT or .CMD file */
        if (!_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".bat")) ||
                !_tcsicmp (_tcsrchr (szFullName, _T('.')), _T(".cmd")))
@@ -197,30 +248,61 @@ Execute (LPTSTR first, LPTSTR rest)
        else
        {
                /* exec the program */
-               TCHAR szFullCmdLine [1024];
+#ifndef __REACTOS__
+               TCHAR szFullCmdLine [CMDLINE_LENGTH];
+#endif
                PROCESS_INFORMATION prci;
                STARTUPINFO stui;
-//                DWORD dwError = 0;
 
 #ifdef _DEBUG
                DebugPrintf ("[EXEC: %s %s]\n", szFullName, rest);
 #endif
+#ifndef __REACTOS__
                /* build command line for CreateProcess() */
                _tcscpy (szFullCmdLine, szFullName);
                _tcscat (szFullCmdLine, _T(" "));
                _tcscat (szFullCmdLine, rest);
+#endif
 
                /* fill startup info */
                memset (&stui, 0, sizeof (STARTUPINFO));
                stui.cb = sizeof (STARTUPINFO);
                stui.dwFlags = STARTF_USESHOWWINDOW;
                stui.wShowWindow = SW_SHOWDEFAULT;
-                       
-               if (CreateProcess (NULL, szFullCmdLine, NULL, NULL, FALSE,
-                                                  0, NULL, NULL, &stui, &prci))
+
+#ifndef __REACTOS__
+               if (CreateProcess (NULL,
+                                  szFullCmdLine,
+                                  NULL,
+                                  NULL,
+                                  FALSE,
+                                  CREATE_NEW_PROCESS_GROUP,
+                                  NULL,
+                                  NULL,
+                                  &stui,
+                                  &prci))
+#else
+               if (CreateProcess (szFullName,
+                                  rest,
+                                  NULL,
+                                  NULL,
+                                  FALSE,
+                                  0,
+                                  NULL,
+                                  NULL,
+                                  &stui,
+                                  &prci))
+#endif
                {
-                       DWORD dwExitCode;
+                       /* FIXME: Protect this with critical section */
+                       bChildProcessRunning = TRUE;
+                       dwChildProcessId = prci.dwProcessId;
+
                        WaitForSingleObject (prci.hProcess, INFINITE);
+
+                       /* FIXME: Protect this with critical section */
+                       bChildProcessRunning = TRUE;
+
                        GetExitCodeProcess (prci.hProcess, &dwExitCode);
                        nErrorLevel = (INT)dwExitCode;
                        CloseHandle (prci.hThread);
@@ -229,9 +311,13 @@ Execute (LPTSTR first, LPTSTR rest)
                else
                {
                        ErrorMessage (GetLastError (),
-                                                 "Error executing CreateProcess()!!\n");
+                                     "Error executing CreateProcess()!!\n");
                }
        }
+
+#ifndef __REACTOS__
+       SetConsoleTitle (szWindowTitle);
+#endif
 }
 
 
@@ -254,6 +340,10 @@ DoCommand (LPTSTR line)
        INT cl;
        LPCOMMAND cmdptr;
 
+#ifdef _DEBUG
+       DebugPrintf ("DoCommand: (\'%s\')\n", line);
+#endif /* DEBUG */
+
        /* Skip over initial white space */
        while (isspace (*rest))
                rest++;
@@ -324,8 +414,10 @@ DoCommand (LPTSTR line)
  * full input/output redirection and piping are supported
  */
 
-VOID ParseCommandLine (LPTSTR s)
+VOID ParseCommandLine (LPTSTR cmd)
 {
+       TCHAR cmdline[CMDLINE_LENGTH];
+       LPTSTR s;
 #ifdef FEATURE_REDIRECTION
        TCHAR in[CMDLINE_LENGTH] = "";
        TCHAR out[CMDLINE_LENGTH] = "";
@@ -342,9 +434,12 @@ VOID ParseCommandLine (LPTSTR s)
        HANDLE hOldConErr;
 #endif /* FEATURE_REDIRECTION */
 
+       _tcscpy (cmdline, cmd);
+       s = &cmdline[0];
+
 #ifdef _DEBUG
-       DebugPrintf ("ParseCommandLine: (\'%s\')]\n", s);
-#endif /* _DEBUG */
+       DebugPrintf ("ParseCommandLine: (\'%s\')\n", s);
+#endif /* DEBUG */
 
 #ifdef FEATURE_ALIASES
        /* expand all aliases */
@@ -385,7 +480,7 @@ VOID ParseCommandLine (LPTSTR s)
                HANDLE hFile;
 
                hFile = CreateFile (in, GENERIC_READ, 0, NULL, OPEN_EXISTING,
-                                                       FILE_ATTRIBUTE_NORMAL, NULL);
+                                   FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
                        ConErrPrintf ("Can't redirect input from file %s\n", in);
@@ -413,7 +508,7 @@ VOID ParseCommandLine (LPTSTR s)
 
                /* Set current stdout to temporary file */
                hFile[1] = CreateFile (szFileName[1], GENERIC_WRITE, 0, NULL,
-                                                          TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
+                                      TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
                SetStdHandle (STD_OUTPUT_HANDLE, hFile[1]);
 
                DoCommand (s);
@@ -443,7 +538,7 @@ VOID ParseCommandLine (LPTSTR s)
 
                /* open new stdin file */
                hFile[0] = CreateFile (szFileName[0], GENERIC_READ, 0, NULL,
-                                                          OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
+                                      OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
                SetStdHandle (STD_INPUT_HANDLE, hFile[0]);
 
                s = s + _tcslen (s) + 1;
@@ -457,8 +552,8 @@ VOID ParseCommandLine (LPTSTR s)
                HANDLE hFile;
 
                hFile = CreateFile (out, GENERIC_WRITE, 0, NULL,
-                                                       (nRedirFlags & OUTPUT_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
-                                                       FILE_ATTRIBUTE_NORMAL, NULL);
+                                   (nRedirFlags & OUTPUT_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
+                                   FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
                        ConErrPrintf ("Can't redirect to file %s\n", out);
@@ -503,15 +598,20 @@ VOID ParseCommandLine (LPTSTR s)
 #ifdef _DEBUG
                        DebugPrintf (_T("Stdout and stderr will use the same file!!\n"));
 #endif
-                       DuplicateHandle (GetCurrentProcess (), GetStdHandle (STD_OUTPUT_HANDLE), GetCurrentProcess (),
-                                                        &hFile, 0, TRUE, DUPLICATE_SAME_ACCESS);
+                       DuplicateHandle (GetCurrentProcess (),
+                                        GetStdHandle (STD_OUTPUT_HANDLE),
+                                        GetCurrentProcess (),
+                                        &hFile, 0, TRUE, DUPLICATE_SAME_ACCESS);
                }
                else
                {
-                       hFile =
-                               CreateFile (err, GENERIC_WRITE, 0, NULL,
-                                                       (nRedirFlags & ERROR_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
-                                                       FILE_ATTRIBUTE_NORMAL, NULL);
+                       hFile = CreateFile (err,
+                                           GENERIC_WRITE,
+                                           0,
+                                           NULL,
+                                           (nRedirFlags & ERROR_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
+                                           FILE_ATTRIBUTE_NORMAL,
+                                           NULL);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
                                ConErrPrintf ("Can't redirect to file %s\n", err);
@@ -607,7 +707,6 @@ VOID ParseCommandLine (LPTSTR s)
 #ifdef _DEBUG
                                        DebugPrintf (_T("hFile[0] and hIn dont match!!!\n"));
 #endif
-
                                }
                        }
                }
@@ -650,8 +749,6 @@ ProcessInput (BOOL bFlag)
        LPTSTR tp;
        LPTSTR ip;
        LPTSTR cp;
-
-       /* JPP 19980807 - changed name so not to conflict with echo global */
        BOOL bEchoThisLine;
 
        do
@@ -698,12 +795,12 @@ ProcessInput (BOOL bFlag)
                                                break;
 
                                        case _T('?'):
-                                                cp += _stprintf (cp, _T("%u"), nErrorLevel);
+                                               cp += _stprintf (cp, _T("%u"), nErrorLevel);
                                                ip++;
                                                break;
 
                                        default:
-                                               if ((tp = _tcschr (ip, _T('%'))))
+                                               if ((tp = _tcschr (ip, _T('%'))) && (tp<=(unsigned int)strchr(ip,_T(' '))-1))
                                                {
                                                        char evar[512];
                                                        *tp = _T('\0');
@@ -715,6 +812,10 @@ ProcessInput (BOOL bFlag)
 
                                                        ip = tp + 1;
                                                }
+                                               else
+                                               {
+                                                       *cp++ = _T('%');
+                                               }
                                                break;
                                }
                                continue;
@@ -728,8 +829,7 @@ ProcessInput (BOOL bFlag)
                *cp = _T('\0');
 
                /* strip trailing spaces */
-               while ((--cp >= commandline) && _istspace (*cp))
-                       ;
+               while ((--cp >= commandline) && _istspace (*cp));
 
                *(cp + 1) = _T('\0');
 
@@ -760,13 +860,40 @@ ProcessInput (BOOL bFlag)
  */
 BOOL BreakHandler (DWORD dwCtrlType)
 {
-       if ((dwCtrlType == CTRL_C_EVENT) ||
-               (dwCtrlType == CTRL_BREAK_EVENT))
+       if ((dwCtrlType != CTRL_C_EVENT) &&
+           (dwCtrlType != CTRL_BREAK_EVENT))
+               return FALSE;
+
+       if (bChildProcessRunning == TRUE)
        {
-               bCtrlBreak = TRUE; /* indicate the break condition */
+               GenerateConsoleCtrlEvent (CTRL_C_EVENT,
+                                         dwChildProcessId);
                return TRUE;
        }
-       return FALSE;
+
+       /* FIXME: Handle batch files */
+
+       /* FIXME: Print "^C" */
+
+
+       return TRUE;
+}
+
+
+VOID AddBreakHandler (VOID)
+{
+#ifndef __REACTOS__
+       SetConsoleCtrlHandler ((PHANDLER_ROUTINE)&BreakHandler,
+                              TRUE);
+#endif
+}
+
+
+VOID RemoveBreakHandler (VOID)
+{
+#ifndef __REACTOS__
+       SetConsoleCtrlHandler (NULL, FALSE);
+#endif
 }
 
 
@@ -777,27 +904,9 @@ BOOL BreakHandler (DWORD dwCtrlType)
 static VOID
 ShowCommands (VOID)
 {
-       LPCOMMAND cmdptr;
-       INT y;
-
+       /* print command list */
        ConOutPrintf (_T("\nInternal commands available:\n"));
-       y = 0;
-       cmdptr = cmds;
-       while (cmdptr->name)
-       {
-               if (++y == 8)
-               {
-                       ConOutPuts (cmdptr->name);
-                       y = 0;
-               }
-               else
-                       ConOutPrintf (_T("%-10s"), cmdptr->name);
-
-               cmdptr++;
-       }
-
-       if (y != 0)
-               ConOutChar ('\n');
+       PrintCommandList ();
 
        /* print feature list */
        ConOutPuts ("\nFeatures available:");
@@ -816,7 +925,7 @@ ShowCommands (VOID)
 #ifdef FEATURE_REDIRECTION
        ConOutPuts ("  [redirections and piping]");
 #endif
-        ConOutChar ('\n');
+       ConOutChar ('\n');
 }
 
 
@@ -827,13 +936,12 @@ ShowCommands (VOID)
  * argv - command-line parameters
  *
  */
-static VOID Initialize (int argc, char *argv[])
+static VOID
+Initialize (int argc, char *argv[])
 {
+       TCHAR commandline[CMDLINE_LENGTH];
        INT i;
 
-       /* Added by Rob Lake 06/16/98.  This enables the command.com
-        * to run the autoexec.bat at startup */
-
 #ifdef _DEBUG
        INT x;
 
@@ -846,106 +954,196 @@ static VOID Initialize (int argc, char *argv[])
 #endif
 
        /* get version information */
-    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-    GetVersionEx (&osvi);
+       osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+       GetVersionEx (&osvi);
 
-    InitLocale ();
+       InitLocale ();
 
        /* get default input and output console handles */
        hOut = GetStdHandle (STD_OUTPUT_HANDLE);
        hIn  = GetStdHandle (STD_INPUT_HANDLE);
 
+       SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
+
+       if (argc >= 2 && !_tcsncmp (argv[1], _T("/?"), 2))
+       {
+               ConOutPuts (_T("Starts a new instance of the ReactOS command line interpreter.\n"
+                              "\n"
+                              "CMD [/[C|K] command][/P][/Q][/T:bf]\n"
+                              "\n"
+                              "  /C command  Runs the specified command and terminates.\n"
+                              "  /K command  Runs the specified command and remains.\n"
+                              "  /P          CMD becomes permanent and runs autoexec.bat\n"
+                              "              (cannot be terminated).\n"
+                              "  /T:bf       Sets the background/foreground color (see COLOR command)."));
+               ExitProcess (0);
+       }
+
 #ifdef INCLUDE_CMD_CHDIR
        InitLastPath ();
 #endif
 
-    if (argc >= 2)
+#ifdef FATURE_ALIASES
+       InitializeAlias ();
+#endif
+
+       if (argc >= 2)
        {
-               if (!_tcsncmp (argv[1], _T("/?"), 2))
+               for (i = 1; i < argc; i++)
                {
-                       ConOutPuts (_T("Starts a new instance of the ReactOS command line interpreter\n\n"
-                                                  "CMD [/P][/C]...\n\n"
-                                                  "  /P  ...\n"
-                                                  "  /C  ..."));
-                       ExitProcess (0);
-               }
-               else
-               {
-                       for (i = 1; i < argc; i++)
+                       if (!_tcsicmp (argv[i], _T("/p")))
                        {
-                               if (!_tcsicmp (argv[i], _T("/p")))
+                               if (!IsValidFileName (_T("\\autoexec.bat")))
                                {
-                                       if (!IsValidFileName (_T("\\autoexec.bat")))
-                                       {
 #ifdef INCLUDE_CMD_DATE
-                                               cmd_date ("", "");
+                                       cmd_date ("", "");
 #endif
 #ifdef INCLUDE_CMD_TIME
-                                               cmd_time ("", "");
+                                       cmd_time ("", "");
 #endif
-                                       }
-                                       else
-                                               ParseCommandLine ("\\autoexec.bat");
-                                       bCanExit = FALSE;
                                }
-                               else if (!_tcsicmp (argv[i], _T("/c")))
+                               else
+                               {
+                                       ParseCommandLine (_T("\\autoexec.bat"));
+                               }
+                               bCanExit = FALSE;
+                       }
+                       else if (!_tcsicmp (argv[i], _T("/c")))
+                       {
+                               /* This just runs a program and exits */
+                               ++i;
+                               if (argv[i])
                                {
-                                       /* This just runs a program and exits, RL: 06/16,21/98 */
-                                       char commandline[CMDLINE_LENGTH];
-                                       ++i;
-                                       strcpy(commandline, argv[i]);
+                                       _tcscpy (commandline, argv[i]);
                                        while (argv[++i])
                                        {
-                                               strcat(commandline, " ");
-                                               strcat(commandline, argv[i]);
+                                               _tcscat (commandline, " ");
+                                               _tcscat (commandline, argv[i]);
                                        }
 
                                        ParseCommandLine(commandline);
-
-                                       /* HBP_003 { Fix return value when /C used }*/
                                        ExitProcess (ProcessInput (TRUE));
                                }
-
-#ifdef INCLUDE_CMD_COLOR
-                               else if (!_tcsnicmp (argv[i], _T("/t:"), 3))
+                               else
                                {
-                                       /* process /t (color) argument */
-                                       wDefColor = (WORD)strtoul (&argv[i][3], NULL, 16);
-                                       wColor = wDefColor;
+                                       ExitProcess (0);
                                }
-#endif
                        }
+                       else if (!_tcsicmp (argv[i], _T("/k")))
+                       {
+                               /* This just runs a program and remains */
+                               ++i;
+                               if (argv[i])
+                               {
+                                       _tcscpy (commandline, argv[i]);
+                                       while (argv[++i])
+                                       {
+                                               _tcscat (commandline, " ");
+                                               _tcscat (commandline, argv[i]);
+                                       }
+
+                                       ParseCommandLine(commandline);
+                               }
+                       }
+#ifdef INCLUDE_CMD_COLOR
+                       else if (!_tcsnicmp (argv[i], _T("/t:"), 3))
+                       {
+                               /* process /t (color) argument */
+                               wDefColor = (WORD)strtoul (&argv[i][3], NULL, 16);
+                               wColor = wDefColor;
+                               SetScreenColor (wColor, TRUE);
+                       }
+#endif
                }
        }
 
+       ShortVersion ();
+       ShowCommands ();
+
+       /* run cmdstart.bat */
+       if (IsValidFileName (_T("cmdstart.bat")))
+       {
+               ParseCommandLine (_T("cmdstart.bat"));
+       }
+       else if (IsValidFileName (_T("\\cmdstart.bat")))
+       {
+               ParseCommandLine (_T("\\cmdstart.bat"));
+       }
+#ifndef __REACTOS__
+       else
+       {
+               /* try to run cmdstart.bat from install dir */
+               LPTSTR p;
+
+               _tcscpy (commandline, argv[0]);
+               p = _tcsrchr (commandline, _T('\\')) + 1;
+               _tcscpy (p, _T("cmdstart.bat"));
+
+               if (IsValidFileName (_T("commandline")))
+               {
+                       ConErrPrintf ("Running %s...\n", commandline);
+                       ParseCommandLine (commandline);
+               }
+       }
+#endif
+
 #ifdef FEATURE_DIR_STACK
        /* initialize directory stack */
        InitDirectoryStack ();
 #endif
 
-#ifdef INCLUDE_CMD_COLOR
-       /* set default colors */
-       SetScreenColor (wColor);
-#endif
 
-       ShortVersion ();
-       ShowCommands ();
+#ifdef FEATURE_HISTORY
+       /*initialize history*/
+       InitHistory();
+#endif
 
        /* Set COMSPEC environment variable */
 #ifndef __REACTOS__
-        if (argv)
-                SetEnvironmentVariable (_T("COMSPEC"), argv[0]);
+       if (argv)
+               SetEnvironmentVariable (_T("COMSPEC"), argv[0]);
 #endif
 
-       /* add ctrl handler */
-#if 0
-       SetConsoleCtrlHandler (NULL, TRUE);
-#endif
+       /* add ctrl break handler */
+       AddBreakHandler ();
 }
 
 
-static VOID Cleanup (VOID)
+static VOID Cleanup (int argc, char *argv[])
 {
+       /* run cmdexit.bat */
+       if (IsValidFileName (_T("cmdexit.bat")))
+       {
+               ConErrPrintf ("Running cmdexit.bat...\n");
+               ParseCommandLine (_T("cmdexit.bat"));
+       }
+       else if (IsValidFileName (_T("\\cmdexit.bat")))
+       {
+               ConErrPrintf ("Running \\cmdexit.bat...\n");
+               ParseCommandLine (_T("\\cmdexit.bat"));
+       }
+#ifndef __REACTOS__
+       else
+       {
+               /* try to run cmdexit.bat from install dir */
+               TCHAR commandline[CMDLINE_LENGTH];
+               LPTSTR p;
+
+               _tcscpy (commandline, argv[0]);
+               p = _tcsrchr (commandline, _T('\\')) + 1;
+               _tcscpy (p, _T("cmdexit.bat"));
+
+               if (IsValidFileName (_T("commandline")))
+               {
+                       ConErrPrintf ("Running %s...\n", commandline);
+                       ParseCommandLine (commandline);
+               }
+       }
+#endif
+
+#ifdef FEATURE_ALIASES
+       DestroyAlias ();
+#endif
 
 #ifdef FEATURE_DIECTORY_STACK
        /* destroy directory stack */
@@ -956,10 +1154,13 @@ static VOID Cleanup (VOID)
        FreeLastPath ();
 #endif
 
-       /* remove ctrl handler */
-#if 0
-    SetConsoleCtrlHandler ((PHANDLER_ROUTINE)&BreakHandler, FALSE);
+#ifdef FEATURE_HISTORY 
+       CleanHistory();
 #endif
+
+
+       /* remove ctrl break handler */
+       RemoveBreakHandler ();
 }
 
 
@@ -969,26 +1170,26 @@ static VOID Cleanup (VOID)
 int main (int argc, char *argv[])
 {
        INT nExitCode;
+       CONSOLE_SCREEN_BUFFER_INFO Info;
 
        AllocConsole ();
-#ifndef __REACTOS__
-        SetFileApisToOEM ();
-#endif
-
-#ifdef __REACTOS__
-        SetCurrentDirectory (_T("C:\\"));
-#endif
+       SetFileApisToOEM ();
 
+       if( GetConsoleScreenBufferInfo( GetStdHandle( STD_OUTPUT_HANDLE ), &Info ) == FALSE )
+          printf( "GetConsoleScreenBufferInfo: Error: %ld\n", GetLastError() );
+       wColor = Info.wAttributes;
+       wDefColor = wColor;
        /* check switches on command-line */
        Initialize (argc, argv);
 
        /* call prompt routine */
-        nExitCode = ProcessInput (FALSE);
+       nExitCode = ProcessInput (FALSE);
 
        /* do the cleanup */
-        Cleanup ();
-        FreeConsole ();
+       Cleanup (argc, argv);
+       FreeConsole ();
 
-        return nExitCode;
-//        return 0;
+       return nExitCode;
 }
+
+/* EOF */