Correctly assign %propmt%.
[reactos.git] / reactos / subsys / system / cmd / cmd.c
index aa697fa..ec01e36 100644 (file)
  *    12-Jul-2004 (Jens Collin <jens.collin@lakhei.com>)
  *       Added ShellExecute call when all else fails to be able to "launch" any file.
  *
- *    02-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
- *        Remove all hardcode string to En.rc  
+ *    02-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc
+ *
+ *    06-May-2005 (Klemens Friedl <frik85@gmail.com>)
+ *        Add 'help' command (list all commands plus description)
+ *
+ *    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
  */
 
-#include "precomp.h"
+#include <precomp.h>
 #include "resource.h"
 
 #ifndef NT_SUCCESS
@@ -155,10 +163,11 @@ OSVERSIONINFO osvi;
 HANDLE hIn;
 HANDLE hOut;
 HANDLE hConsole;
+HANDLE CMD_ModuleHandle;
+HMODULE NtDllModule;
 
-static NtQueryInformationProcessProc NtQueryInformationProcessPtr;
-static NtReadVirtualMemoryProc       NtReadVirtualMemoryPtr;
-static BOOL NtDllChecked = FALSE;
+static NtQueryInformationProcessProc NtQueryInformationProcessPtr = NULL;
+static NtReadVirtualMemoryProc       NtReadVirtualMemoryPtr = NULL;
 
 #ifdef INCLUDE_CMD_COLOR
 WORD wColor;              /* current color */
@@ -184,28 +193,6 @@ static BOOL IsConsoleProcess(HANDLE Process)
        PROCESS_BASIC_INFORMATION Info;
        PEB ProcessPeb;
        ULONG BytesRead;
