2 * CONSOLE.C - console input/output functions.
7 * 20-Jan-1999 (Eric Kohl)
10 * 03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
11 * Remove all hardcode string to En.rc
13 * 01-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
14 * Added ConPrintfPaging and ConOutPrintfPaging
16 * 02-Feb-2007 (Paolo Devoti) <devotip at gmail.com>)
17 * Fixed ConPrintfPaging
23 #define OUTPUT_BUFFER_SIZE 4096
30 VOID
ConInDisable (VOID
)
32 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
35 GetConsoleMode (hInput
, &dwMode
);
36 dwMode
&= ~ENABLE_PROCESSED_INPUT
;
37 SetConsoleMode (hInput
, dwMode
);
41 VOID
ConInEnable (VOID
)
43 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
46 GetConsoleMode (hInput
, &dwMode
);
47 dwMode
|= ENABLE_PROCESSED_INPUT
;
48 SetConsoleMode (hInput
, dwMode
);
52 VOID
ConInFlush (VOID
)
54 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE
));
58 VOID
ConInKey (PINPUT_RECORD lpBuffer
)
60 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
63 if (hInput
== INVALID_HANDLE_VALUE
)
64 WARN ("Invalid input handle!!!\n");
68 ReadConsoleInput (hInput
, lpBuffer
, 1, &dwRead
);
69 if ((lpBuffer
->EventType
== KEY_EVENT
) &&
70 (lpBuffer
->Event
.KeyEvent
.bKeyDown
== TRUE
))
77 VOID
ConInString (LPTSTR lpInput
, DWORD dwLength
)
87 pBuf
= (PCHAR
)cmd_alloc(dwLength
- 1);
91 ZeroMemory (lpInput
, dwLength
* sizeof(TCHAR
));
92 hFile
= GetStdHandle (STD_INPUT_HANDLE
);
93 GetConsoleMode (hFile
, &dwOldMode
);
95 SetConsoleMode (hFile
, ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
);
97 ReadFile (hFile
, (PVOID
)pBuf
, dwLength
- 1, &dwRead
, NULL
);
100 MultiByteToWideChar(InputCodePage
, 0, pBuf
, dwRead
, lpInput
, dwLength
- 1);
103 for (p
= lpInput
; *p
; p
++)
105 if (*p
== _T('\x0d'))
112 SetConsoleMode (hFile
, dwOldMode
);
115 static VOID
ConWrite(TCHAR
*str
, DWORD len
, DWORD nStdHandle
)
118 HANDLE hOutput
= GetStdHandle(nStdHandle
);
120 if (WriteConsole(hOutput
, str
, len
, &dwWritten
, NULL
))
123 /* We're writing to a file or pipe instead of the console. Convert the
124 * string from TCHARs to the desired output format, if the two differ */
128 WCHAR
*buffer
= cmd_alloc(len
* sizeof(WCHAR
));
131 error_out_of_memory();
134 len
= MultiByteToWideChar(OutputCodePage
, 0, str
, len
, buffer
, len
);
137 WriteFile(hOutput
, str
, len
* sizeof(WCHAR
), &dwWritten
, NULL
);
145 CHAR
*buffer
= cmd_alloc(len
* MB_LEN_MAX
* sizeof(CHAR
));
148 error_out_of_memory();
151 len
= WideCharToMultiByte(OutputCodePage
, 0, str
, len
, buffer
, len
* MB_LEN_MAX
, NULL
, NULL
);
154 WriteFile(hOutput
, str
, len
, &dwWritten
, NULL
);
161 VOID
ConOutChar (TCHAR c
)
163 ConWrite(&c
, 1, STD_OUTPUT_HANDLE
);
166 VOID
ConPuts(LPTSTR szText
, DWORD nStdHandle
)
168 ConWrite(szText
, _tcslen(szText
), nStdHandle
);
171 VOID
ConOutResPaging(BOOL NewPage
, UINT resID
)
173 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
174 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
175 ConOutPrintfPaging(NewPage
, szMsg
);
178 VOID
ConOutResPuts (UINT resID
)
180 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
181 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
183 ConPuts(szMsg
, STD_OUTPUT_HANDLE
);
186 VOID
ConOutPuts (LPTSTR szText
)
188 ConPuts(szText
, STD_OUTPUT_HANDLE
);
192 VOID
ConPrintf(LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
194 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
195 ConWrite(szOut
, _vstprintf(szOut
, szFormat
, arg_ptr
), nStdHandle
);
198 INT
ConPrintfPaging(BOOL NewPage
, LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
201 CONSOLE_SCREEN_BUFFER_INFO csbi
;
202 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
204 HANDLE hOutput
= GetStdHandle(nStdHandle
);
206 /* used to count number of lines since last pause */
207 static int LineCount
= 0;
209 /* used to see how big the screen is */
212 /* chars since start of line */
220 /* rest LineCount and return if no string have been given */
221 if (szFormat
== NULL
)
225 //get the size of the visual screen that can be printed too
226 if (!GetConsoleScreenBufferInfo(hOutput
, &csbi
))
228 // we assuming its a file handle
229 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
232 //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
233 ScreenLines
= (csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
) - 4;
234 CharSL
= csbi
.dwCursorPosition
.X
;
236 //make sure they didnt make the screen to small
239 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
243 len
= _vstprintf (szOut
, szFormat
, arg_ptr
);
247 // Search until the end of a line is reached
248 if (szOut
[i
++] != _T('\n') && ++CharSL
< csbi
.dwSize
.X
)
254 if(LineCount
>= ScreenLines
)
256 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
259 if(PagePrompt() != PROMPT_YES
)
263 //reset the number of lines being printed
268 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
273 VOID
ConErrFormatMessage (DWORD MessageId
, ...)
275 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
280 va_start (arg_ptr
, MessageId
);
281 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
284 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
297 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
302 VOID
ConOutFormatMessage (DWORD MessageId
, ...)
304 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
309 va_start (arg_ptr
, MessageId
);
310 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
313 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
326 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
331 VOID
ConOutResPrintf (UINT resID
, ...)
333 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
336 va_start (arg_ptr
, resID
);
337 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
338 ConPrintf(szMsg
, arg_ptr
, STD_OUTPUT_HANDLE
);
342 VOID
ConOutPrintf (LPTSTR szFormat
, ...)
346 va_start (arg_ptr
, szFormat
);
347 ConPrintf(szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
351 INT
ConOutPrintfPaging (BOOL NewPage
, LPTSTR szFormat
, ...)
356 va_start (arg_ptr
, szFormat
);
357 iReturn
= ConPrintfPaging(NewPage
, szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
362 VOID
ConErrChar (TCHAR c
)
364 ConWrite(&c
, 1, STD_ERROR_HANDLE
);
368 VOID
ConErrResPuts (UINT resID
)
370 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
371 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
372 ConPuts(szMsg
, STD_ERROR_HANDLE
);
375 VOID
ConErrPuts (LPTSTR szText
)
377 ConPuts(szText
, STD_ERROR_HANDLE
);
381 VOID
ConErrResPrintf (UINT resID
, ...)
383 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
386 va_start (arg_ptr
, resID
);
387 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
388 ConPrintf(szMsg
, arg_ptr
, STD_ERROR_HANDLE
);
392 VOID
ConErrPrintf (LPTSTR szFormat
, ...)
396 va_start (arg_ptr
, szFormat
);
397 ConPrintf(szFormat
, arg_ptr
, STD_ERROR_HANDLE
);
401 VOID
SetCursorXY (SHORT x
, SHORT y
)
407 SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE
), coPos
);
411 VOID
GetCursorXY (PSHORT x
, PSHORT y
)
413 CONSOLE_SCREEN_BUFFER_INFO csbi
;
415 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
417 *x
= csbi
.dwCursorPosition
.X
;
418 *y
= csbi
.dwCursorPosition
.Y
;
422 SHORT
GetCursorX (VOID
)
424 CONSOLE_SCREEN_BUFFER_INFO csbi
;
426 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
428 return csbi
.dwCursorPosition
.X
;
432 SHORT
GetCursorY (VOID
)
434 CONSOLE_SCREEN_BUFFER_INFO csbi
;
436 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
438 return csbi
.dwCursorPosition
.Y
;
442 VOID
GetScreenSize (PSHORT maxx
, PSHORT maxy
)
444 CONSOLE_SCREEN_BUFFER_INFO csbi
;
446 if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
))
453 *maxx
= csbi
.dwSize
.X
;
455 *maxy
= csbi
.dwSize
.Y
;
459 VOID
SetCursorType (BOOL bInsert
, BOOL bVisible
)
461 CONSOLE_CURSOR_INFO cci
;
463 cci
.dwSize
= bInsert
? 10 : 99;
464 cci
.bVisible
= bVisible
;
466 SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE
), &cci
);