Doxygen

console.c
Go to the documentation of this file.
00001 /*
00002  *  CONSOLE.C - console input/output functions.
00003  *
00004  *
00005  *  History:
00006  *
00007  *    20-Jan-1999 (Eric Kohl)
00008  *        started
00009  *
00010  *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
00011  *        Remove all hardcode string to En.rc
00012  *
00013  *    01-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
00014  *        Added ConPrintfPaging and ConOutPrintfPaging
00015  *
00016  *    02-Feb-2007 (Paolo Devoti) <devotip at gmail.com>)
00017  *        Fixed ConPrintfPaging
00018  */
00019 
00020 #include "precomp.h"
00021 
00022 #define OUTPUT_BUFFER_SIZE  4096
00023 
00024 
00025 UINT InputCodePage;
00026 UINT OutputCodePage;
00027 
00028 
00029 VOID ConInDisable (VOID)
00030 {
00031     HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
00032     DWORD dwMode;
00033 
00034     GetConsoleMode (hInput, &dwMode);
00035     dwMode &= ~ENABLE_PROCESSED_INPUT;
00036     SetConsoleMode (hInput, dwMode);
00037 }
00038 
00039 
00040 VOID ConInEnable (VOID)
00041 {
00042     HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
00043     DWORD dwMode;
00044 
00045     GetConsoleMode (hInput, &dwMode);
00046     dwMode |= ENABLE_PROCESSED_INPUT;
00047     SetConsoleMode (hInput, dwMode);
00048 }
00049 
00050 
00051 VOID ConInFlush (VOID)
00052 {
00053     FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
00054 }
00055 
00056 
00057 VOID ConInKey (PINPUT_RECORD lpBuffer)
00058 {
00059     HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
00060     DWORD  dwRead;
00061 
00062     if (hInput == INVALID_HANDLE_VALUE)
00063         WARN ("Invalid input handle!!!\n");
00064 
00065     do
00066     {
00067         ReadConsoleInput (hInput, lpBuffer, 1, &dwRead);
00068         if ((lpBuffer->EventType == KEY_EVENT) &&
00069             (lpBuffer->Event.KeyEvent.bKeyDown == TRUE))
00070             break;
00071     }
00072     while (TRUE);
00073 }
00074 
00075 
00076 VOID ConInString (LPTSTR lpInput, DWORD dwLength)
00077 {
00078     DWORD dwOldMode;
00079     DWORD dwRead = 0;
00080     HANDLE hFile;
00081 
00082     LPTSTR p;
00083     PCHAR pBuf;
00084 
00085 #ifdef _UNICODE
00086     pBuf = (PCHAR)cmd_alloc(dwLength - 1);
00087 #else
00088     pBuf = lpInput;
00089 #endif
00090     ZeroMemory (lpInput, dwLength * sizeof(TCHAR));
00091     hFile = GetStdHandle (STD_INPUT_HANDLE);
00092     GetConsoleMode (hFile, &dwOldMode);
00093 
00094     SetConsoleMode (hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
00095 
00096     ReadFile (hFile, (PVOID)pBuf, dwLength - 1, &dwRead, NULL);
00097 
00098 #ifdef _UNICODE
00099     MultiByteToWideChar(InputCodePage, 0, pBuf, dwRead, lpInput, dwLength - 1);
00100     cmd_free(pBuf);
00101 #endif
00102     for (p = lpInput; *p; p++)
00103     {
00104         if (*p == _T('\x0d'))
00105         {
00106             *p = _T('\0');
00107             break;
00108         }
00109     }
00110 
00111     SetConsoleMode (hFile, dwOldMode);
00112 }
00113 
00114 static VOID ConWrite(TCHAR *str, DWORD len, DWORD nStdHandle)
00115 {
00116     DWORD dwWritten;
00117     HANDLE hOutput = GetStdHandle(nStdHandle);
00118 
00119     if (WriteConsole(hOutput, str, len, &dwWritten, NULL))
00120         return;
00121 
00122     /* We're writing to a file or pipe instead of the console. Convert the
00123      * string from TCHARs to the desired output format, if the two differ */
00124     if (bUnicodeOutput)
00125     {
00126 #ifndef _UNICODE
00127         WCHAR *buffer = cmd_alloc(len * sizeof(WCHAR));
00128         if (!buffer)
00129         {
00130             error_out_of_memory();
00131             return;
00132         }
00133         len = MultiByteToWideChar(OutputCodePage, 0, str, len, buffer, len);
00134         str = (PVOID)buffer;
00135 #endif
00136         WriteFile(hOutput, str, len * sizeof(WCHAR), &dwWritten, NULL);
00137 #ifndef _UNICODE
00138         cmd_free(buffer);
00139 #endif
00140     }
00141     else
00142     {
00143 #ifdef _UNICODE
00144         CHAR *buffer = cmd_alloc(len * MB_LEN_MAX * sizeof(CHAR));
00145         if (!buffer)
00146         {
00147             error_out_of_memory();
00148             return;
00149         }
00150         len = WideCharToMultiByte(OutputCodePage, 0, str, len, buffer, len * MB_LEN_MAX, NULL, NULL);
00151         str = (PVOID)buffer;
00152 #endif
00153         WriteFile(hOutput, str, len, &dwWritten, NULL);
00154 #ifdef _UNICODE
00155         cmd_free(buffer);
00156 #endif
00157     }
00158 }
00159 
00160 VOID ConOutChar (TCHAR c)
00161 {
00162     ConWrite(&c, 1, STD_OUTPUT_HANDLE);
00163 }
00164 
00165 VOID ConPuts(LPTSTR szText, DWORD nStdHandle)
00166 {
00167     ConWrite(szText, _tcslen(szText), nStdHandle);
00168 }
00169 
00170 VOID ConOutResPaging(BOOL NewPage, UINT resID)
00171 {
00172     TCHAR szMsg[RC_STRING_MAX_SIZE];
00173     LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
00174     ConOutPrintfPaging(NewPage, szMsg);
00175 }
00176 
00177 VOID ConOutResPuts (UINT resID)
00178 {
00179     TCHAR szMsg[RC_STRING_MAX_SIZE];
00180     LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
00181 
00182     ConPuts(szMsg, STD_OUTPUT_HANDLE);
00183 }
00184 
00185 VOID ConOutPuts (LPTSTR szText)
00186 {
00187     ConPuts(szText, STD_OUTPUT_HANDLE);
00188 }
00189 
00190 
00191 VOID ConPrintf(LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
00192 {
00193     TCHAR szOut[OUTPUT_BUFFER_SIZE];
00194     ConWrite(szOut, _vstprintf(szOut, szFormat, arg_ptr), nStdHandle);
00195 }
00196 
00197 INT ConPrintfPaging(BOOL NewPage, LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
00198 {
00199     INT len;
00200     CONSOLE_SCREEN_BUFFER_INFO csbi;
00201     TCHAR szOut[OUTPUT_BUFFER_SIZE];
00202     DWORD dwWritten;
00203     HANDLE hOutput = GetStdHandle(nStdHandle);
00204 
00205     /* used to count number of lines since last pause */
00206     static int LineCount = 0;
00207 
00208     /* used to see how big the screen is */
00209     int ScreenLines = 0;
00210 
00211     /* chars since start of line */
00212     int CharSL;
00213 
00214     int from = 0, i = 0;
00215 
00216     if(NewPage == TRUE)
00217         LineCount = 0;
00218 
00219     /* rest LineCount and return if no string have been given */
00220     if (szFormat == NULL)
00221         return 0;
00222 
00223 
00224     //get the size of the visual screen that can be printed too
00225     if (!GetConsoleScreenBufferInfo(hOutput, &csbi))
00226     {
00227         // we assuming its a file handle
00228         ConPrintf(szFormat, arg_ptr, nStdHandle);
00229         return 0;
00230     }
00231     //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
00232     ScreenLines = (csbi.srWindow.Bottom  - csbi.srWindow.Top) - 4;
00233     CharSL = csbi.dwCursorPosition.X;
00234 
00235     //make sure they didnt make the screen to small
00236     if(ScreenLines<4)
00237     {
00238         ConPrintf(szFormat, arg_ptr, nStdHandle);
00239         return 0;
00240     }
00241 
00242     len = _vstprintf (szOut, szFormat, arg_ptr);
00243 
00244     while (i < len)
00245     {
00246         // Search until the end of a line is reached
00247         if (szOut[i++] != _T('\n') && ++CharSL < csbi.dwSize.X)
00248             continue;
00249 
00250         LineCount++;
00251         CharSL=0;
00252 
00253         if(LineCount >= ScreenLines)
00254         {
00255             WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL);
00256             from = i;
00257 
00258             if(PagePrompt() != PROMPT_YES)
00259             {
00260                 return 1;
00261             }
00262             //reset the number of lines being printed
00263             LineCount = 0;
00264         }
00265     }
00266 
00267     WriteConsole(hOutput, &szOut[from], i-from, &dwWritten, NULL);
00268 
00269     return 0;
00270 }
00271 
00272 VOID ConErrFormatMessage (DWORD MessageId, ...)
00273 {
00274     TCHAR szMsg[RC_STRING_MAX_SIZE];
00275     DWORD ret;
00276     LPTSTR text;
00277     va_list arg_ptr;
00278 
00279     va_start (arg_ptr, MessageId);
00280     ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00281            NULL,
00282            MessageId,
00283            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00284            (LPTSTR) &text,
00285            0,
00286            &arg_ptr);
00287 
00288     va_end (arg_ptr);
00289     if(ret > 0)
00290     {
00291         ConErrPuts (text);
00292         LocalFree(text);
00293     }
00294     else
00295     {
00296         LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
00297         ConErrPrintf(szMsg);
00298     }
00299 }
00300 
00301 VOID ConOutFormatMessage (DWORD MessageId, ...)
00302 {
00303     TCHAR szMsg[RC_STRING_MAX_SIZE];
00304     DWORD ret;
00305     LPTSTR text;
00306     va_list arg_ptr;
00307 
00308     va_start (arg_ptr, MessageId);
00309     ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00310            NULL,
00311            MessageId,
00312            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00313            (LPTSTR) &text,
00314            0,
00315            &arg_ptr);
00316 
00317     va_end (arg_ptr);
00318     if(ret > 0)
00319     {
00320         ConErrPuts (text);
00321         LocalFree(text);
00322     }
00323     else
00324     {
00325         LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
00326         ConErrPrintf(szMsg);
00327     }
00328 }
00329 
00330 VOID ConOutResPrintf (UINT resID, ...)
00331 {
00332     TCHAR szMsg[RC_STRING_MAX_SIZE];
00333     va_list arg_ptr;
00334 
00335     va_start (arg_ptr, resID);
00336     LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
00337     ConPrintf(szMsg, arg_ptr, STD_OUTPUT_HANDLE);
00338     va_end (arg_ptr);
00339 }
00340 
00341 VOID ConOutPrintf (LPTSTR szFormat, ...)
00342 {
00343     va_list arg_ptr;
00344 
00345     va_start (arg_ptr, szFormat);
00346     ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE);
00347     va_end (arg_ptr);
00348 }
00349 
00350 INT ConOutPrintfPaging (BOOL NewPage, LPTSTR szFormat, ...)
00351 {
00352     INT iReturn;
00353     va_list arg_ptr;
00354 
00355     va_start (arg_ptr, szFormat);
00356     iReturn = ConPrintfPaging(NewPage, szFormat, arg_ptr, STD_OUTPUT_HANDLE);
00357     va_end (arg_ptr);
00358     return iReturn;
00359 }
00360 
00361 VOID ConErrChar (TCHAR c)
00362 {
00363     ConWrite(&c, 1, STD_ERROR_HANDLE);
00364 }
00365 
00366 
00367 VOID ConErrResPuts (UINT resID)
00368 {
00369     TCHAR szMsg[RC_STRING_MAX_SIZE];
00370     LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
00371     ConPuts(szMsg, STD_ERROR_HANDLE);
00372 }
00373 
00374 VOID ConErrPuts (LPTSTR szText)
00375 {
00376     ConPuts(szText, STD_ERROR_HANDLE);
00377 }
00378 
00379 
00380 VOID ConErrResPrintf (UINT resID, ...)
00381 {
00382     TCHAR szMsg[RC_STRING_MAX_SIZE];
00383     va_list arg_ptr;
00384 
00385     va_start (arg_ptr, resID);
00386     LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
00387     ConPrintf(szMsg, arg_ptr, STD_ERROR_HANDLE);
00388     va_end (arg_ptr);
00389 }
00390 
00391 VOID ConErrPrintf (LPTSTR szFormat, ...)
00392 {
00393     va_list arg_ptr;
00394 
00395     va_start (arg_ptr, szFormat);
00396     ConPrintf(szFormat, arg_ptr, STD_ERROR_HANDLE);
00397     va_end (arg_ptr);
00398 }
00399 
00400 VOID SetCursorXY (SHORT x, SHORT y)
00401 {
00402     COORD coPos;
00403 
00404     coPos.X = x;
00405     coPos.Y = y;
00406     SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos);
00407 }
00408 
00409 
00410 VOID GetCursorXY (PSHORT x, PSHORT y)
00411 {
00412     CONSOLE_SCREEN_BUFFER_INFO csbi;
00413 
00414     GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
00415 
00416     *x = csbi.dwCursorPosition.X;
00417     *y = csbi.dwCursorPosition.Y;
00418 }
00419 
00420 
00421 SHORT GetCursorX (VOID)
00422 {
00423     CONSOLE_SCREEN_BUFFER_INFO csbi;
00424 
00425     GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
00426 
00427     return csbi.dwCursorPosition.X;
00428 }
00429 
00430 
00431 SHORT GetCursorY (VOID)
00432 {
00433     CONSOLE_SCREEN_BUFFER_INFO csbi;
00434 
00435     GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
00436 
00437     return csbi.dwCursorPosition.Y;
00438 }
00439 
00440 
00441 VOID GetScreenSize (PSHORT maxx, PSHORT maxy)
00442 {
00443     CONSOLE_SCREEN_BUFFER_INFO csbi;
00444 
00445     if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi))
00446     {
00447         csbi.dwSize.X = 80;
00448         csbi.dwSize.Y = 25;
00449     }
00450 
00451     if (maxx)
00452         *maxx = csbi.dwSize.X;
00453     if (maxy)
00454         *maxy = csbi.dwSize.Y;
00455 }
00456 
00457 
00458 VOID SetCursorType (BOOL bInsert, BOOL bVisible)
00459 {
00460     CONSOLE_CURSOR_INFO cci;
00461 
00462     cci.dwSize = bInsert ? 10 : 99;
00463     cci.bVisible = bVisible;
00464 
00465     SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci);
00466 }
00467 
00468 /* EOF */