-       HMODULE NtDllModule;
-
-       /* 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
-           dynamically instead */
-       if (! NtDllChecked)
-       {
-               NtDllChecked = TRUE;
-               NtDllModule = LoadLibrary(_T("ntdll.dll"));
-               if (NULL == NtDllModule)
-               {
-                       /* Probably non-WinNT system. Just wait for the commands
-                           to finish. */
-                       NtQueryInformationProcessPtr = NULL;
-                       NtReadVirtualMemoryPtr = NULL;
-                       return TRUE;
-               }
-               NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)
-                                               GetProcAddress(NtDllModule, "NtQueryInformationProcess");
-               NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)
-                                        GetProcAddress(NtDllModule, "NtReadVirtualMemory");
-       }
 
        if (NULL == NtQueryInformationProcessPtr || NULL == NtReadVirtualMemoryPtr)
        {
@@ -300,14 +287,18 @@ static BOOL RunFile(LPTSTR filename)
 /*
  * This command (in first) was not found in the command table
  *
- * first - first word on command line
- * rest  - rest of command line
+ * Full  - whole command line
+ * First - first word on command line
+ * Rest  - rest of command line
  */
 
 static VOID
-Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
+Execute (LPTSTR Full, LPTSTR First, LPTSTR Rest)
 {
        TCHAR szFullName[MAX_PATH];
+       TCHAR first[CMDLINE_LENGTH];
+       TCHAR rest[CMDLINE_LENGTH];
+       TCHAR full[CMDLINE_LENGTH];
 #ifndef __REACTOS__
        TCHAR szWindowTitle[MAX_PATH];
 #endif
@@ -317,6 +308,51 @@ Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
        DebugPrintf (_T("Execute: \'%s\' \'%s\'\n"), first, rest);
 #endif
 
+       /* Though it was already parsed once, we have a different set of rules
+          for parsing before we pass to CreateProccess */
+       if(!_tcschr(Full,_T('\"')))
+       {
+               _tcscpy(first,First);
+               _tcscpy(rest,Rest);
+               _tcscpy(full,Full);
+       }
+       else
+       {
+               INT i = 0;              
+               BOOL bInside = FALSE;
+               rest[0] = _T('\0');
+               full[0] = _T('\0');
+               first[0] = _T('\0');
+               _tcscpy(first,Full);
+               /* find the end of the command and start of the args */
+               for(i = 0; i < _tcslen(first); i++)
+               {
+                       if(!_tcsncmp(&first[i], _T("\""), 1))
+                               bInside = !bInside;
+                       if(!_tcsncmp(&first[i], _T(" "), 1) && !bInside)
+                       {
+                               _tcscpy(rest,&first[i]);
+                               first[i] = _T('\0');
+                               break;
+                       }
+
+               }
+               i = 0;
+               /* remove any slashes */
+               while(i < _tcslen(first))
+               {
+                       if(first[i] == _T('\"'))
+                               memmove(&first[i],&first[i + 1], _tcslen(&first[i]) * sizeof(TCHAR));
+                       else
+                               i++;
+               }
+               /* Drop quotes around it just in case there is a space */
+               _tcscpy(full,_T("\""));
+               _tcscat(full,first);
+               _tcscat(full,_T("\" "));
+               _tcscat(full,rest);
+       }
+
        /* check for a drive change */
        if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
        {
@@ -332,7 +368,7 @@ Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
                        working = SetCurrentDirectory(str);
                }
 
-               if (!working) ConErrPuts (INVALIDDRIVE);
+               if (!working) ConErrResPuts (STRING_FREE_ERROR1);
 
                return;
        }
@@ -567,7 +603,7 @@ VOID ParseCommandLine (LPTSTR cmd)
        INT  nRedirFlags = 0;
        INT  Length;
        UINT Attributes;
-
+       BOOL bNewBatch = TRUE;
        HANDLE hOldConIn;
        HANDLE hOldConOut;
        HANDLE hOldConErr;
@@ -620,6 +656,20 @@ VOID ParseCommandLine (LPTSTR cmd)
                ;
        _tcscpy (err, t);
 
+       if(bc && !_tcslen (in) && _tcslen (bc->In))
+               _tcscpy(in, bc->In);
+       if(bc && !out[0] && _tcslen(bc->Out))
+       {
+               nRedirFlags |= OUTPUT_APPEND;
+               _tcscpy(out, bc->Out);
+       }
+       if(bc && !_tcslen (err) && _tcslen (bc->Err))
+       {
+               nRedirFlags |= ERROR_APPEND;
+               _tcscpy(err, bc->Err);
+       }
+               
+
        /* Set up the initial conditions ... */
        /* preserve STDIN, STDOUT and STDERR handles */
        hOldConIn  = GetStdHandle (STD_INPUT_HANDLE);
@@ -632,18 +682,22 @@ VOID ParseCommandLine (LPTSTR cmd)
                HANDLE hFile;
                SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
 
+    /* we need make sure the LastError msg is zero before calling CreateFile */
+               SetLastError(0); 
+
+    /* Set up pipe for the standard input handler */
                hFile = CreateFile (in, GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING,
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, in);
                        return;
                }
 
                if (!SetStdHandle (STD_INPUT_HANDLE, hFile))
-               {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
+               {      
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, in);
                        return;
                }
@@ -659,16 +713,20 @@ VOID ParseCommandLine (LPTSTR cmd)
        while (num-- > 1)
        {
                SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
-
-               /* Create unique temporary file name */
+    
+    /* Create unique temporary file name */
                GetTempFileName (szTempPath, _T("CMD"), 0, szFileName[1]);
 
+    /* we need make sure the LastError msg is zero before calling CreateFile */
+                SetLastError(0); 
+
                /* Set current stdout to temporary file */
                hFile[1] = CreateFile (szFileName[1], GENERIC_WRITE, 0, &sa,
                                       TRUNCATE_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
-               if (hFile[1] == INVALID_HANDLE_VALUE)
-               {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR2, szMsg, RC_STRING_MAX_SIZE);
+               
+    if (hFile[1] == INVALID_HANDLE_VALUE)
+               {            
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR2, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg);
                        return;
                }
@@ -700,6 +758,9 @@ VOID ParseCommandLine (LPTSTR cmd)
                _tcscpy (szFileName[0], szFileName[1]);
                *szFileName[1] = _T('\0');
 
+    /* we need make sure the LastError msg is zero before calling CreateFile */
+               SetLastError(0); 
+
                /* open new stdin file */
                hFile[0] = CreateFile (szFileName[0], GENERIC_READ, 0, &sa,
                                       OPEN_EXISTING, FILE_ATTRIBUTE_TEMPORARY, NULL);
@@ -715,20 +776,42 @@ VOID ParseCommandLine (LPTSTR cmd)
                /* Final output to here */
                HANDLE hFile;
                SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};
