Made cmd unicode compatible.
[reactos.git] / reactos / subsys / system / cmd / console.c
index 870edfb..df3de99 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id$
- *
+/*
  *  CONSOLE.C - console input/output functions.
  *
  *
@@ -9,16 +8,25 @@
  *        started
  *
  *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
- *        Remove all hardcode string to En.rc  
+ *        Remove all hardcode string to En.rc
+ *
+ *    01-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
+ *        Added ConPrintfPaging and ConOutPrintfPaging
  */
 
-#include "precomp.h"
+
+
+#include <precomp.h>
 #include "resource.h"
 
 
 #define OUTPUT_BUFFER_SIZE  4096
 
 
+UINT InputCodePage;
+UINT OutputCodePage;
+
+
 VOID ConInDisable (VOID)
 {
        HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
@@ -106,7 +114,7 @@ VOID ConInString (LPTSTR lpInput, DWORD dwLength)
        ReadFile (hFile, (PVOID)pBuf, dwLength, &dwRead, NULL);
 
 #ifdef _UNICODE
-       MultiByteToWideChar(CP_ACP, 0, pBuf, dwLength + 1, lpInput, dwLength + 1);
+       MultiByteToWideChar(  InputCodePage, 0, pBuf, dwLength + 1, lpInput, dwLength + 1);
 #endif
        p = lpInput;
        for (i = 0; i < dwRead; i++, p++)
@@ -134,7 +142,7 @@ static VOID ConChar(TCHAR c, DWORD nStdHandle)
        WCHAR ws[2];
        ws[0] = c;
        ws[1] = 0;
-       WideCharToMultiByte(CP_ACP, 0, ws, 2, as, 2, NULL, NULL);
+       WideCharToMultiByte( OutputCodePage, 0, ws, 2, as, 2, NULL, NULL);
        cc = as[0];
 #else
        cc = c;
@@ -160,7 +168,7 @@ VOID ConPuts(LPTSTR szText, DWORD nStdHandle)
        len = _tcslen(szText);
 #ifdef _UNICODE
        pBuf = malloc(len + 1);
-       len = WideCharToMultiByte(CP_ACP, 0, szText, len + 1, pBuf, len + 1, NULL, NULL) - 1;
+       len = WideCharToMultiByte( OutputCodePage, 0, szText, len + 1, pBuf, len + 1, NULL, NULL) - 1;
 #else
        pBuf = szText;
 #endif
@@ -179,6 +187,21 @@ VOID ConPuts(LPTSTR szText, DWORD nStdHandle)
 #endif
 }
 
