cmd update:
[reactos.git] / reactos / subsys / system / cmd / cmd.c
index 43f3178..8f34812 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: cmd.c,v 1.11 2004/04/26 20:26:15 gdalsnes Exp $
- *
+/*
  *  CMD.C - command-line interface.
  *
  *
@@ -37,7 +36,7 @@
  *        message!
  *
  *        changed the format to call internal commands (again) so that if
- *        they want to split their commands, they can do it themselves 
+ *        they want to split their commands, they can do it themselves
  *        (none of the internal functions so far need that much power, anyway)
  *
  *    27 Aug 1996 (Tim Norman)
  *
  *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
  *        %envvar% replacement conflicted with for.
+ *
+ *    30-Apr-2004 (Filip Navara <xnavara@volny.cz>)
+ *       Make MakeSureDirectoryPathExistsEx unicode safe.
+ *
+ *    28-Mai-2004 (Hartmut Birr)
+ *       Removed MakeSureDirectoryPathExistsEx.
+ *       Use the current directory if GetTempPath fails.
+ *
+ *    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
+ *
+ *    06-May-2005 (Klemens Friedl <frik85@gmail.com>)
+ *        Add 'help' command (list all commands plus description)
  */
 
-#include "config.h"
-
-#include <windows.h>
-#include <tchar.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <winnt.h>
-#include <winternl.h>
+#include "precomp.h"
+#include "resource.h"
 
 #ifndef NT_SUCCESS
 #define NT_SUCCESS(StatCode)  ((NTSTATUS)(StatCode) >= 0)
 #endif
 
-#include "cmd.h"
-#include "batch.h"
-
 typedef NTSTATUS (STDCALL *NtQueryInformationProcessProc)(HANDLE, PROCESSINFOCLASS,
                                                           PVOID, ULONG, PULONG);
 typedef NTSTATUS (STDCALL *NtReadVirtualMemoryProc)(HANDLE, PVOID, PVOID, ULONG, PULONG);
@@ -154,6 +158,7 @@ OSVERSIONINFO osvi;
 HANDLE hIn;
 HANDLE hOut;
 HANDLE hConsole;
+HANDLE CMD_ModuleHandle;
 
 static NtQueryInformationProcessProc NtQueryInformationProcessPtr;
 static NtReadVirtualMemoryProc       NtReadVirtualMemoryPtr;
@@ -164,59 +169,6 @@ WORD wColor;              /* current color */
 WORD wDefColor;           /* default color */
 #endif
 