+               
+    /* we need make sure the LastError msg is zero before calling CreateFile */
+               SetLastError(0); 
 
-               hFile = CreateFile (out, GENERIC_WRITE, FILE_SHARE_READ, &sa,
+    hFile = CreateFile (out, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, &sa,
                                    (nRedirFlags & OUTPUT_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
-                                   FILE_ATTRIBUTE_NORMAL, NULL);
-               if (hFile == INVALID_HANDLE_VALUE)
+                                   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
+               
+    if (hFile == INVALID_HANDLE_VALUE)
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
-                       ConErrPrintf(szMsg, out);
-                       return;
+      INT size = _tcslen(out)-1;
+      
+      if (out[size] != _T(':'))
+      {
+                          LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                          ConErrPrintf(szMsg, out);
+                          return;
+      }
+      
+      out[size]=_T('\0');
+      hFile = CreateFile (out, GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, &sa,
+                                   (nRedirFlags & OUTPUT_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
+                                   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
+
+     if (hFile == INVALID_HANDLE_VALUE)
+     {
+                          LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                          ConErrPrintf(szMsg, out);
+                          return;
+      }
+      
                }
 
                if (!SetStdHandle (STD_OUTPUT_HANDLE, hFile))
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, out);
                        return;
                }
@@ -775,14 +858,14 @@ VOID ParseCommandLine (LPTSTR cmd)
                {
                        hFile = CreateFile (err,
                                            GENERIC_WRITE,
-                                           0,
+                                           FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
                                            &sa,
                                            (nRedirFlags & ERROR_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
-                                           FILE_ATTRIBUTE_NORMAL,
+                                           FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
                                            NULL);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
-                               LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                               LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
                                ConErrPrintf(szMsg, err);
                                return;
                        }
@@ -790,7 +873,7 @@ VOID ParseCommandLine (LPTSTR cmd)
 
                if (!SetStdHandle (STD_ERROR_HANDLE, hFile))
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, err);
                        return;
                }
@@ -815,12 +898,17 @@ VOID ParseCommandLine (LPTSTR cmd)
                        CloseHandle (hErr);
                hOldConErr = INVALID_HANDLE_VALUE;
        }
+
+       if(bc)
+               bNewBatch = FALSE;
 #endif
 
        /* process final command */
        DoCommand (s);
 
 #ifdef FEATURE_REDIRECTION
+       if(bNewBatch && bc)
+               AddBatchRedirection(in, out, err);
        /* close old stdin file */
 #if 0  /* buggy implementation */
        SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
@@ -921,7 +1009,7 @@ ProcessInput (BOOL bFlag)
        LPTSTR ip;
        LPTSTR cp;
        BOOL bEchoThisLine;