+VOID ConOutResPaging(BOOL NewPage, UINT resID)
+{
+  TCHAR szMsg[RC_STRING_MAX_SIZE];
+  LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
+  ConOutPrintfPaging(NewPage, szMsg);
+}
+
+VOID ConOutResPuts (UINT resID)
+{
+  TCHAR szMsg[RC_STRING_MAX_SIZE];
+  LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
+
+  ConPuts(szMsg, STD_OUTPUT_HANDLE);
+}
+
 VOID ConOutPuts (LPTSTR szText)
 {
        ConPuts(szText, STD_OUTPUT_HANDLE);
@@ -195,27 +218,159 @@ VOID ConPrintf(LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
        len = _vstprintf (szOut, szFormat, arg_ptr);
 #ifdef _UNICODE
        pBuf = malloc(len + 1);
-       len = WideCharToMultiByte(CP_ACP, 0, szOut, len + 1, pBuf, len + 1, NULL, NULL) - 1;
+       len = WideCharToMultiByte( OutputCodePage, 0, szOut, len + 1, pBuf, len + 1, NULL, NULL) - 1;
 #else
        pBuf = szOut;
 #endif
+
        WriteFile (GetStdHandle (nStdHandle),
                   pBuf,
                   len,
                   &dwWritten,
                   NULL);
+
+
+#ifdef UNICODE
+       free(pBuf);
+#endif
+}
+
+VOID ConPrintfPaging(BOOL NewPage, LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
+{
+       INT len;
+       PCHAR pBuf;
+       CONSOLE_SCREEN_BUFFER_INFO csbi;
+       TCHAR szOut[OUTPUT_BUFFER_SIZE];
+       DWORD dwWritten;
+  
+  /* used to count number of lines since last pause */
+       static int LineCount = 0;
+
+  /* used to see how big the screen is */
+       int ScreenLines = 0;  
+
+  /* the number of chars in a roow */
+       int ScreenCol = 0;  
+
+  /* chars since end of line */
+       int CharEL = 0; 
+  
+       int i = 0;
+
+       if(NewPage == TRUE)
+               LineCount = 0;
+
+  /* rest LineCount and return if no string have been given */
+        if (szFormat == NULL)
+                return;
+
+
+       //get the size of the visual screen that can be printed too
+       if (!GetConsoleScreenBufferInfo(hConsole, &csbi))
+        {
+                // we assuming its a file handle
+                ConPrintf(szFormat, arg_ptr, nStdHandle);
+                return;
+        }
+       //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
+       ScreenLines = (csbi.srWindow.Bottom  - csbi.srWindow.Top) - 4;
+       ScreenCol = (csbi.srWindow.Right - csbi.srWindow.Left) + 1;
+
+       //make sure they didnt make the screen to small 
+       if(ScreenLines<4)
+        {
+               ConPrintf(szFormat, arg_ptr, nStdHandle);
+                return ;
+        }
+          
+       len = _vstprintf (szOut, szFormat, arg_ptr);
+#ifdef _UNICODE
+       pBuf = malloc(len + 1);
+       len = WideCharToMultiByte( OutputCodePage, 0, szOut, len + 1, pBuf, len + 1, NULL, NULL) - 1;
+#else
+       pBuf = szOut;
+#endif
+             
+       for(i = 0; i < len; i++)
+       { 
+      
+                if(pBuf[i] == '\n')
+               {                               
+                       LineCount++; 
+                        CharEL=0;
+               }      
+                else
+                {      
+                        CharEL++;           
+                        if (CharEL>=ScreenCol)
+                        {        
+                                if (i+1<len)
+                                {
+                                        if(pBuf[i+1] != '\n') LineCount++;          
+                                }
+                                CharEL=0;
+                        }
+                }
+
+                /* FIXME : write more that one char at time */
+                WriteFile (GetStdHandle (nStdHandle),&pBuf[i],sizeof(CHAR),&dwWritten,NULL);
+               if(LineCount >= ScreenLines)
+               {
+                        if(strnicmp(&pBuf[i], "\n", 2)!=0)
+                        WriteFile (GetStdHandle (nStdHandle),"\n",sizeof(CHAR),&dwWritten,NULL); 
+
+                       if(PagePrompt() != PROMPT_YES)
+                       {
+                               return;
+                       }
+                       //reset the number of lines being printed         
+                       LineCount = 0;
+                        CharEL=0;
+               }
+      
+       }
+
 #ifdef UNICODE
        free(pBuf);
 #endif
 }
 
+VOID ConErrFormatMessage (DWORD MessageId, ...)
+{
+       TCHAR szMsg[RC_STRING_MAX_SIZE];
+       DWORD ret;
+       LPTSTR text;
+       va_list arg_ptr;
+
+       va_start (arg_ptr, MessageId);
+       ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+              NULL,
+              MessageId,
+              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+              (LPTSTR) &text,
+              0,
+              &arg_ptr);
+
+       va_end (arg_ptr);
+       if(ret > 0)
+       {
+               ConErrPuts (text);
+               LocalFree(text);
+       }
+       else
+       {
+               LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
+               ConErrPrintf(szMsg);
+       }
+}
+
 VOID ConOutFormatMessage (DWORD MessageId, ...)
 {
+       TCHAR szMsg[RC_STRING_MAX_SIZE];
        DWORD ret;
        LPTSTR text;
        va_list arg_ptr;
-       WCHAR szMsg[RC_STRING_MAX_SIZE];
-       
+
        va_start (arg_ptr, MessageId);
        ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
               NULL,
@@ -224,7 +379,7 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
               (LPTSTR) &text,
               0,
               &arg_ptr);
-       
+
        va_end (arg_ptr);
        if(ret > 0)
        {
@@ -233,8 +388,8 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
        }
        else
        {
-               LoadString( GetModuleHandle(NULL), STRING_CONSOLE_ERROR, (LPTSTR) szMsg,sizeof(szMsg));
-        ConErrPrintf ((LPTSTR)szMsg);
+               LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
+               ConErrPrintf(szMsg);
        }
 }
 
@@ -247,12 +402,28 @@ VOID ConOutPrintf (LPTSTR szFormat, ...)
        va_end (arg_ptr);
 }
 
+VOID ConOutPrintfPaging (BOOL NewPage, LPTSTR szFormat, ...)
+{
+       va_list arg_ptr;
+
+       va_start (arg_ptr, szFormat);
+       ConPrintfPaging(NewPage, szFormat, arg_ptr, STD_OUTPUT_HANDLE);
+       va_end (arg_ptr);
+}
+
 VOID ConErrChar (TCHAR c)
 {
        ConChar(c, STD_ERROR_HANDLE);
 }
 
 
+VOID ConErrResPuts (UINT resID)
+{
+       TCHAR szMsg[RC_STRING_MAX_SIZE];
+    LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
+       ConPuts(szMsg, STD_ERROR_HANDLE);
+}
+
 VOID ConErrPuts (LPTSTR szText)
 {
        ConPuts(szText, STD_ERROR_HANDLE);