adding page break on almost all help param and on help command.
[reactos.git] / reactos / subsys / system / cmd / console.c
1 /*
2 * CONSOLE.C - console input/output functions.
3 *
4 *
5 * History:
6 *
7 * 20-Jan-1999 (Eric Kohl <ekohl@abo.rhein-zeitung.de>)
8 * started
9 *
10 * 03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
11 * Remove all hardcode string to En.rc
12 *
13 * 01-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
14 * Added ConPrintfPaging and ConOutPrintfPaging
15 */
16
17
18
19 #include "precomp.h"
20 #include "resource.h"
21
22
23 #define OUTPUT_BUFFER_SIZE 4096
24
25
26 UINT InputCodePage;
27 UINT OutputCodePage;
28
29
30 VOID ConInDisable (VOID)
31 {
32 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
33 DWORD dwMode;
34
35 GetConsoleMode (hInput, &dwMode);
36 dwMode &= ~ENABLE_PROCESSED_INPUT;
37 SetConsoleMode (hInput, dwMode);
38 }
39
40
41 VOID ConInEnable (VOID)
42 {
43 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
44 DWORD dwMode;
45
46 GetConsoleMode (hInput, &dwMode);
47 dwMode |= ENABLE_PROCESSED_INPUT;
48 SetConsoleMode (hInput, dwMode);
49 }
50
51
52 VOID ConInDummy (VOID)
53 {
54 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
55 INPUT_RECORD dummy;
56 DWORD dwRead;
57
58 #ifdef _DEBUG
59 if (hInput == INVALID_HANDLE_VALUE)
60 DebugPrintf (_T("Invalid input handle!!!\n"));
61 #endif /* _DEBUG */
62 ReadConsoleInput (hInput, &dummy, 1, &dwRead);
63 }
64
65 VOID ConInFlush (VOID)
66 {
67 FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE));
68 }
69
70
71 VOID ConInKey (PINPUT_RECORD lpBuffer)
72 {
73 HANDLE hInput = GetStdHandle (STD_INPUT_HANDLE);
74 DWORD dwRead;
75
76 #ifdef _DEBUG
77 if (hInput == INVALID_HANDLE_VALUE)
78 DebugPrintf (_T("Invalid input handle!!!\n"));
79 #endif /* _DEBUG */
80
81 do
82 {
83 ReadConsoleInput (hInput, lpBuffer, 1, &dwRead);
84 if ((lpBuffer->EventType == KEY_EVENT) &&
85 (lpBuffer->Event.KeyEvent.bKeyDown == TRUE))
86 break;
87 }
88 while (TRUE);
89 }
90
91
92
93 VOID ConInString (LPTSTR lpInput, DWORD dwLength)
94 {
95 DWORD dwOldMode;
96 DWORD dwRead;
97 HANDLE hFile;
98
99 LPTSTR p;
100 DWORD i;
101 PCHAR pBuf;
102
103 #ifdef _UNICODE
104 pBuf = (PCHAR)malloc(dwLength);
105 #else
106 pBuf = lpInput;
107 #endif
108 ZeroMemory (lpInput, dwLength * sizeof(TCHAR));
109 hFile = GetStdHandle (STD_INPUT_HANDLE);
110 GetConsoleMode (hFile, &dwOldMode);
111
112 SetConsoleMode (hFile, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT);
113
114 ReadFile (hFile, (PVOID)pBuf, dwLength, &dwRead, NULL);
115
116 #ifdef _UNICODE
117 MultiByteToWideChar( InputCodePage, 0, pBuf, dwLength + 1, lpInput, dwLength + 1);
118 #endif
119 p = lpInput;
120 for (i = 0; i < dwRead; i++, p++)
121 {
122 if (*p == _T('\x0d'))
123 {
124 *p = _T('\0');
125 break;
126 }
127 }
128
129 #ifdef _UNICODE
130 free(pBuf);
131 #endif
132
133 SetConsoleMode (hFile, dwOldMode);
134 }
135
136 static VOID ConChar(TCHAR c, DWORD nStdHandle)
137 {
138 DWORD dwWritten;
139 CHAR cc;
140 #ifdef _UNICODE
141 CHAR as[2];
142 WCHAR ws[2];
143 ws[0] = c;
144 ws[1] = 0;
145 WideCharToMultiByte( OutputCodePage, 0, ws, 2, as, 2, NULL, NULL);
146 cc = as[0];
147 #else
148 cc = c;
149 #endif
150 WriteFile (GetStdHandle (nStdHandle),
151 &cc,
152 1,
153 &dwWritten,
154 NULL);
155 }
156
157 VOID ConOutChar (TCHAR c)
158 {
159 ConChar(c, STD_OUTPUT_HANDLE);
160 }
161
162 VOID ConPuts(LPTSTR szText, DWORD nStdHandle)
163 {
164 DWORD dwWritten;
165 PCHAR pBuf;
166 INT len;
167
168 len = _tcslen(szText);
169 #ifdef _UNICODE
170 pBuf = malloc(len + 1);
171 len = WideCharToMultiByte( OutputCodePage, 0, szText, len + 1, pBuf, len + 1, NULL, NULL) - 1;
172 #else
173 pBuf = szText;
174 #endif
175 WriteFile (GetStdHandle (nStdHandle),
176 pBuf,
177 len,
178 &dwWritten,
179 NULL);
180 WriteFile (GetStdHandle (nStdHandle),
181 "\n",
182 1,
183 &dwWritten,
184 NULL);
185 #ifdef UNICODE
186 free(pBuf);
187 #endif
188 }
189
190 VOID ConOutResPaging(BOOL NewPage, UINT resID)
191 {
192 TCHAR szMsg[RC_STRING_MAX_SIZE];
193 LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
194 ConOutPrintfPaging(NewPage, szMsg);
195 }
196
197 VOID ConOutResPuts (UINT resID)
198 {
199 TCHAR szMsg[RC_STRING_MAX_SIZE];
200 LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
201
202 ConPuts(szMsg, STD_OUTPUT_HANDLE);
203 }
204
205 VOID ConOutPuts (LPTSTR szText)
206 {
207 ConPuts(szText, STD_OUTPUT_HANDLE);
208 }
209
210
211 VOID ConPrintf(LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
212 {
213 INT len;
214 PCHAR pBuf;
215 TCHAR szOut[OUTPUT_BUFFER_SIZE];
216 DWORD dwWritten;
217
218 len = _vstprintf (szOut, szFormat, arg_ptr);
219 #ifdef _UNICODE
220 pBuf = malloc(len + 1);
221 len = WideCharToMultiByte( OutputCodePage, 0, szOut, len + 1, pBuf, len + 1, NULL, NULL) - 1;
222 #else
223 pBuf = szOut;
224 #endif
225 WriteFile (GetStdHandle (nStdHandle),
226 pBuf,
227 len,
228 &dwWritten,
229 NULL);
230 #ifdef UNICODE
231 free(pBuf);
232 #endif
233 }
234
235 VOID ConPrintfPaging(BOOL NewPage, LPTSTR szFormat, va_list arg_ptr, DWORD nStdHandle)
236 {
237 INT len;
238 PCHAR pBuf;
239 CONSOLE_SCREEN_BUFFER_INFO csbi;
240 TCHAR szOut[OUTPUT_BUFFER_SIZE];
241 DWORD dwWritten;
242 static int LineCount = 0; //used to count number of lines since last pause
243 int ScreenLines = 0; //used to see how big the screen is
244 int ScreenCol = 0; //the number of chars in a roow
245 int CharEL = 0; //chars since end of line
246 int i = 0;
247
248 if(NewPage == TRUE)
249 LineCount = 0;
250
251 //get the size of the visual screen that can be printed too
252 GetConsoleScreenBufferInfo(hConsole, &csbi);
253 //subtract 2 to account for "press any key..." and for the blank line at the end of PagePrompt()
254 ScreenLines = csbi.srWindow.Bottom - csbi.srWindow.Top - 2;
255 ScreenCol = csbi.srWindow.Right + 1;
256
257 //make sure they didnt make the screen to small
258 if(ScreenLines<2)
259 ConPrintf(szFormat, arg_ptr, nStdHandle);
260 //if more lines have been printed then screen size it is time to stop
261 if(LineCount >= ScreenLines)
262 {
263 if(PagePrompt() != PROMPT_YES)
264 {
265 return;
266 }
267 //reset the number of lines being printed
268 LineCount = 0;
269 }
270
271 len = _vstprintf (szOut, szFormat, arg_ptr);
272 #ifdef _UNICODE
273 pBuf = malloc(len + 1);
274 len = WideCharToMultiByte( OutputCodePage, 0, szOut, len + 1, pBuf, len + 1, NULL, NULL) - 1;
275 #else
276 pBuf = szOut;
277 #endif
278 WriteFile (GetStdHandle (nStdHandle),
279 pBuf,
280 len,
281 &dwWritten,
282 NULL);
283
284
285
286 if(len < ScreenCol)
287 {
288 //if it is smaller then a row then just check for \n
289 for(i = 0; i < len; i++)
290 if(szOut[i] == '\n')
291 LineCount++;
292
293 }
294 else
295 {
296 //if it is bigger then a row check for \n and a string longer then a row can handle
297 for(i = 0; i < len; i++)
298 {
299 if(szOut[i] == '\n')
300 {
301 CharEL = 0;
302 LineCount++;
303 }
304 else
305 {
306 CharEL++;
307 if(CharEL > ScreenCol)
308 {
309 CharEL = 0;
310 LineCount++;
311 }
312 }
313 }
314 }
315
316 #ifdef UNICODE
317 free(pBuf);
318 #endif
319 }
320
321 VOID ConOutFormatMessage (DWORD MessageId, ...)
322 {
323 TCHAR szMsg[RC_STRING_MAX_SIZE];
324 DWORD ret;
325 LPTSTR text;
326 va_list arg_ptr;
327
328 va_start (arg_ptr, MessageId);
329 ret = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
330 NULL,
331 MessageId,
332 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
333 (LPTSTR) &text,
334 0,
335 &arg_ptr);
336
337 va_end (arg_ptr);
338 if(ret > 0)
339 {
340 ConErrPuts (text);
341 LocalFree(text);
342 }
343 else
344 {
345 LoadString(CMD_ModuleHandle, STRING_CONSOLE_ERROR, szMsg, RC_STRING_MAX_SIZE);
346 ConErrPrintf(szMsg);
347 }
348 }
349
350 VOID ConOutPrintf (LPTSTR szFormat, ...)
351 {
352 va_list arg_ptr;
353
354 va_start (arg_ptr, szFormat);
355 ConPrintf(szFormat, arg_ptr, STD_OUTPUT_HANDLE);
356 va_end (arg_ptr);
357 }
358
359 VOID ConOutPrintfPaging (BOOL NewPage, LPTSTR szFormat, ...)
360 {
361 va_list arg_ptr;
362
363 va_start (arg_ptr, szFormat);
364 ConPrintfPaging(NewPage, szFormat, arg_ptr, STD_OUTPUT_HANDLE);
365 va_end (arg_ptr);
366 }
367
368 VOID ConErrChar (TCHAR c)
369 {
370 ConChar(c, STD_ERROR_HANDLE);
371 }
372
373
374 VOID ConErrResPuts (UINT resID)
375 {
376 TCHAR szMsg[RC_STRING_MAX_SIZE];
377 LoadString(CMD_ModuleHandle, resID, szMsg, RC_STRING_MAX_SIZE);
378 ConPuts(szMsg, STD_ERROR_HANDLE);
379 }
380
381 VOID ConErrPuts (LPTSTR szText)
382 {
383 ConPuts(szText, STD_ERROR_HANDLE);
384 }
385
386
387 VOID ConErrPrintf (LPTSTR szFormat, ...)
388 {
389 va_list arg_ptr;
390
391 va_start (arg_ptr, szFormat);
392 ConPrintf(szFormat, arg_ptr, STD_ERROR_HANDLE);
393 va_end (arg_ptr);
394 }
395
396 #ifdef _DEBUG
397 VOID DebugPrintf (LPTSTR szFormat, ...)
398 {
399 va_list arg_ptr;
400
401 va_start (arg_ptr, szFormat);
402 ConPrintf(szFormat, arg_ptr, STD_ERROR_HANDLE);
403 va_end (arg_ptr);
404 #if 0
405 TCHAR szOut[OUTPUT_BUFFER_SIZE];
406 va_start (arg_ptr, szFormat);
407 _vstprintf (szOut, szFormat, arg_ptr);
408 OutputDebugString (szOut);
409 va_end (arg_ptr);
410 #endif
411 }
412 #endif /* _DEBUG */
413
414 VOID SetCursorXY (SHORT x, SHORT y)
415 {
416 COORD coPos;
417
418 coPos.X = x;
419 coPos.Y = y;
420 SetConsoleCursorPosition (GetStdHandle (STD_OUTPUT_HANDLE), coPos);
421 }
422
423
424 VOID GetCursorXY (PSHORT x, PSHORT y)
425 {
426 CONSOLE_SCREEN_BUFFER_INFO csbi;
427
428 GetConsoleScreenBufferInfo (hConsole, &csbi);
429
430 *x = csbi.dwCursorPosition.X;
431 *y = csbi.dwCursorPosition.Y;
432 }
433
434
435 SHORT GetCursorX (VOID)
436 {
437 CONSOLE_SCREEN_BUFFER_INFO csbi;
438
439 GetConsoleScreenBufferInfo (hConsole, &csbi);
440
441 return csbi.dwCursorPosition.X;
442 }
443
444
445 SHORT GetCursorY (VOID)
446 {
447 CONSOLE_SCREEN_BUFFER_INFO csbi;
448
449 GetConsoleScreenBufferInfo (hConsole, &csbi);
450
451 return csbi.dwCursorPosition.Y;
452 }
453
454
455 VOID GetScreenSize (PSHORT maxx, PSHORT maxy)
456 {
457 CONSOLE_SCREEN_BUFFER_INFO csbi;
458
459 GetConsoleScreenBufferInfo (hConsole, &csbi);
460
461 if (maxx)
462 *maxx = csbi.dwSize.X;
463 if (maxy)
464 *maxy = csbi.dwSize.Y;
465 }
466
467
468 VOID SetCursorType (BOOL bInsert, BOOL bVisible)
469 {
470 CONSOLE_CURSOR_INFO cci;
471
472 cci.dwSize = bInsert ? 10 : 99;
473 cci.bVisible = bVisible;
474
475 SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cci);
476 }
477
478 /* EOF */