-       
+
 
        do
        {
@@ -939,7 +1027,7 @@ ProcessInput (BOOL bFlag)
                cp = commandline;
                while (*ip)
                {
-                       if (*ip == _T('%'))
+         if (*ip == _T('%'))
                        {
                                switch (*++ip)
                                {
@@ -976,25 +1064,134 @@ ProcessInput (BOOL bFlag)
                                                if ((tp != NULL) &&
                                                    (tp <= _tcschr(ip, _T(' ')) - 1))
                                                {
-                                                       TCHAR evar[512];
+              INT size = 512;
+                                                       TCHAR *evar;
                                                        *tp = _T('\0');
 
-                                                       /* FIXME: This is just a quick hack!! */
-                                                       /* Do a proper memory allocation!! */
-                                                       if (GetEnvironmentVariable (ip, evar, 512))
-                                                               cp = _stpcpy (cp, evar);
-
+              /* FIXME: Correct error handling when it can not alloc memmory */
+                               
+              /* %CD% */
+              if (_tcsicmp(ip,_T("cd")) ==0)
+              {
+                TCHAR szPath[MAX_PATH];
+                           GetCurrentDirectory (MAX_PATH, szPath);
+                cp = _stpcpy (cp, szPath);                 
+              }
+              /* %TIME% */
+              else if (_tcsicmp(ip,_T("time")) ==0)
+              {
+                TCHAR szTime[40];                                                                               
+                SYSTEMTIME t;
+                GetSystemTime(&t); 
+
+                _sntprintf(szTime ,40,_T("%02d%c%02d%c%02d%c%02d"), t.wHour, cTimeSeparator,t.wMinute , cTimeSeparator,t.wSecond , cDecimalSeparator, t.wMilliseconds );
+                cp = _stpcpy (cp, szTime);                                   
+              }
+              
+              /* %DATE% */
+              else if (_tcsicmp(ip,_T("date")) ==0)
+              {
+              TCHAR szDate[40];
+
+                   GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, _T("ddd"), szDate, sizeof (szDate));
+              cp = _stpcpy (cp, szDate);        
+              cp = _stpcpy (cp, _T(" "));        
+              GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, szDate, sizeof (szDate));
+              cp = _stpcpy (cp, szDate);        
+              }
+
+              /* %RANDOM% */
+              else if (_tcsicmp(ip,_T("random")) ==0)
+              {
+               TCHAR szRand[40];               
+               /* Get random number */
+               _itot(rand(),szRand,10);
+               cp = _stpcpy (cp, szRand); 
+              }
+               
+              /* %CMDCMDLINE% */
+              else if (_tcsicmp(ip,_T("cmdcmdline")) ==0)
+              {                      
+               TCHAR *pargv;               
+               /* Get random number */        
+               pargv = GetCommandLine();
+               cp = _stpcpy (cp, pargv); 
+              }
+
+              /* %CMDEXTVERSION% */
+              else if (_tcsicmp(ip,_T("cmdextversion")) ==0)
+              {
+               TCHAR szVER[40];               
+               /* Set version number to 2 */
+               _itot(2,szVER,10);
+               cp = _stpcpy (cp, szVER); 
+              }
+                       
+              /* %ERRORLEVEL% */
+              else if (_tcsicmp(ip,_T("errorlevel")) ==0)
+              {
+                evar = malloc ( size * sizeof(TCHAR));
+                if (evar==NULL) 
+                    return 1; 
+
+                memset(evar,0,512 * sizeof(TCHAR));
+                _itot(nErrorLevel,evar,10);        
+                cp = _stpcpy (cp, evar);
+
+                free(evar);
+              }               
+                                                       else 
+              {
+                evar = malloc ( 512 * sizeof(TCHAR));
+                if (evar==NULL) 
+                    return 1; 
+                                        SetLastError(0);
+                size = GetEnvironmentVariable (ip, evar, 512);
+                                        if(GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+                                        {
+                                                /* if no env var is found you must 
+                                                   continue with what was input*/
+                                          cp = _stpcpy (cp, _T("%"));
+                                               cp = _stpcpy (cp, ip);
+                                               cp = _stpcpy (cp, _T("%"));
+                                        }
+                                        else
+                                        {
+                if (size > 512)
+                {
+                    evar = realloc(evar,size * sizeof(TCHAR) );
+                    if (evar==NULL)
+                    {
+                      return 1;
+                    }
+                    size = GetEnvironmentVariable (ip, evar, size);
+                }
+
+                if (size)
+                {
+                                                                cp = _stpcpy (cp, evar);
+                }
+                                        }
+
+                free(evar);
+              }
+               
                                                        ip = tp + 1;
+
                                                }
                                                else
                                                {
                                                        *cp++ = _T('%');
-                                               }
+                                               }              
+           
                                                break;
                                }
                                continue;
                        }
 
+
+     
+
                        if (_istcntrl (*ip))
                                *ip = _T(' ');
                        *cp++ = *ip++;
@@ -1003,10 +1200,10 @@ ProcessInput (BOOL bFlag)
                *cp = _T('\0');
 
                /* strip trailing spaces */