-
-
-/***********************************************************************
- *           MakeSureDirectoryPathExistsEx
- *
- * If a dir is at the end and the path ends with a backslash, FileAtEnd
- * is ignored. If the path doesn't end with a backslash, FileAtEnd is
- * used to determine if the last part of the path is a file name or a
- * directory.
- *
- * Path may be absolute or relative to current dir.
- *
- * FIXME: maybe put this in a header/library where everyone can use it?????
- */
-BOOL WINAPI MakeSureDirectoryPathExistsEx(LPCSTR DirPath, BOOL FileAtEnd)
-{
-   char Path[MAX_PATH];
-   char *SlashPos = Path;
-   char Slash;
-   BOOL bRes;
-   
-   strcpy(Path, DirPath);
-        
-   while((SlashPos=strpbrk(SlashPos+1,"\\/")))
-   {
-      Slash = *SlashPos;
-      *SlashPos = 0;
-      
-      bRes = CreateDirectoryA(Path, NULL);
-      if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
-      {
-         return FALSE;
-      }
-      
-      *SlashPos = Slash;
-      
-      if (*(SlashPos+1) == 0) return TRUE;
-   }
-
-   if (!FileAtEnd)
-   {
-      bRes = CreateDirectoryA(Path, NULL);
-      if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
-      {
-         return FALSE;
-      }
-   }
-
-   return TRUE;
-}
-
-
-
 /*
  *  is character a delimeter when used on first word?
  *
@@ -261,7 +213,7 @@ static BOOL IsConsoleProcess(HANDLE Process)
 
        if (NULL == NtQueryInformationProcessPtr || NULL == NtReadVirtualMemoryPtr)
        {
-               return FALSE;
+               return TRUE;
        }
 
        Status = NtQueryInformationProcessPtr(Process, ProcessBasicInformation,
@@ -287,6 +239,68 @@ static BOOL IsConsoleProcess(HANDLE Process)
 }
 
 
+
+#ifdef _UNICODE
+#define SHELLEXECUTETEXT       "ShellExecuteW"
+#else
+#define SHELLEXECUTETEXT       "ShellExecuteA"
+#endif
+
+typedef HINSTANCE (WINAPI *MYEX)(
+    HWND hwnd,
+    LPCTSTR lpOperation,
+    LPCTSTR lpFile,
+    LPCTSTR lpParameters,
+    LPCTSTR lpDirectory,
+    INT nShowCmd
+);
+
+
+
+static BOOL RunFile(LPTSTR filename)
+{
+       HMODULE         hShell32;
+       MYEX            hShExt;
+       HINSTANCE       ret;
+
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile(%s)\n"), filename);
+#endif
+       hShell32 = LoadLibrary(_T("SHELL32.DLL"));
+       if (!hShell32)
+       {
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile: couldn't load SHELL32.DLL!\n"));
+#endif
+               return FALSE;
+       }
+
+       hShExt = (MYEX)(FARPROC)GetProcAddress(hShell32, SHELLEXECUTETEXT);
+       if (!hShExt)
+       {
+#ifdef _DEBUG
+               DebugPrintf (_T("RunFile: couldn't find ShellExecuteA/W in SHELL32.DLL!\n"));
+#endif
+               FreeLibrary(hShell32);
+               return FALSE;
+       }
+
+#ifdef _DEBUG
+       DebugPrintf (_T("RunFile: ShellExecuteA/W is at %x\n"), hShExt);
+#endif
+
+       ret = (hShExt)(NULL, _T("open"), filename, NULL, NULL, SW_SHOWNORMAL);
+
+#ifdef _DEBUG
+       DebugPrintf (_T("RunFile: ShellExecuteA/W returned %d\n"), (DWORD)ret);
+#endif
+
+       FreeLibrary(hShell32);
+       return (((DWORD)ret) > 32);
+}
+
+
+
 /*
  * This command (in first) was not found in the command table
  *
@@ -295,7 +309,7 @@ static BOOL IsConsoleProcess(HANDLE Process)
  */
 
 static VOID
