Made cmd unicode compatible.
[reactos.git] / reactos / subsys / system / cmd / console.c
index e5e2264..df3de99 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: console.c,v 1.7 2004/06/23 19:32:17 weiden Exp $
- *
+/*
  *  CONSOLE.C - console input/output functions.
  *
  *
@@ -7,22 +6,27 @@
  *
  *    20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
  *        started
+ *
+ *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
+ *        Remove all hardcode string to En.rc
+ *
+ *    01-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
+ *        Added ConPrintfPaging and ConOutPrintfPaging
  */
 
-#include "config.h"
 
-#include <windows.h>
-#include <tchar.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
 
-#include "cmd.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);
@@ -55,12 +59,7 @@ VOID ConInDummy (VOID)
        if (hInput == INVALID_HANDLE_VALUE)
                DebugPrintf (_T("Invalid input handle!!!\n"));
 #endif /* _DEBUG */
-#ifdef __REACTOS__
-       /* ReadConsoleInputW isn't implwmented within ROS. */
-       ReadConsoleInputA (hInput, &dummy, 1, &dwRead);
-#else
        ReadConsoleInput (hInput, &dummy, 1, &dwRead);
-#endif
 }
 
 VOID ConInFlush (VOID)
@@ -81,12 +80,7 @@ VOID ConInKey (PINPUT_RECORD lpBuffer)
 
        do
        {
-#ifdef __REACTOS__
-               /* ReadConsoleInputW isn't implwmented within ROS. */
-               ReadConsoleInputA (hInput, lpBuffer, 1, &dwRead);
-#else
                ReadConsoleInput (hInput, lpBuffer, 1, &dwRead);
-#endif
                if ((lpBuffer->EventType == KEY_EVENT) &&
                        (lpBuffer->Event.KeyEvent.bKeyDown == TRUE))
                        break;
@@ -120,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++)
@@ -148,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;
@@ -174,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
@@ -193,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);
@@ -209,26 +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;
-       
+
        va_start (arg_ptr, MessageId);
        ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
               NULL,
@@ -237,7 +379,7 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
               (LPTSTR) &text,
               0,
               &arg_ptr);
-       
+
        va_end (arg_ptr);
        if(ret > 0)
        {
@@ -246,7 +388,8 @@ VOID ConOutFormatMessage (DWORD MessageId, ...)
        }
        else
        {
-               ConErrPrintf (_T("Unknown error: %d\n"), MessageId);
+               LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
+               ConErrPrintf(szMsg);
        }
 }
 
@@ -259,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);