-               while ((--cp >= commandline) && _istspace (*cp));
+               while ((--cp >= commandline) && _istspace (*cp));     
 
                *(cp + 1) = _T('\0');
-
+   
                /* JPP 19980807 */
                /* Echo batch file line */
                if (bEchoThisLine)
@@ -1034,7 +1231,7 @@ ProcessInput (BOOL bFlag)
  */
 BOOL WINAPI BreakHandler (DWORD dwCtrlType)
 {
-       
+
        if ((dwCtrlType != CTRL_C_EVENT) &&
            (dwCtrlType != CTRL_BREAK_EVENT))
                return FALSE;
@@ -1075,36 +1272,27 @@ VOID RemoveBreakHandler (VOID)
 static VOID
 ShowCommands (VOID)
 {
-       TCHAR szMsg[RC_STRING_MAX_SIZE];
-
        /* print command list */
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP1, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPrintf(szMsg);
+       ConOutResPuts(STRING_CMD_HELP1);
        PrintCommandList();
 
        /* print feature list */
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP2, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+       ConOutResPuts(STRING_CMD_HELP2);
 
-#ifdef FEATURE_ALIASES 
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP3, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+#ifdef FEATURE_ALIASES
+       ConOutResPuts(STRING_CMD_HELP3);
 #endif
 #ifdef FEATURE_HISTORY
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP4, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+       ConOutResPuts(STRING_CMD_HELP4);
 #endif
 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP5, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+       ConOutResPuts(STRING_CMD_HELP5);
 #endif
 #ifdef FEATURE_DIRECTORY_STACK
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP6, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+       ConOutResPuts(STRING_CMD_HELP6);
 #endif
 #ifdef FEATURE_REDIRECTION
-       LoadString(GetModuleHandle(NULL), STRING_CMD_HELP7, szMsg, RC_STRING_MAX_SIZE);
-       ConOutPuts(szMsg);
+       ConOutResPuts(STRING_CMD_HELP7);
 #endif
        ConOutChar(_T('\n'));
 }
@@ -1120,13 +1308,37 @@ ShowCommands (VOID)
 static VOID
 Initialize (int argc, TCHAR* argv[])
 {
-       TCHAR szMsg[RC_STRING_MAX_SIZE];
        TCHAR commandline[CMDLINE_LENGTH];
        TCHAR ModuleName[_MAX_PATH + 1];
        INT i;
 
        //INT len;
        //TCHAR *ptr, *cmdLine;
+       
+       /* get version information */
+       osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+       GetVersionEx (&osvi);
+
+       /* 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
+           dynamically instead */
+
+       if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT)
+       {
+               /* ntdll is always present on NT */
+               NtDllModule = GetModuleHandle(TEXT("ntdll.dll"));
+       }
+       else
+       {
+               /* not all 9x versions have a ntdll.dll, try to load it */
+               NtDllModule = LoadLibrary(TEXT("ntdll.dll"));
+       }
+
+       if (NtDllModule != NULL)
+       {
+               NtQueryInformationProcessPtr = (NtQueryInformationProcessProc)GetProcAddress(NtDllModule, "NtQueryInformationProcess");
+               NtReadVirtualMemoryPtr = (NtReadVirtualMemoryProc)GetProcAddress(NtDllModule, "NtReadVirtualMemory");
+       }
 
 
 #ifdef _DEBUG
@@ -1140,21 +1352,18 @@ Initialize (int argc, TCHAR* argv[])
        DebugPrintf (_T("]\n"));
 #endif
 
-       /* get version information */
-       osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-       GetVersionEx (&osvi);
-
        InitLocale ();
 
        /* get default input and output console handles */
        hOut = GetStdHandle (STD_OUTPUT_HANDLE);
        hIn  = GetStdHandle (STD_INPUT_HANDLE);
 
+       SetEnvironmentVariable (_T("PROMPT"), _T("$P$G"));
+
 
        if (argc >= 2 && !_tcsncmp (argv[1], _T("/?"), 2))
        {
-               LoadString(GetModuleHandle(NULL), STRING_CMD_HELP8, szMsg, RC_STRING_MAX_SIZE);
-               ConOutPuts(szMsg);
+               ConOutResPaging(TRUE,STRING_CMD_HELP8);
                ExitProcess(0);
        }
        SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
@@ -1258,7 +1467,7 @@ Initialize (int argc, TCHAR* argv[])
 
                if (IsExistingFile (_T("commandline")))
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, commandline);
                        ParseCommandLine (commandline);
                }