-Execute (LPTSTR first, LPTSTR rest)
+Execute (LPTSTR full, LPTSTR first, LPTSTR rest)
 {
        TCHAR szFullName[MAX_PATH];
 #ifndef __REACTOS__
@@ -309,7 +323,7 @@ Execute (LPTSTR first, LPTSTR rest)
 
        /* check for a drive change */
        if ((_istalpha (first[0])) && (!_tcscmp (first + 1, _T(":"))))
-       {       
+       {
                BOOL working = TRUE;
                if (!SetCurrentDirectory(first))
                /* Guess they changed disc or something, handle that gracefully and get to root */
@@ -322,7 +336,7 @@ Execute (LPTSTR first, LPTSTR rest)
                        working = SetCurrentDirectory(str);
                }
 
-               if (!working) ConErrPuts (INVALIDDRIVE);
+               if (!working) ConErrResPuts (STRING_FREE_ERROR1);
 
                return;
        }
@@ -351,17 +365,13 @@ Execute (LPTSTR first, LPTSTR rest)
        else
        {
                /* exec the program */
-               TCHAR szFullCmdLine [CMDLINE_LENGTH];
                PROCESS_INFORMATION prci;
                STARTUPINFO stui;
 
 #ifdef _DEBUG
-               DebugPrintf (_T("[EXEC: %s %s]\n"), szFullName, rest);
+               DebugPrintf (_T("[EXEC: %s %s]\n"), full, rest);
 #endif
                /* build command line for CreateProcess() */
-               _tcscpy (szFullCmdLine, first);
-               _tcscat (szFullCmdLine, _T(" "));
-               _tcscat (szFullCmdLine, rest);
 
                /* fill startup info */
                memset (&stui, 0, sizeof (STARTUPINFO));
@@ -372,12 +382,12 @@ Execute (LPTSTR first, LPTSTR rest)
                // return console to standard mode
                SetConsoleMode (GetStdHandle(STD_INPUT_HANDLE),
                                ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_ECHO_INPUT );
-               
+
                if (CreateProcess (szFullName,
-                                  szFullCmdLine,
+                                  full,
                                   NULL,
                                   NULL,
-                                  FALSE,
+                                  TRUE,
                                   CREATE_NEW_PROCESS_GROUP,
                                   NULL,
                                   NULL,
@@ -403,14 +413,26 @@ Execute (LPTSTR first, LPTSTR rest)
                }
                else
                {
-                       ErrorMessage (GetLastError (),
-                                     _T("Error executing CreateProcess()!!\n"));
+#ifdef _DEBUG
+                       DebugPrintf (_T("[ShellExecute: %s]\n"), full);
+#endif
+                       // See if we can run this with ShellExecute() ie myfile.xls
+                       if (!RunFile(full))
+                       {
+#ifdef _DEBUG
+                               DebugPrintf (_T("[ShellExecute failed!: %s]\n"), full);
+#endif
+                               error_bad_command ();
+                       }
                }
                // restore console mode
                SetConsoleMode( GetStdHandle( STD_INPUT_HANDLE ),
                                ENABLE_PROCESSED_INPUT );
        }
 
+       /* Get code page if it has been change */
+       InputCodePage= GetConsoleCP();
+    OutputCodePage = GetConsoleOutputCP();
 #ifndef __REACTOS__
        SetConsoleTitle (szWindowTitle);
 #endif
@@ -432,7 +454,7 @@ DoCommand (LPTSTR line)
        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 */
+       LPTSTR rest;   /* pointer to the rest of the command line */
        INT cl;
        LPCOMMAND cmdptr;
 
@@ -441,8 +463,9 @@ DoCommand (LPTSTR line)
 #endif /* DEBUG */
 
        /* Skip over initial white space */
-       while (_istspace (*rest))
-               rest++;
+       while (_istspace (*line))
+               line++;
+       rest = line;
 
        cstart = rest;
 
@@ -457,6 +480,8 @@ DoCommand (LPTSTR line)
 
                        while(*rest != _T('\0') && *rest != _T('"'))
                                *cp++ = _totlower (*rest++);
+                       if (*rest == _T('"'))
+                               rest++;
                }
                else
                {
@@ -467,7 +492,7 @@ DoCommand (LPTSTR line)
 
                /* Terminate first word */
                *cp = _T('\0');
-               
+
                /* commands are limited to MAX_PATH */
                if(_tcslen(com) > MAX_PATH)
                {
@@ -485,7 +510,7 @@ DoCommand (LPTSTR line)
                        /* If end of table execute ext cmd */
                        if (cmdptr->name == NULL)
                        {
-                               Execute (com, rest);
+                               Execute (line, com, rest);
                                break;
                        }
 
@@ -531,6 +556,7 @@ DoCommand (LPTSTR line)
 
 VOID ParseCommandLine (LPTSTR cmd)
 {
+       TCHAR szMsg[RC_STRING_MAX_SIZE];
        TCHAR cmdline[CMDLINE_LENGTH];
        LPTSTR s;
 #ifdef FEATURE_REDIRECTION
@@ -543,6 +569,8 @@ VOID ParseCommandLine (LPTSTR cmd)
        LPTSTR t = NULL;
        INT  num = 0;
        INT  nRedirFlags = 0;
+       INT  Length;
+       UINT Attributes;
 
        HANDLE hOldConIn;
        HANDLE hOldConOut;
@@ -563,8 +591,20 @@ VOID ParseCommandLine (LPTSTR cmd)
 
 #ifdef FEATURE_REDIRECTION
        /* find the temp path to store temporary files */
-       GetTempPath (MAX_PATH, szTempPath);
-   MakeSureDirectoryPathExistsEx(szTempPath, FALSE);
+       Length = GetTempPath (MAX_PATH, szTempPath);
+       if (Length > 0 && Length < MAX_PATH)
+       {
+               Attributes = GetFileAttributes(szTempPath);
+               if (Attributes == 0xffffffff ||
+                   !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
+               {
+                       Length = 0;
+               }
+       }
+       if (Length == 0 || Length >= MAX_PATH)
+       {
+               _tcscpy(szTempPath, _T(".\\"));
+       }
        if (szTempPath[_tcslen (szTempPath) - 1] != _T('\\'))
                _tcscat (szTempPath, _T("\\"));
 
@@ -600,13 +640,15 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, in);
                        return;
                }
 
                if (!SetStdHandle (STD_INPUT_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect input from file %s\n"), in);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR1, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, in);
                        return;
                }
 #ifdef _DEBUG
@@ -624,16 +666,17 @@ VOID ParseCommandLine (LPTSTR cmd)
 
                /* Create unique temporary file name */
                GetTempFileName (szTempPath, _T("CMD"), 0, szFileName[1]);
-      
+
                /* 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){
-         ConErrPrintf (_T("Error creating temporary file for pipe data\n"));
-         return;
-      }
-                   
+               if (hFile[1] == INVALID_HANDLE_VALUE)
+               {
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR2, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg);
+                       return;
+               }
+
                SetStdHandle (STD_OUTPUT_HANDLE, hFile[1]);
 
                DoCommand (s);
@@ -682,13 +725,15 @@ VOID ParseCommandLine (LPTSTR cmd)
                                    FILE_ATTRIBUTE_NORMAL, NULL);
                if (hFile == INVALID_HANDLE_VALUE)
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, out);
                        return;
                }
 
                if (!SetStdHandle (STD_OUTPUT_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), out);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, out);
                        return;
                }
 
@@ -741,13 +786,16 @@ VOID ParseCommandLine (LPTSTR cmd)
                                            NULL);
                        if (hFile == INVALID_HANDLE_VALUE)
                        {
-                               ConErrPrintf (_T("Can't redirect to file %s\n"), err);
+                               LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                               ConErrPrintf(szMsg, err);
                                return;
                        }
                }
+
                if (!SetStdHandle (STD_ERROR_HANDLE, hFile))
                {
-                       ConErrPrintf (_T("Can't redirect to file %s\n"), err);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, err);
                        return;
                }
 
@@ -780,7 +828,7 @@ VOID ParseCommandLine (LPTSTR cmd)
        /* close old stdin file */
 #if 0  /* buggy implementation */
        SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
-       if ((hFile[0] != INVALID_HANDLE_VALUE) && 
+       if ((hFile[0] != INVALID_HANDLE_VALUE) &&
                (hFile[0] != hOldConIn))
        {
                /* delete old stdin file, if it is a real file */
@@ -868,7 +916,7 @@ VOID ParseCommandLine (LPTSTR cmd)
  *
  */
 
-static INT 
+static INT
 ProcessInput (BOOL bFlag)
 {
        TCHAR commandline[CMDLINE_LENGTH];
@@ -878,6 +926,7 @@ ProcessInput (BOOL bFlag)
        LPTSTR cp;
        BOOL bEchoThisLine;
 
+
        do
        {
                /* if no batch input then... */
@@ -989,6 +1038,7 @@ ProcessInput (BOOL bFlag)
  */
 BOOL WINAPI BreakHandler (DWORD dwCtrlType)
 {
+
        if ((dwCtrlType != CTRL_C_EVENT) &&
            (dwCtrlType != CTRL_BREAK_EVENT))
                return FALSE;
@@ -1030,27 +1080,28 @@ static VOID
 ShowCommands (VOID)
 {
        /* print command list */
-       ConOutPrintf (_T("\nInternal commands available:\n"));
-       PrintCommandList ();
+       ConOutResPuts(STRING_CMD_HELP1);
+       PrintCommandList();
 
        /* print feature list */
-       ConOutPuts (_T("\nFeatures available:"));
+       ConOutResPuts(STRING_CMD_HELP2);
+
 #ifdef FEATURE_ALIASES
-       ConOutPuts (_T("  [aliases]"));
+       ConOutResPuts(STRING_CMD_HELP3);
 #endif
 #ifdef FEATURE_HISTORY
-       ConOutPuts (_T("  [history]"));
+       ConOutResPuts(STRING_CMD_HELP4);
 #endif
 #ifdef FEATURE_UNIX_FILENAME_COMPLETION
-       ConOutPuts (_T("  [unix filename completion]"));
+       ConOutResPuts(STRING_CMD_HELP5);
 #endif
 #ifdef FEATURE_DIRECTORY_STACK
-       ConOutPuts (_T("  [directory stack]"));
+       ConOutResPuts(STRING_CMD_HELP6);
 #endif
 #ifdef FEATURE_REDIRECTION
-       ConOutPuts (_T("  [redirections and piping]"));
+       ConOutResPuts(STRING_CMD_HELP7);
 #endif
-       ConOutChar (_T('\n'));
+       ConOutChar(_T('\n'));
 }
 #endif
 
@@ -1067,6 +1118,7 @@ Initialize (int argc, TCHAR* argv[])
        TCHAR commandline[CMDLINE_LENGTH];
        TCHAR ModuleName[_MAX_PATH + 1];
        INT i;
+
        //INT len;
        //TCHAR *ptr, *cmdLine;
 
@@ -1095,16 +1147,8 @@ Initialize (int argc, TCHAR* argv[])
 
        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);
+               ConOutResPuts(STRING_CMD_HELP8);
+               ExitProcess(0);
        }
        SetConsoleMode (hIn, ENABLE_PROCESSED_INPUT);
 
@@ -1122,7 +1166,7 @@ Initialize (int argc, TCHAR* argv[])
                {
                        if (!_tcsicmp (argv[i], _T("/p")))
                        {
-                               if (!IsValidFileName (_T("\\autoexec.bat")))
+                               if (!IsExistingFile (_T("\\autoexec.bat")))
                                {
 #ifdef INCLUDE_CMD_DATE
                                        cmd_date (_T(""), _T(""));
@@ -1187,11 +1231,11 @@ Initialize (int argc, TCHAR* argv[])
        }
 
        /* run cmdstart.bat */
-       if (IsValidFileName (_T("cmdstart.bat")))
+       if (IsExistingFile (_T("cmdstart.bat")))
        {
                ParseCommandLine (_T("cmdstart.bat"));
        }
-       else if (IsValidFileName (_T("\\cmdstart.bat")))
+       else if (IsExistingFile (_T("\\cmdstart.bat")))
        {
                ParseCommandLine (_T("\\cmdstart.bat"));
        }
@@ -1205,9 +1249,10 @@ Initialize (int argc, TCHAR* argv[])
                p = _tcsrchr (commandline, _T('\\')) + 1;
                _tcscpy (p, _T("cmdstart.bat"));
 
-               if (IsValidFileName (_T("commandline")))
+               if (IsExistingFile (_T("commandline")))
                {
-                       ConErrPrintf (_T("Running %s...\n", commandline));
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, commandline);
                        ParseCommandLine (commandline);
                }
        }
@@ -1238,15 +1283,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 (IsValidFileName (_T("cmdexit.bat")))
+       if (IsExistingFile (_T("cmdexit.bat")))
        {
-               ConErrPrintf (_T("Running cmdexit.bat...\n"));
+               ConErrResPuts(STRING_CMD_ERROR5);
+
                ParseCommandLine (_T("cmdexit.bat"));
        }
-       else if (IsValidFileName (_T("\\cmdexit.bat")))
+       else if (IsExistingFile (_T("\\cmdexit.bat")))
        {
-               ConErrPrintf (_T("Running \\cmdexit.bat...\n"));
+               ConErrResPuts (STRING_CMD_ERROR5);
                ParseCommandLine (_T("\\cmdexit.bat"));
        }
 #ifndef __REACTOS__
@@ -1260,9 +1310,10 @@ static VOID Cleanup (int argc, TCHAR *argv[])
                p = _tcsrchr (commandline, _T('\\')) + 1;
                _tcscpy (p, _T("cmdexit.bat"));
 
-               if (IsValidFileName (_T("commandline")))
+               if (IsExistingFile (_T("commandline")))
                {
-                       ConErrPrintf (_T("Running %s...\n"), commandline);
+                       LoadString(CMD_ModuleHandle, STRING_CMD_ERROR4, szMsg, RC_STRING_MAX_SIZE);
+                       ConErrPrintf(szMsg, commandline);
                        ParseCommandLine (commandline);
                }
        }
@@ -1281,7 +1332,7 @@ static VOID Cleanup (int argc, TCHAR *argv[])
        FreeLastPath ();
 #endif
 
-#ifdef FEATURE_HISTORY 
+#ifdef FEATURE_HISTORY
        CleanHistory();
 #endif
 
@@ -1361,18 +1412,24 @@ int main (int argc, char *argv[])
 #endif
 
   SetFileApisToOEM();
+  InputCodePage= 0;
+  OutputCodePage = 0;
 
-  hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE, 
-                        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, 
+  hConsole = CreateFile(_T("CONOUT$"), GENERIC_READ|GENERIC_WRITE,
+                        FILE_SHARE_READ|FILE_SHARE_WRITE, NULL,
                        OPEN_EXISTING, 0, NULL);
   if (GetConsoleScreenBufferInfo(hConsole, &Info) == FALSE)
     {
-      ConErrPrintf (_T("GetConsoleScreenBufferInfo: Error: %ld\n"), GetLastError());
+      ConOutFormatMessage(GetLastError());
       return(1);
     }
   wColor = Info.wAttributes;
   wDefColor = wColor;
 
+  InputCodePage= GetConsoleCP();
+  OutputCodePage = GetConsoleOutputCP();
+  CMD_ModuleHandle = GetModuleHandle(NULL);
+
   /* check switches on command-line */
   Initialize(argc, argv);