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
ConInDummy (VOID
)
54 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
58 if (hInput
== INVALID_HANDLE_VALUE
)
59 WARN ("Invalid input handle!!!\n");
60 ReadConsoleInput (hInput
, &dummy
, 1, &dwRead
);
63 VOID
ConInFlush (VOID
)
65 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE
));
69 VOID
ConInKey (PINPUT_RECORD lpBuffer
)
71 HANDLE hInput
= GetStdHandle (STD_INPUT_HANDLE
);
74 if (hInput
== INVALID_HANDLE_VALUE
)
75 WARN ("Invalid input handle!!!\n");
79 ReadConsoleInput (hInput
, lpBuffer
, 1, &dwRead
);
80 if ((lpBuffer
->EventType
== KEY_EVENT
) &&
81 (lpBuffer
->Event
.KeyEvent
.bKeyDown
== TRUE
))
88 VOID
ConInString (LPTSTR lpInput
, DWORD dwLength
)
99 pBuf
= (PCHAR
)cmd_alloc(dwLength
);
103 ZeroMemory (lpInput
, dwLength
* sizeof(TCHAR
));
104 hFile
= GetStdHandle (STD_INPUT_HANDLE
);
105 GetConsoleMode (hFile
, &dwOldMode
);
107 SetConsoleMode (hFile
, ENABLE_LINE_INPUT
| ENABLE_ECHO_INPUT
);
109 ReadFile (hFile
, (PVOID
)pBuf
, dwLength
, &dwRead
, NULL
);
112 MultiByteToWideChar( InputCodePage
, 0, pBuf
, dwLength
+ 1, lpInput
, dwLength
+ 1);
115 for (i
= 0; i
< dwRead
; i
++, p
++)
117 if (*p
== _T('\x0d'))
128 SetConsoleMode (hFile
, dwOldMode
);
131 static VOID
ConChar(TCHAR c
, DWORD nStdHandle
)
140 WideCharToMultiByte( OutputCodePage
, 0, ws
, 2, as
, 2, NULL
, NULL
);
145 WriteFile (GetStdHandle (nStdHandle
),
152 VOID
ConOutChar (TCHAR c
)
154 ConChar(c
, STD_OUTPUT_HANDLE
);
157 VOID
ConPuts(LPTSTR szText
, DWORD nStdHandle
)
164 len
= _tcslen(szText
);
166 pBuf
= cmd_alloc(len
+ 1);
167 len
= WideCharToMultiByte( OutputCodePage
, 0, szText
, len
+ 1, pBuf
, len
+ 1, NULL
, NULL
) - 1;
171 hStdHandle
= GetStdHandle(nStdHandle
);
173 WriteFile (hStdHandle
,
178 WriteFile (hStdHandle
,
188 VOID
ConOutResPaging(BOOL NewPage
, UINT resID
)
190 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
191 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
192 ConOutPrintfPaging(NewPage
, szMsg
);
195 VOID
ConOutResPuts (UINT resID
)
197 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
198 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
200 ConPuts(szMsg
, STD_OUTPUT_HANDLE
);
203 VOID
ConOutPuts (LPTSTR szText
)
205 ConPuts(szText
, STD_OUTPUT_HANDLE
);
209 VOID
ConPrintf(LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
213 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
216 len
= _vstprintf (szOut
, szFormat
, arg_ptr
);
218 pBuf
= cmd_alloc(len
+ 1);
219 len
= WideCharToMultiByte( OutputCodePage
, 0, szOut
, len
+ 1, pBuf
, len
+ 1, NULL
, NULL
) - 1;
224 WriteFile (GetStdHandle (nStdHandle
),
236 INT
ConPrintfPaging(BOOL NewPage
, LPTSTR szFormat
, va_list arg_ptr
, DWORD nStdHandle
)
240 CONSOLE_SCREEN_BUFFER_INFO csbi
;
241 TCHAR szOut
[OUTPUT_BUFFER_SIZE
];
244 /* used to count number of lines since last pause */
245 static int LineCount
= 0;
247 /* used to see how big the screen is */
250 /* the number of chars in a roow */
253 /* chars since start of line */
261 /* rest LineCount and return if no string have been given */
262 if (szFormat
== NULL
)
266 //get the size of the visual screen that can be printed too
267 if (!GetConsoleScreenBufferInfo(hConsole
, &csbi
))
269 // we assuming its a file handle
270 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
273 //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
274 ScreenLines
= (csbi
.srWindow
.Bottom
- csbi
.srWindow
.Top
) - 4;
275 ScreenCol
= (csbi
.srWindow
.Right
- csbi
.srWindow
.Left
) + 1;
277 //make sure they didnt make the screen to small
280 ConPrintf(szFormat
, arg_ptr
, nStdHandle
);
284 len
= _vstprintf (szOut
, szFormat
, arg_ptr
);
286 pBuf
= cmd_alloc(len
+ 1);
287 len
= WideCharToMultiByte( OutputCodePage
, 0, szOut
, len
+ 1, pBuf
, len
+ 1, NULL
, NULL
) - 1;
292 for(i
= 0; i
< len
; i
++)
294 // search 'end of string' '\n' or 'end of screen line'
295 for(; (i
< len
) && (pBuf
[i
] != _T('\n') && (CharSL
<ScreenCol
)) ; i
++)
298 WriteFile (GetStdHandle (nStdHandle
),&pBuf
[i
-CharSL
],sizeof(CHAR
)*(CharSL
+1),&dwWritten
,NULL
);
302 if(LineCount
>= ScreenLines
)
304 if(_strnicmp(&pBuf
[i
], "\n", 2)!=0)
305 WriteFile (GetStdHandle (nStdHandle
),_T("\n"),sizeof(CHAR
),&dwWritten
,NULL
);
307 if(PagePrompt() != PROMPT_YES
)
314 //reset the number of lines being printed
327 VOID
ConErrFormatMessage (DWORD MessageId
, ...)
329 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
334 va_start (arg_ptr
, MessageId
);
335 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
338 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
351 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
356 VOID
ConOutFormatMessage (DWORD MessageId
, ...)
358 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
363 va_start (arg_ptr
, MessageId
);
364 ret
= FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
,
367 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
380 LoadString(CMD_ModuleHandle
, STRING_CONSOLE_ERROR
, szMsg
, RC_STRING_MAX_SIZE
);
385 VOID
ConOutPrintf (LPTSTR szFormat
, ...)
389 va_start (arg_ptr
, szFormat
);
390 ConPrintf(szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
394 INT
ConOutPrintfPaging (BOOL NewPage
, LPTSTR szFormat
, ...)
399 va_start (arg_ptr
, szFormat
);
400 iReturn
= ConPrintfPaging(NewPage
, szFormat
, arg_ptr
, STD_OUTPUT_HANDLE
);
405 VOID
ConErrChar (TCHAR c
)
407 ConChar(c
, STD_ERROR_HANDLE
);
411 VOID
ConErrResPuts (UINT resID
)
413 TCHAR szMsg
[RC_STRING_MAX_SIZE
];
414 LoadString(CMD_ModuleHandle
, resID
, szMsg
, RC_STRING_MAX_SIZE
);
415 ConPuts(szMsg
, STD_ERROR_HANDLE
);
418 VOID
ConErrPuts (LPTSTR szText
)
420 ConPuts(szText
, STD_ERROR_HANDLE
);
424 VOID
ConErrPrintf (LPTSTR szFormat
, ...)
428 va_start (arg_ptr
, szFormat
);
429 ConPrintf(szFormat
, arg_ptr
, STD_ERROR_HANDLE
);
433 VOID
SetCursorXY (SHORT x
, SHORT y
)
439 SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE
), coPos
);
443 VOID
GetCursorXY (PSHORT x
, PSHORT y
)
445 CONSOLE_SCREEN_BUFFER_INFO csbi
;
447 GetConsoleScreenBufferInfo (hConsole
, &csbi
);
449 *x
= csbi
.dwCursorPosition
.X
;
450 *y
= csbi
.dwCursorPosition
.Y
;
454 SHORT
GetCursorX (VOID
)
456 CONSOLE_SCREEN_BUFFER_INFO csbi
;
458 GetConsoleScreenBufferInfo (hConsole
, &csbi
);
460 return csbi
.dwCursorPosition
.X
;
464 SHORT
GetCursorY (VOID
)
466 CONSOLE_SCREEN_BUFFER_INFO csbi
;
468 GetConsoleScreenBufferInfo (hConsole
, &csbi
);
470 return csbi
.dwCursorPosition
.Y
;
474 VOID
GetScreenSize (PSHORT maxx
, PSHORT maxy
)
476 CONSOLE_SCREEN_BUFFER_INFO csbi
;
478 GetConsoleScreenBufferInfo (hConsole
, &csbi
);
481 *maxx
= csbi
.dwSize
.X
;
483 *maxy
= csbi
.dwSize
.Y
;
487 VOID
SetCursorType (BOOL bInsert
, BOOL bVisible
)
489 CONSOLE_CURSOR_INFO cci
;
491 cci
.dwSize
= bInsert
? 10 : 99;
492 cci
.bVisible
= bVisible
;
494 SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE
), &cci
);