@@ -1290,20 +1499,20 @@ Initialize (int argc, TCHAR* argv[])
 
 static VOID Cleanup (int argc, TCHAR *argv[])
 {
+#ifndef __REACTOS__
        TCHAR szMsg[RC_STRING_MAX_SIZE];
+#endif
 
        /* run cmdexit.bat */
        if (IsExistingFile (_T("cmdexit.bat")))
        {
-               LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR5, szMsg, RC_STRING_MAX_SIZE);
-               ConErrPrintf(szMsg);
+               ConErrResPuts(STRING_CMD_ERROR5);
 
                ParseCommandLine (_T("cmdexit.bat"));
        }
        else if (IsExistingFile (_T("\\cmdexit.bat")))
        {
-               LoadString( GetModuleHandle(NULL), STRING_CMD_ERROR5, szMsg, RC_STRING_MAX_SIZE);
-               ConErrPrintf ((LPTSTR)szMsg);
+               ConErrResPuts (STRING_CMD_ERROR5);
                ParseCommandLine (_T("\\cmdexit.bat"));
        }
 #ifndef __REACTOS__
@@ -1319,7 +1528,7 @@ static VOID Cleanup (int argc, TCHAR *argv[])
 
                if (IsExistingFile (_T("commandline")))
                {
-                       LoadString(GetModuleHandle(NULL), STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
                        ConErrPrintf(szMsg, commandline);
                        ParseCommandLine (commandline);
                }
@@ -1348,6 +1557,11 @@ static VOID Cleanup (int argc, TCHAR *argv[])
        RemoveBreakHandler ();
        SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
                        ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
+
+       if (NtDllModule != NULL)
+       {
+               FreeLibrary(NtDllModule);
+       }
 }
 
 #ifdef __REACTOS__
@@ -1401,11 +1615,12 @@ PWCHAR * _CommandLineToArgvW(PWCHAR lpCmdLine, int *pNumArgs)
  * main function
  */
 #ifdef _UNICODE
-int main(void)
+int _main(void)
 #else
-int main (int argc, char *argv[])
+int _main (int argc, char *argv[])
 #endif
 {
+  TCHAR startPath[MAX_PATH];
   CONSOLE_SCREEN_BUFFER_INFO Info;
   INT nExitCode;
 #ifdef _UNICODE
@@ -1417,6 +1632,9 @@ int main (int argc, char *argv[])
   argv = CommandLineToArgvW(GetCommandLineW(), &argc);
 #endif
 #endif
+      
+  GetCurrentDirectory(MAX_PATH,startPath);
+  _tchdir(startPath);
 
   SetFileApisToOEM();
   InputCodePage= 0;
@@ -1427,7 +1645,7 @@ int main (int argc, char *argv[])
                        OPEN_EXISTING, 0, NULL);
   if (GetConsoleScreenBufferInfo(hConsole, &Info) == FALSE)
     {
-      ConOutFormatMessage(GetLastError());
+      ConErrFormatMessage(GetLastError());
       return(1);
     }
   wColor = Info.wAttributes;
@@ -1435,16 +1653,19 @@ int main (int argc, char *argv[])
 
   InputCodePage= GetConsoleCP();
   OutputCodePage = GetConsoleOutputCP();
-
+  CMD_ModuleHandle = GetModuleHandle(NULL);
+  
   /* check switches on command-line */
   Initialize(argc, argv);
 
   /* call prompt routine */
   nExitCode = ProcessInput(FALSE);
 
+  
   /* do the cleanup */
   Cleanup(argc, argv);
 
+  
   return(nExitCode);
 }