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
22 #define OUTPUT_BUFFER_SIZE 4096
29 VOID
ConInDisable (VOID
)
31 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
34 GetConsoleMode (hInput
, &dwMode
);
35 dwMode
&= ~ENABLE_PROCESSED_INPUT
;
36 SetConsoleMode (hInput
, dwMode
);
40 VOID
ConInEnable (VOID
)
42 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
45 GetConsoleMode (hInput
, &dwMode
);
46 dwMode
|= ENABLE_PROCESSED_INPUT
;
47 SetConsoleMode (hInput
, dwMode
);
51 VOID
ConInFlush (VOID
)
53 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE
));
57 VOID
ConInKey (PINPUT_RECORD lpBuffer
)
59 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
62 if (hInput
== INVALID_HANDLE_VALUE
)
63 WARN ("Invalid input handle!!!\n");
67 ReadConsoleInput (hInput
, lpBuffer
, 1, &dwRead
);
68 if ((lpBuffer
->EventType
== KEY_EVENT
) &&
69 (lpBuffer
->Event
.KeyEvent
.bKeyDown
== TRUE
))
76 VOID
ConInString (LPTSTR lpInput
, DWORD dwLength
)
86 pBuf
= (PCHAR
)cmd_alloc(dwLength
- 1);
90 ZeroMemory (lpInput
, dwLength
* sizeof(TCHAR
));
91 hFile
= GetStdHandle (STD_INPUT_HANDLE
);
92 GetConsoleMode (hFile
, &dwOldMode
);
94 SetConsoleMode (hFile
, ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
);
96 ReadFile (hFile
, (PVOID
)pBuf
, dwLength
- 1, &dwRead
, NULL
);
99 MultiByteToWideChar(InputCodePage
, 0, pBuf
, dwRead
, lpInput
, dwLength
- 1);
102 for (p
= lpInput
; *p
; p
++)
104 if (*p
== _T('\x0d'))
111 SetConsoleMode (hFile
, dwOldMode
);
114 static VOID
ConWrite(TCHAR
*str
, DWORD len
, DWORD nStdHandle
)
117 HANDLE hOutput
= GetStdHandle(nStdHandle
);
119 if (WriteConsole(hOutput
, str
, len
, &dwWritten
, NULL
))
122 /* We're writing to a file or pipe instead of the console. Convert the
123 * string from TCHARs to the desired output format, if the two differ */
127 WCHAR
*buffer
= cmd_alloc(len
* sizeof(WCHAR
));
130 error_out_of_memory();
133 len
= MultiByteToWideChar(OutputCodePage
, 0, str
, len
, buffer
, len
);
136 WriteFile(hOutput
, str
, len
* sizeof(WCHAR
), &dwWritten
, NULL
);
144 CHAR
*buffer
= cmd_alloc(len
* MB_LEN_MAX
* sizeof(CHAR
));
147 error_out_of_memory();
150 len
= WideCharToMultiByte(OutputCodePage
, 0, str
, len
, buffer
, len
* MB_LEN_MAX
, NULL
, NULL
);
153 WriteFile(hOutput
, str
, len
, &dwWritten
, NULL
);
160 VOID
ConOutChar (TCHAR c
)
162 ConWrite(&c
, 1, STD_OUTPUT_HANDLE
);
165 VOID
ConPuts(LPTSTR szText
, DWORD nStdHandle
)
167 ConWrite(szText
, _tcslen(szText
), nStdHandle
);
170 VOID
ConOutResPaging(BOOL NewPage
, UINT resID
)
172 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
173 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
174 ConOutPrintfPaging(NewPage
, szMsg
);
177 VOID
ConOutResPuts (UINT resID
)
179 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
180 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
182 ConPuts(szMsg
, STD_OUTPUT_HANDLE
);
185 VOID
ConOutPuts (LPTSTR szText
)
187 ConPuts(szText
, STD_OUTPUT_HANDLE
);
191 VOID
ConPrintf(LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
193 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
194 ConWrite(szOut
, _vstprintf(szOut
, szFormat
, arg_ptr
), nStdHandle
);
197 INT
ConPrintfPaging(BOOL NewPage
, LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
200 CONSOLE_SCREEN_BUFFER_INFO csbi
;
201 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
203 HANDLE hOutput
= GetStdHandle(nStdHandle
);
205 /* used to count number of lines since last pause */
206 static int LineCount
= 0;
208 /* used to see how big the screen is */
211 /* chars since start of line */
219 /* rest LineCount and return if no string have been given */
220 if (szFormat
== NULL
)
224 //get the size of the visual screen that can be printed too
225 if (!GetConsoleScreenBufferInfo(hOutput
, &csbi
))
227 // we assuming its a file handle
228 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
231 //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
232 ScreenLines
= (csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
) - 4;
233 CharSL
= csbi
.dwCursorPosition
.X
;
235 //make sure they didnt make the screen to small
238 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
242 len
= _vstprintf (szOut
, szFormat
, arg_ptr
);
246 // Search until the end of a line is reached
247 if (szOut
[i
++] != _T('\n') && ++CharSL
< csbi
.dwSize
.X
)
253 if(LineCount
>= ScreenLines
)
255 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
258 if(PagePrompt() != PROMPT_YES
)
262 //reset the number of lines being printed
267 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
272 VOID
ConErrFormatMessage (DWORD MessageId
, ...)
274 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
279 va_start (arg_ptr
, MessageId
);
280 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
283 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
296 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
301 VOID
ConOutFormatMessage (DWORD MessageId
, ...)
303 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
308 va_start (arg_ptr
, MessageId
);
309 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
312 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
325 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
330 VOID
ConOutResPrintf (UINT resID
, ...)
332 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
335 va_start (arg_ptr
, resID
);
336 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
337 ConPrintf(szMsg
, arg_ptr
, STD_OUTPUT_HANDLE
);
341 VOID
ConOutPrintf (LPTSTR szFormat
, ...)
345 va_start (arg_ptr
, szFormat
);
346 ConPrintf(szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
350 INT
ConOutPrintfPaging (BOOL NewPage
, LPTSTR szFormat
, ...)
355 va_start (arg_ptr
, szFormat
);
356 iReturn
= ConPrintfPaging(NewPage
, szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
361 VOID
ConErrChar (TCHAR c
)
363 ConWrite(&c
, 1, STD_ERROR_HANDLE
);
367 VOID
ConErrResPuts (UINT resID
)
369 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
370 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
371 ConPuts(szMsg
, STD_ERROR_HANDLE
);
374 VOID
ConErrPuts (LPTSTR szText
)
376 ConPuts(szText
, STD_ERROR_HANDLE
);
380 VOID
ConErrResPrintf (UINT resID
, ...)
382 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
385 va_start (arg_ptr
, resID
);
386 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
387 ConPrintf(szMsg
, arg_ptr
, STD_ERROR_HANDLE
);
391 VOID
ConErrPrintf (LPTSTR szFormat
, ...)
395 va_start (arg_ptr
, szFormat
);
396 ConPrintf(szFormat
, arg_ptr
, STD_ERROR_HANDLE
);
400 VOID
SetCursorXY (SHORT x
, SHORT y
)
406 SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE
), coPos
);
410 VOID
GetCursorXY (PSHORT x
, PSHORT y
)
412 CONSOLE_SCREEN_BUFFER_INFO csbi
;
414 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
416 *x
= csbi
.dwCursorPosition
.X
;
417 *y
= csbi
.dwCursorPosition
.Y
;
421 SHORT
GetCursorX (VOID
)
423 CONSOLE_SCREEN_BUFFER_INFO csbi
;
425 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
427 return csbi
.dwCursorPosition
.X
;
431 SHORT
GetCursorY (VOID
)
433 CONSOLE_SCREEN_BUFFER_INFO csbi
;
435 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
437 return csbi
.dwCursorPosition
.Y
;
441 VOID
GetScreenSize (PSHORT maxx
, PSHORT maxy
)
443 CONSOLE_SCREEN_BUFFER_INFO csbi
;
445 if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
))
452 *maxx
= csbi
.dwSize
.X
;
454 *maxy
= csbi
.dwSize
.Y
;
458 VOID
SetCursorType (BOOL bInsert
, BOOL bVisible
)
460 CONSOLE_CURSOR_INFO cci
;
462 cci
.dwSize
= bInsert
? 10 : 99;
463 cci
.bVisible
= bVisible
;
465 SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE
), &cci
);