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
, NULL
, NULL
);
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
);
169 ConWrite(_T("\r\n"), 2, nStdHandle
);
172 VOID
ConOutResPaging(BOOL NewPage
, UINT resID
)
174 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
175 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
176 ConOutPrintfPaging(NewPage
, szMsg
);
179 VOID
ConOutResPuts (UINT resID
)
181 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
182 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
184 ConPuts(szMsg
, STD_OUTPUT_HANDLE
);
187 VOID
ConOutPuts (LPTSTR szText
)
189 ConPuts(szText
, STD_OUTPUT_HANDLE
);
193 VOID
ConPrintf(LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
195 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
196 ConWrite(szOut
, _vstprintf(szOut
, szFormat
, arg_ptr
), nStdHandle
);
199 INT
ConPrintfPaging(BOOL NewPage
, LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
202 CONSOLE_SCREEN_BUFFER_INFO csbi
;
203 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
205 HANDLE hOutput
= GetStdHandle(nStdHandle
);
207 /* used to count number of lines since last pause */
208 static int LineCount
= 0;
210 /* used to see how big the screen is */
213 /* chars since start of line */
221 /* rest LineCount and return if no string have been given */
222 if (szFormat
== NULL
)
226 //get the size of the visual screen that can be printed too
227 if (!GetConsoleScreenBufferInfo(hOutput
, &csbi
))
229 // we assuming its a file handle
230 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
233 //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
234 ScreenLines
= (csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
) - 4;
235 CharSL
= csbi
.dwCursorPosition
.X
;
237 //make sure they didnt make the screen to small
240 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
244 len
= _vstprintf (szOut
, szFormat
, arg_ptr
);
248 // Search until the end of a line is reached
249 if (szOut
[i
++] != _T('\n') && ++CharSL
< csbi
.dwSize
.X
)
255 if(LineCount
>= ScreenLines
)
257 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
260 if(PagePrompt() != PROMPT_YES
)
264 //reset the number of lines being printed
269 WriteConsole(hOutput
, &szOut
[from
], i
-from
, &dwWritten
, NULL
);
274 VOID
ConErrFormatMessage (DWORD MessageId
, ...)
276 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
281 va_start (arg_ptr
, MessageId
);
282 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
285 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
298 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
303 VOID
ConOutFormatMessage (DWORD MessageId
, ...)
305 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
310 va_start (arg_ptr
, MessageId
);
311 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
314 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
327 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
332 VOID
ConOutResPrintf (UINT resID
, ...)
334 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
337 va_start (arg_ptr
, resID
);
338 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
339 ConPrintf(szMsg
, arg_ptr
, STD_OUTPUT_HANDLE
);
343 VOID
ConOutPrintf (LPTSTR szFormat
, ...)
347 va_start (arg_ptr
, szFormat
);
348 ConPrintf(szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
352 INT
ConOutPrintfPaging (BOOL NewPage
, LPTSTR szFormat
, ...)
357 va_start (arg_ptr
, szFormat
);
358 iReturn
= ConPrintfPaging(NewPage
, szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
363 VOID
ConErrChar (TCHAR c
)
365 ConWrite(&c
, 1, STD_ERROR_HANDLE
);
369 VOID
ConErrResPuts (UINT resID
)
371 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
372 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
373 ConPuts(szMsg
, STD_ERROR_HANDLE
);
376 VOID
ConErrPuts (LPTSTR szText
)
378 ConPuts(szText
, STD_ERROR_HANDLE
);
382 VOID
ConErrResPrintf (UINT resID
, ...)
384 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
387 va_start (arg_ptr
, resID
);
388 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
389 ConPrintf(szMsg
, arg_ptr
, STD_ERROR_HANDLE
);
393 VOID
ConErrPrintf (LPTSTR szFormat
, ...)
397 va_start (arg_ptr
, szFormat
);
398 ConPrintf(szFormat
, arg_ptr
, STD_ERROR_HANDLE
);
402 VOID
SetCursorXY (SHORT x
, SHORT y
)
408 SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE
), coPos
);
412 VOID
GetCursorXY (PSHORT x
, PSHORT y
)
414 CONSOLE_SCREEN_BUFFER_INFO csbi
;
416 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
418 *x
= csbi
.dwCursorPosition
.X
;
419 *y
= csbi
.dwCursorPosition
.Y
;
423 SHORT
GetCursorX (VOID
)
425 CONSOLE_SCREEN_BUFFER_INFO csbi
;
427 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
429 return csbi
.dwCursorPosition
.X
;
433 SHORT
GetCursorY (VOID
)
435 CONSOLE_SCREEN_BUFFER_INFO csbi
;
437 GetConsoleScreenBufferInfo (GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
);
439 return csbi
.dwCursorPosition
.Y
;
443 VOID
GetScreenSize (PSHORT maxx
, PSHORT maxy
)
445 CONSOLE_SCREEN_BUFFER_INFO csbi
;
447 if (!GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE
), &csbi
))
454 *maxx
= csbi
.dwSize
.X
;
456 *maxy
= csbi
.dwSize
.Y
;
460 VOID
SetCursorType (BOOL bInsert
, BOOL bVisible
)
462 CONSOLE_CURSOR_INFO cci
;
464 cci
.dwSize
= bInsert
? 10 : 99;
465 cci
.bVisible
= bVisible
;
467 SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE
), &cci
);