ReactOS 0.4.15-dev-7670-g69b08be
more.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS More Command
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Displays text stream from STDIN or from an arbitrary number
5 * of files to STDOUT, with screen capabilities (more than CAT,
6 * but less than LESS ^^).
7 * COPYRIGHT: Copyright 1999 Paolo Pantaleo
8 * Copyright 2003 Timothy Schepens
9 * Copyright 2016-2021 Hermes Belusca-Maito
10 * Copyright 2021 Katayama Hirofumi MZ
11 */
12/*
13 * MORE.C - external command.
14 *
15 * clone from 4nt more command
16 *
17 * 26 Sep 1999 - Paolo Pantaleo <paolopan@freemail.it>
18 * started
19 *
20 * Oct 2003 - Timothy Schepens <tischepe at fastmail dot fm>
21 * use window size instead of buffer size.
22 */
23
24#include <stdio.h>
25#include <stdlib.h>
26
27#include <windef.h>
28#include <winbase.h>
29#include <winnt.h>
30#include <winnls.h>
31#include <winreg.h>
32#include <winuser.h>
33
34#include <conutils.h>
35#include <strsafe.h>
36
37#include "resource.h"
38
39/* PagePrompt statistics for the current file */
40DWORD dwFileSize; // In bytes
42// The average number of bytes per character is equal to
43// dwSumReadBytes / dwSumReadChars. Note that dwSumReadChars
44// will never be == 0 when ConWritePaging (and possibly PagePrompt)
45// is called.
46
47/* Handles for file and console */
51
52/* Enable/Disable extensions */
53BOOL bEnableExtensions = TRUE; // FIXME: By default, it should be FALSE.
54
55/* Parser flags */
56#define FLAG_HELP (1 << 0)
57#define FLAG_E (1 << 1)
58#define FLAG_C (1 << 2)
59#define FLAG_P (1 << 3)
60#define FLAG_S (1 << 4)
61#define FLAG_Tn (1 << 5)
62#define FLAG_PLUSn (1 << 6)
63
64/* Prompt flags */
65#define PROMPT_PERCENT (1 << 0)
66#define PROMPT_LINE_AT (1 << 1)
67#define PROMPT_OPTIONS (1 << 2)
68#define PROMPT_LINES (1 << 3)
69
70static DWORD s_dwFlags = 0;
71static LONG s_nTabWidth = 8;
74static WORD s_fPrompt = 0;
76
78{
79 DWORD ich;
80 WORD wType;
81 for (ich = 0; ich < cch; ++ich)
82 {
83 /*
84 * Explicitly exclude FORM-FEED from the check,
85 * so that the pager can handle it.
86 */
87 if (line[ich] == L'\f')
88 return FALSE;
89
90 /*
91 * Otherwise do the extended blanks check.
92 * Note that MS MORE.COM only checks for spaces (\x20) and TABs (\x09).
93 * See http://archives.miloush.net/michkap/archive/2007/06/11/3230072.html
94 * for more information.
95 */
96 wType = 0;
97 GetStringTypeW(CT_CTYPE1, &line[ich], 1, &wType);
98 if (!(wType & (C1_BLANK | C1_SPACE)))
99 return FALSE;
100 }
101 return TRUE;
102}
103
104static BOOL
107 IN OUT PCON_PAGER Pager,
108 IN PCWCH line,
109 IN DWORD cch)
110{
111 if (s_dwFlags & FLAG_PLUSn) /* Skip lines */
112 {
113 if (Pager->lineno < s_nNextLineNo)
114 {
116 return TRUE; /* Handled */
117 }
118 s_dwFlags &= ~FLAG_PLUSn;
119 }
120
121 if (s_dwFlags & FLAG_S) /* Shrink blank lines */
122 {
123 if (IsBlankLine(line, cch))
124 {
126 return TRUE; /* Handled */
127
128 /*
129 * Display a single blank line, independently of the actual size
130 * of the current line, by displaying just one space: this is
131 * especially needed in order to force line wrapping when the
132 * ENABLE_VIRTUAL_TERMINAL_PROCESSING or DISABLE_NEWLINE_AUTO_RETURN
133 * console modes are enabled.
134 * Then, reposition the cursor to the next line, first column.
135 */
136 if (Pager->PageColumns > 0)
137 ConStreamWrite(Pager->Screen->Stream, TEXT(" "), 1);
138 ConStreamWrite(Pager->Screen->Stream, TEXT("\n"), 1);
139 Pager->iLine++;
140 Pager->iColumn = 0;
141
143 s_nNextLineNo = 0;
144
145 return TRUE; /* Handled */
146 }
147 else
148 {
150 }
151 }
152
153 s_nNextLineNo = 0;
154 /* Not handled, let the pager do the default action */
155 return FALSE;
156}
157
158static BOOL
160PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
161{
163 HANDLE hOutput = ConStreamGetOSHandle(Pager->Screen->Stream);
165 COORD orgCursorPosition;
166 DWORD dwMode;
167
168 KEY_EVENT_RECORD KeyEvent;
169 BOOL fCtrl;
170 DWORD nLines;
171 WCHAR chSubCommand = 0;
172
173 /* Prompt strings (small size since the prompt should
174 * hold ideally on one <= 80-character line) */
175 static WCHAR StrPercent[80] = L"";
176 static WCHAR StrLineAt[80] = L"";
177 static WCHAR StrOptions[80] = L"";
178 static WCHAR StrLines[80] = L"";
179
180 WCHAR szPercent[80] = L"";
181 WCHAR szLineAt[80] = L"";
182
183 /* Load the prompt strings */
184 if (!*StrPercent)
185 K32LoadStringW(NULL, IDS_CONTINUE_PERCENT, StrPercent, ARRAYSIZE(StrPercent));
186 if (!*StrLineAt)
187 K32LoadStringW(NULL, IDS_CONTINUE_LINE_AT, StrLineAt, ARRAYSIZE(StrLineAt));
188 if (!*StrOptions)
189 K32LoadStringW(NULL, IDS_CONTINUE_OPTIONS, StrOptions, ARRAYSIZE(StrOptions));
190 if (!*StrLines)
191 K32LoadStringW(NULL, IDS_CONTINUE_LINES, StrLines, ARRAYSIZE(StrLines));
192
193 /*
194 * Check whether the pager is prompting, but we have actually finished
195 * to display a given file, or no data is present in STDIN anymore.
196 * In this case, skip the prompt altogether. The only exception is when
197 * we are displaying other files.
198 */
199 // TODO: Implement!
200
201Restart:
202 nLines = 0;
203
204 /* Do not show the progress percentage when STDIN is being displayed */
205 if (s_fPrompt & PROMPT_PERCENT) // && (hFile != hStdIn)
206 {
207 /*
208 * The progress percentage is evaluated as follows.
209 * So far we have read a total of 'dwSumReadBytes' bytes from the file.
210 * Amongst those is the latest read chunk of 'dwReadBytes' bytes, to which
211 * correspond a number of 'dwReadChars' characters with which we have called
212 * ConWritePaging who called PagePrompt. We then have: Total == dwReadChars.
213 * During this ConWritePaging call the PagePrompt was called after 'Done'
214 * number of characters over 'Total'.
215 * It should be noted that for 'dwSumReadBytes' number of bytes read it
216 * *roughly* corresponds 'dwSumReadChars' number of characters. This is
217 * because there may be some failures happening during the conversion of
218 * the bytes read to the character string for a given encoding.
219 * Therefore the number of characters displayed on screen is equal to:
220 * dwSumReadChars - Total + Done ,
221 * but the best corresponding approximed number of bytes would be:
222 * dwSumReadBytes - (Total - Done) * (dwSumReadBytes / dwSumReadChars) ,
223 * where the ratio is the average number of bytes per character.
224 * The percentage is then computed relative to the total file size.
225 */
226 DWORD dwPercent = (dwSumReadBytes - (Total - Done) *
228 StringCchPrintfW(szPercent, ARRAYSIZE(szPercent), StrPercent, dwPercent);
229 }
231 {
232 StringCchPrintfW(szLineAt, ARRAYSIZE(szLineAt), StrLineAt, Pager->lineno);
233 }
234
235 /* Suitably format and display the prompt */
238 (s_fPrompt & PROMPT_LINE_AT ? szLineAt : L""),
239 (s_fPrompt & PROMPT_OPTIONS ? StrOptions : L""),
240 (s_fPrompt & PROMPT_LINES ? StrLines : L""));
241
242 /* Reset the prompt to a default state */
244
245 /* RemoveBreakHandler */
247 /* ConInDisable */
248 GetConsoleMode(hInput, &dwMode);
249 dwMode &= ~ENABLE_PROCESSED_INPUT;
250 SetConsoleMode(hInput, dwMode);
251
252 // FIXME: Does not support TTY yet!
253 ConGetScreenInfo(Pager->Screen, &csbi);
254 orgCursorPosition = csbi.dwCursorPosition;
255 for (;;)
256 {
257 INPUT_RECORD ir = {0};
258 DWORD dwRead;
259 WCHAR ch;
260
261 do
262 {
263 ReadConsoleInput(hInput, &ir, 1, &dwRead);
264 }
265 while ((ir.EventType != KEY_EVENT) || (!ir.Event.KeyEvent.bKeyDown));
266
267 /* Got our key */
268 KeyEvent = ir.Event.KeyEvent;
269
270 /* Ignore any unsupported keyboard press */
271 if ((KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
272 (KeyEvent.wVirtualKeyCode == VK_MENU) ||
273 (KeyEvent.wVirtualKeyCode == VK_CONTROL))
274 {
275 continue;
276 }
277
278 /* Ctrl key is pressed? */
279 fCtrl = !!(KeyEvent.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED));
280
281 /* Ctrl+C or Ctrl+Esc? */
282 if (fCtrl && ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
283 (KeyEvent.wVirtualKeyCode == L'C')))
284 {
285 chSubCommand = 0;
286 break;
287 }
288
289 /* If extended features are unavailable, or no
290 * pending commands, don't do more processing. */
291 if (!(s_dwFlags & FLAG_E) || (chSubCommand == 0))
292 break;
293
294 ch = KeyEvent.uChar.UnicodeChar;
295 if (L'0' <= ch && ch <= L'9')
296 {
297 nLines *= 10;
298 nLines += ch - L'0';
299 ConStreamWrite(Pager->Screen->Stream, &ch, 1);
300 continue;
301 }
302 else if (KeyEvent.wVirtualKeyCode == VK_RETURN)
303 {
304 /* Validate the line number */
305 break;
306 }
307 else if (KeyEvent.wVirtualKeyCode == VK_ESCAPE)
308 {
309 /* Cancel the current command */
310 chSubCommand = 0;
311 break;
312 }
313 else if (KeyEvent.wVirtualKeyCode == VK_BACK)
314 {
315 if (nLines != 0)
316 nLines /= 10;
317
318 /* Erase the current character */
319 ConGetScreenInfo(Pager->Screen, &csbi);
320 if ( (csbi.dwCursorPosition.Y > orgCursorPosition.Y) ||
321 ((csbi.dwCursorPosition.Y == orgCursorPosition.Y) &&
322 (csbi.dwCursorPosition.X > orgCursorPosition.X)) )
323 {
324 if (csbi.dwCursorPosition.X > 0)
325 {
326 csbi.dwCursorPosition.X = csbi.dwCursorPosition.X - 1;
327 }
328 else if (csbi.dwCursorPosition.Y > 0)
329 {
330 csbi.dwCursorPosition.Y = csbi.dwCursorPosition.Y - 1;
331 csbi.dwCursorPosition.X = (csbi.dwSize.X ? csbi.dwSize.X - 1 : 0);
332 }
333
335
336 ch = L' ';
337 ConStreamWrite(Pager->Screen->Stream, &ch, 1);
339 }
340
341 continue;
342 }
343 }
344
345 /* AddBreakHandler */
347 /* ConInEnable */
348 GetConsoleMode(hInput, &dwMode);
349 dwMode |= ENABLE_PROCESSED_INPUT;
350 SetConsoleMode(hInput, dwMode);
351
352 /* Refresh the screen information, as the console may have been
353 * redimensioned. Update also the default number of lines to scroll. */
354 ConGetScreenInfo(Pager->Screen, &csbi);
355 Pager->ScrollRows = csbi.srWindow.Bottom - csbi.srWindow.Top;
356
357 /*
358 * Erase the full line where the cursor is, and move
359 * the cursor back to the beginning of the line.
360 */
361 ConClearLine(Pager->Screen->Stream);
362
363 /* Ctrl+C or Ctrl+Esc: Control Break */
364 if (fCtrl && ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
365 (KeyEvent.wVirtualKeyCode == L'C')))
366 {
367 /* We break, output a newline */
368 WCHAR ch = L'\n';
369 ConStreamWrite(Pager->Screen->Stream, &ch, 1);
370 return FALSE;
371 }
372
373 switch (chSubCommand)
374 {
375 case L'P':
376 {
377 /* If we don't display other lines, just restart the prompt */
378 if (nLines == 0)
379 {
380 chSubCommand = 0;
381 goto Restart;
382 }
383 /* Otherwise tell the pager to display them */
384 Pager->ScrollRows = nLines;
385 return TRUE;
386 }
387 case L'S':
388 {
390 s_nNextLineNo = Pager->lineno + nLines;
391 /* Use the default Pager->ScrollRows value */
392 return TRUE;
393 }
394 default:
395 chSubCommand = 0;
396 break;
397 }
398
399 /* If extended features are available */
400 if (s_dwFlags & FLAG_E)
401 {
402 /* Ignore any key presses if Ctrl is pressed */
403 if (fCtrl)
404 {
405 chSubCommand = 0;
406 goto Restart;
407 }
408
409 /* 'Q': Quit */
410 if (KeyEvent.wVirtualKeyCode == L'Q')
411 {
412 /* We break, output a newline */
413 WCHAR ch = L'\n';
414 ConStreamWrite(Pager->Screen->Stream, &ch, 1);
415 return FALSE;
416 }
417
418 /* 'F': Next file */
419 if (KeyEvent.wVirtualKeyCode == L'F')
420 {
422 return FALSE;
423 }
424
425 /* '?': Show Options */
426 if (KeyEvent.uChar.UnicodeChar == L'?')
427 {
429 goto Restart;
430 }
431
432 /* [Enter] key: Display one line */
433 if (KeyEvent.wVirtualKeyCode == VK_RETURN)
434 {
435 Pager->ScrollRows = 1;
436 return TRUE;
437 }
438
439 /* [Space] key: Display one page */
440 if (KeyEvent.wVirtualKeyCode == VK_SPACE)
441 {
442 if (s_dwFlags & FLAG_C)
443 {
444 /* Clear the screen */
445 ConClearScreen(Pager->Screen);
446 }
447 /* Use the default Pager->ScrollRows value */
448 return TRUE;
449 }
450
451 /* 'P': Display n lines */
452 if (KeyEvent.wVirtualKeyCode == L'P')
453 {
455 chSubCommand = L'P';
456 goto Restart;
457 }
458
459 /* 'S': Skip n lines */
460 if (KeyEvent.wVirtualKeyCode == L'S')
461 {
463 chSubCommand = L'S';
464 goto Restart;
465 }
466
467 /* '=': Show current line number */
468 if (KeyEvent.uChar.UnicodeChar == L'=')
469 {
471 goto Restart;
472 }
473
474 chSubCommand = 0;
475 goto Restart;
476 }
477 else
478 {
479 /* Extended features are unavailable: display one page */
480 /* Use the default Pager->ScrollRows value */
481 return TRUE;
482 }
483}
484
485/*
486 * See base/applications/cmdutils/clip/clip.c!IsDataUnicode()
487 * and base/applications/notepad/text.c!ReadText() for more details.
488 * Also some good code example can be found at:
489 * https://github.com/AutoIt/text-encoding-detect
490 */
491typedef enum
492{
496 ENCODING_UTF8 = 3
498
499static BOOL
503 OUT ENCODING* Encoding OPTIONAL,
505{
506 PBYTE pBytes = Buffer;
507 ENCODING encFile = ENCODING_ANSI;
508 DWORD dwPos = 0;
509
510 /*
511 * See http://archives.miloush.net/michkap/archive/2007/04/22/2239345.html
512 * for more details about the algorithm and the pitfalls behind it.
513 * Of course it would be actually great to make a nice function that
514 * would work, once and for all, and put it into a library.
515 */
516
517 /* Look for Byte Order Marks */
518 if ((BufferSize >= 2) && (pBytes[0] == 0xFF) && (pBytes[1] == 0xFE))
519 {
520 encFile = ENCODING_UTF16LE;
521 dwPos = 2;
522 }
523 else if ((BufferSize >= 2) && (pBytes[0] == 0xFE) && (pBytes[1] == 0xFF))
524 {
525 encFile = ENCODING_UTF16BE;
526 dwPos = 2;
527 }
528 else if ((BufferSize >= 3) && (pBytes[0] == 0xEF) && (pBytes[1] == 0xBB) && (pBytes[2] == 0xBF))
529 {
530 encFile = ENCODING_UTF8;
531 dwPos = 3;
532 }
533 else
534 {
535 /*
536 * Try using statistical analysis. Do not rely on the return value of
537 * IsTextUnicode as we can get FALSE even if the text is in UTF-16 BE
538 * (i.e. we have some of the IS_TEXT_UNICODE_REVERSE_MASK bits set).
539 * Instead, set all the tests we want to perform, then just check
540 * the passed tests and try to deduce the string properties.
541 */
542
543/*
544 * This mask contains the 3 highest bits from IS_TEXT_UNICODE_NOT_ASCII_MASK
545 * and the 1st highest bit from IS_TEXT_UNICODE_NOT_UNICODE_MASK.
546 */
547#define IS_TEXT_UNKNOWN_FLAGS_MASK ((7 << 13) | (1 << 11))
548
549 /* Flag out the unknown flags here, the passed tests will not have them either */
554 INT Results;
555
557 Results = Tests;
558
559 /*
560 * As the IS_TEXT_UNICODE_NULL_BYTES or IS_TEXT_UNICODE_ILLEGAL_CHARS
561 * flags are expected to be potentially present in the result without
562 * modifying our expectations, filter them out now.
563 */
565
566 /*
567 * NOTE: The flags IS_TEXT_UNICODE_ASCII16 and
568 * IS_TEXT_UNICODE_REVERSE_ASCII16 are not reliable.
569 *
570 * NOTE2: Check for potential "bush hid the facts" effect by also
571 * checking the original results (in 'Tests') for the absence of
572 * the IS_TEXT_UNICODE_NULL_BYTES flag, as we may presumably expect
573 * that in UTF-16 text there will be at some point some NULL bytes.
574 * If not, fall back to ANSI. This shows the limitations of using the
575 * IsTextUnicode API to perform such tests, and the usage of a more
576 * improved encoding detection algorithm would be really welcome.
577 */
578 if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
579 !(Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
580 (Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
582 {
583 encFile = ENCODING_UTF16LE;
584 dwPos = (Results & IS_TEXT_UNICODE_SIGNATURE) ? 2 : 0;
585 }
586 else
587 if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
588 !(Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
589 (Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
591 {
592 encFile = ENCODING_UTF16BE;
593 dwPos = (Results & IS_TEXT_UNICODE_REVERSE_SIGNATURE) ? 2 : 0;
594 }
595 else
596 {
597 /*
598 * Either 'Results' has neither of those masks set, as it can be
599 * the case for UTF-8 text (or ANSI), or it has both as can be the
600 * case when analysing pure binary data chunk. This is therefore
601 * invalid and we fall back to ANSI encoding.
602 * FIXME: In case of failure, assume ANSI (as long as we do not have
603 * correct tests for UTF8, otherwise we should do them, and at the
604 * very end, assume ANSI).
605 */
606 encFile = ENCODING_ANSI; // ENCODING_UTF8;
607 dwPos = 0;
608 }
609 }
610
611 if (Encoding)
612 *Encoding = encFile;
613 if (SkipBytes)
614 *SkipBytes = dwPos;
615
616 return (encFile != ENCODING_ANSI);
617}
618
619/*
620 * Adapted from base/shell/cmd/misc.c!FileGetString(), but with correct
621 * text encoding support. Also please note that similar code should be
622 * also used in the CMD.EXE 'TYPE' command.
623 * Contrary to CMD's FileGetString() we do not stop at new-lines.
624 *
625 * Read text data from a file and convert it from a given encoding to UTF-16.
626 *
627 * IN OUT PVOID pCacheBuffer and IN DWORD CacheBufferLength :
628 * Implementation detail so that the function uses an external user-provided
629 * buffer to store the data temporarily read from the file. The function
630 * could have used an internal buffer instead. The length is in number of bytes.
631 *
632 * IN OUT PWSTR* pBuffer and IN OUT PDWORD pnBufferLength :
633 * Reallocated buffer containing the string data converted to UTF-16.
634 * In input, contains a pointer to the original buffer and its length.
635 * In output, contains a pointer to the reallocated buffer and its length.
636 * The length is in number of characters.
637 *
638 * At first call to this function, pBuffer can be set to NULL, in which case
639 * when the function returns the pointer will point to a valid buffer.
640 * After the last call to this function, free the pBuffer pointer with:
641 * HeapFree(GetProcessHeap(), 0, *pBuffer);
642 *
643 * If Encoding is set to ENCODING_UTF16LE or ENCODING_UTF16BE, since we are
644 * compiled in UNICODE, no extra conversion is performed and therefore
645 * pBuffer is unused (remains unallocated) and one can directly use the
646 * contents of pCacheBuffer as it is expected to contain valid UTF-16 text.
647 *
648 * OUT PDWORD pdwReadBytes : Number of bytes read from the file (optional).
649 * OUT PDWORD pdwReadChars : Corresponding number of characters read (optional).
650 */
651static BOOL
654 IN ENCODING Encoding,
655 IN OUT PVOID pCacheBuffer,
656 IN DWORD CacheBufferLength,
658 IN OUT PDWORD pnBufferLength,
659 OUT PDWORD pdwReadBytes OPTIONAL,
660 OUT PDWORD pdwReadChars OPTIONAL)
661{
663 UINT CodePage = (UINT)-1;
664 DWORD dwReadBytes;
665 INT len;
666
667 // ASSERT(pCacheBuffer && (CacheBufferLength > 0));
668 // ASSERT(CacheBufferLength % 2 == 0); // Cache buffer length MUST BE even!
669 // ASSERT(pBuffer && pnBufferLength);
670
671 /* Always reset the retrieved number of bytes/characters */
672 if (pdwReadBytes) *pdwReadBytes = 0;
673 if (pdwReadChars) *pdwReadChars = 0;
674
675 Success = ReadFile(hFile, pCacheBuffer, CacheBufferLength, &dwReadBytes, NULL);
676 if (!Success || dwReadBytes == 0)
677 return FALSE;
678
679 if (pdwReadBytes) *pdwReadBytes = dwReadBytes;
680
681 if ((Encoding == ENCODING_ANSI) || (Encoding == ENCODING_UTF8))
682 {
683 /* Conversion is needed */
684
685 if (Encoding == ENCODING_ANSI)
686 CodePage = GetConsoleCP(); // CP_ACP; // FIXME: Cache GetConsoleCP() value.
687 else // if (Encoding == ENCODING_UTF8)
688 CodePage = CP_UTF8;
689
690 /* Retrieve the needed buffer size */
691 len = MultiByteToWideChar(CodePage, 0, pCacheBuffer, dwReadBytes,
692 NULL, 0);
693 if (len == 0)
694 {
695 /* Failure, bail out */
696 return FALSE;
697 }
698
699 /* Initialize the conversion buffer if needed... */
700 if (*pBuffer == NULL)
701 {
702 *pnBufferLength = len;
703 *pBuffer = HeapAlloc(GetProcessHeap(), 0, *pnBufferLength * sizeof(WCHAR));
704 if (*pBuffer == NULL)
705 {
706 // *pBuffer = NULL;
707 *pnBufferLength = 0;
708 // WARN("DEBUG: Cannot allocate memory for *pBuffer!\n");
709 // ConErrFormatMessage(GetLastError());
710 return FALSE;
711 }
712 }
713 /* ... or reallocate only if the new length is greater than the old one */
714 else if (len > *pnBufferLength)
715 {
716 PWSTR OldBuffer = *pBuffer;
717
718 *pnBufferLength = len;
719 *pBuffer = HeapReAlloc(GetProcessHeap(), 0, *pBuffer, *pnBufferLength * sizeof(WCHAR));
720 if (*pBuffer == NULL)
721 {
722 /* Do not leak old buffer */
723 HeapFree(GetProcessHeap(), 0, OldBuffer);
724 // *pBuffer = NULL;
725 *pnBufferLength = 0;
726 // WARN("DEBUG: Cannot reallocate memory for *pBuffer!\n");
727 // ConErrFormatMessage(GetLastError());
728 return FALSE;
729 }
730 }
731
732 /* Now perform the conversion proper */
733 len = MultiByteToWideChar(CodePage, 0, pCacheBuffer, dwReadBytes,
734 *pBuffer, len);
735 dwReadBytes = len;
736 }
737 else
738 {
739 /*
740 * No conversion needed, just convert from big to little endian if needed.
741 * pBuffer and pnBufferLength are left untouched and pCacheBuffer can be
742 * directly used.
743 */
744 PWCHAR pWChars = pCacheBuffer;
745 DWORD i;
746
747 dwReadBytes /= sizeof(WCHAR);
748
749 if (Encoding == ENCODING_UTF16BE)
750 {
751 for (i = 0; i < dwReadBytes; i++)
752 {
753 /* Equivalent to RtlUshortByteSwap: reverse high/low bytes */
754 pWChars[i] = MAKEWORD(HIBYTE(pWChars[i]), LOBYTE(pWChars[i]));
755 }
756 }
757 // else if (Encoding == ENCODING_UTF16LE), we are good, nothing to do.
758 }
759
760 /* Return the number of characters (dwReadBytes is converted) */
761 if (pdwReadChars) *pdwReadChars = dwReadBytes;
762
763 return TRUE;
764}
765
766static VOID
768{
769 LONG lRet;
770 HKEY hKey;
771 DWORD dwType, len;
772 /*
773 * Buffer big enough to hold the string L"4294967295",
774 * corresponding to the literal 0xFFFFFFFF (MAXULONG) in decimal.
775 */
776 WCHAR Buffer[sizeof("4294967295")];
777 C_ASSERT(sizeof(Buffer) >= sizeof(DWORD));
778
779 lRet = RegOpenKeyExW(hKeyRoot,
780 L"Software\\Microsoft\\Command Processor",
781 0,
783 &hKey);
784 if (lRet != ERROR_SUCCESS)
785 return;
786
787 len = sizeof(Buffer);
788 lRet = RegQueryValueExW(hKey,
789 L"EnableExtensions",
790 NULL,
791 &dwType,
792 (PBYTE)&Buffer,
793 &len);
794 if (lRet == ERROR_SUCCESS)
795 {
796 /* Overwrite the default setting */
797 if (dwType == REG_DWORD)
799 else if (dwType == REG_SZ)
801 }
802 // else, use the default setting set globally.
803
805}
806
808{
809 PCWSTR pch;
810 PWCHAR endptr;
811
812 if (param[0] == L'/')
813 return TRUE;
814
815 if (param[0] == L'+')
816 {
817 pch = param + 1;
818 if (*pch)
819 {
820 (void)wcstol(pch, &endptr, 10);
821 return (*endptr == 0);
822 }
823 }
824 return FALSE;
825}
826
827static BOOL ParseArgument(PCWSTR arg, BOOL* pbHasFiles)
828{
829 PWCHAR endptr;
830
831 if (arg[0] == L'/')
832 {
833 switch (towupper(arg[1]))
834 {
835 case L'?':
836 if (arg[2] == 0)
837 {
839 return TRUE;
840 }
841 break;
842 case L'E':
843 if (arg[2] == 0)
844 {
845 s_dwFlags |= FLAG_E;
846 return TRUE;
847 }
848 break;
849 case L'C':
850 if (arg[2] == 0)
851 {
852 s_dwFlags |= FLAG_C;
853 return TRUE;
854 }
855 break;
856 case L'P':
857 if (arg[2] == 0)
858 {
859 s_dwFlags |= FLAG_P;
860 return TRUE;
861 }
862 break;
863 case L'S':
864 if (arg[2] == 0)
865 {
866 s_dwFlags |= FLAG_S;
867 return TRUE;
868 }
869 break;
870 case L'T':
871 if (arg[2] != 0)
872 {
874 s_nTabWidth = wcstol(&arg[2], &endptr, 10);
875 if (*endptr == 0)
876 return TRUE;
877 }
878 break;
879 default:
880 break;
881 }
882 }
883 else if (arg[0] == L'+')
884 {
885 if (arg[1] != 0)
886 {
888 s_nNextLineNo = wcstol(&arg[1], &endptr, 10) + 1;
889 if (*endptr == 0)
890 return TRUE;
891 }
892 }
893
894 if (IsFlag(arg))
895 {
897 return FALSE;
898 }
899 else
900 {
901 *pbHasFiles = TRUE;
902 }
903
904 return TRUE;
905}
906
907static BOOL ParseMoreVariable(BOOL* pbHasFiles)
908{
909 BOOL ret = TRUE;
910 PWSTR psz;
911 PWCHAR pch;
912 DWORD cch;
913
914 cch = GetEnvironmentVariableW(L"MORE", NULL, 0);
915 if (cch == 0)
916 return TRUE;
917
918 psz = (PWSTR)malloc((cch + 1) * sizeof(WCHAR));
919 if (!psz)
920 return TRUE;
921
922 if (!GetEnvironmentVariableW(L"MORE", psz, cch + 1))
923 {
924 free(psz);
925 return TRUE;
926 }
927
928 for (pch = wcstok(psz, L" "); pch; pch = wcstok(NULL, L" "))
929 {
930 ret = ParseArgument(pch, pbHasFiles);
931 if (!ret)
932 break;
933 }
934
935 free(psz);
936 return ret;
937}
938
939// INT CommandMore(LPTSTR cmd, LPTSTR param)
940int wmain(int argc, WCHAR* argv[])
941{
942 // FIXME this stuff!
944 CON_PAGER Pager = {&Screen, 0};
945
946 int i;
947
948 BOOL bRet, bContinue;
949
950 ENCODING Encoding;
951 DWORD SkipBytes = 0;
952 BOOL HasFiles;
953
954#define FileCacheBufferSize 4096
955 PVOID FileCacheBuffer = NULL;
957 DWORD StringBufferLength = 0;
958 DWORD dwReadBytes = 0, dwReadChars = 0;
959
960 TCHAR szFullPath[MAX_PATH];
961
964
965 /* Initialize the Console Standard Streams */
969
970 /*
971 * Bad usage (too much options) or we use the /? switch.
972 * Display help for the MORE command.
973 */
974 if (argc > 1 && wcscmp(argv[1], L"/?") == 0)
975 {
977 return 0;
978 }
979
980 /* Load the registry settings */
984 s_dwFlags |= FLAG_E;
985
986 // NOTE: We might try to duplicate the ConOut for read access... ?
989 OPEN_EXISTING, 0, NULL);
992
993 FileCacheBuffer = HeapAlloc(GetProcessHeap(), 0, FileCacheBufferSize);
994 if (!FileCacheBuffer)
995 {
996 ConPuts(StdErr, L"Error: no memory\n");
998 return 1;
999 }
1000
1001 /* First, load the "MORE" environment variable and parse it,
1002 * then parse the command-line parameters. */
1003 HasFiles = FALSE;
1004 if (!ParseMoreVariable(&HasFiles))
1005 return 1;
1006 for (i = 1; i < argc; i++)
1007 {
1008 if (!ParseArgument(argv[i], &HasFiles))
1009 return 1;
1010 }
1011
1012 if (s_dwFlags & FLAG_HELP)
1013 {
1015 return 0;
1016 }
1017
1018 Pager.PagerLine = MorePagerLine;
1020 if (s_dwFlags & FLAG_P)
1022 Pager.nTabWidth = s_nTabWidth;
1023
1024 /* Special case where we run 'MORE' without any argument: we use STDIN */
1025 if (!HasFiles)
1026 {
1027 /*
1028 * Assign STDIN handle to hFile so that the page prompt function will
1029 * know the data comes from STDIN, and will take different actions.
1030 */
1031 hFile = hStdIn;
1032
1033 /* Update the statistics for PagePrompt */
1034 dwFileSize = 0;
1036
1037 /* We suppose we read text from the file */
1038
1039 /* For STDIN we always suppose we are in ANSI mode */
1040 // SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
1041 Encoding = ENCODING_ANSI; // ENCODING_UTF8;
1042
1043 /* Start paging */
1044 bContinue = ConWritePaging(&Pager, PagePrompt, TRUE, NULL, 0);
1045 if (!bContinue)
1046 goto Quit;
1047
1048 do
1049 {
1050 bRet = FileGetString(hFile, Encoding,
1051 FileCacheBuffer, FileCacheBufferSize,
1052 &StringBuffer, &StringBufferLength,
1053 &dwReadBytes, &dwReadChars);
1054 if (!bRet || dwReadBytes == 0 || dwReadChars == 0)
1055 {
1056 /* We failed at reading the file, bail out */
1057 break;
1058 }
1059
1060 /* Update the statistics for PagePrompt */
1061 dwSumReadBytes += dwReadBytes;
1062 dwSumReadChars += dwReadChars;
1063
1064 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
1065 StringBuffer, dwReadChars);
1066 /* If we Ctrl-C/Ctrl-Break, stop everything */
1067 if (!bContinue)
1068 break;
1069 }
1070 while (bRet && dwReadBytes > 0);
1071
1072 /* Flush any cached pager buffers */
1073 if (bContinue)
1074 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE, NULL, 0);
1075
1076 goto Quit;
1077 }
1078
1079 /* We have files: read them and output them to STDOUT */
1080 for (i = 1; i < argc; i++)
1081 {
1082 if (IsFlag(argv[i]))
1083 continue;
1084
1085 GetFullPathNameW(argv[i], ARRAYSIZE(szFullPath), szFullPath, NULL);
1086 hFile = CreateFileW(szFullPath,
1089 NULL,
1091 0, // FILE_ATTRIBUTE_NORMAL,
1092 NULL);
1094 {
1095 ConResPrintf(StdErr, IDS_FILE_ACCESS, szFullPath);
1096 goto Quit;
1097 }
1098
1099 /* We currently do not support files too big */
1102 {
1103 ConPuts(StdErr, L"ERROR: Invalid file size!\n");
1105 continue;
1106 }
1107
1108 /* We suppose we read text from the file */
1109
1110 /* Check whether the file is UNICODE and retrieve its encoding */
1112 bRet = ReadFile(hFile, FileCacheBuffer, FileCacheBufferSize, &dwReadBytes, NULL);
1113 IsDataUnicode(FileCacheBuffer, dwReadBytes, &Encoding, &SkipBytes);
1115
1116 /* Reset state for paging */
1117 s_nNextLineNo = 0;
1121
1122 /* Update the statistics for PagePrompt */
1124
1125 /* Start paging */
1126 bContinue = ConWritePaging(&Pager, PagePrompt, TRUE, NULL, 0);
1127 if (!bContinue)
1128 {
1129 /* We stop displaying this file */
1131 if (s_bDoNextFile)
1132 {
1133 /* Bail out and continue with the other files */
1134 continue;
1135 }
1136
1137 /* We Ctrl-C/Ctrl-Break, stop everything */
1138 goto Quit;
1139 }
1140
1141 do
1142 {
1143 bRet = FileGetString(hFile, Encoding,
1144 FileCacheBuffer, FileCacheBufferSize,
1145 &StringBuffer, &StringBufferLength,
1146 &dwReadBytes, &dwReadChars);
1147 if (!bRet || dwReadBytes == 0 || dwReadChars == 0)
1148 {
1149 /*
1150 * We failed at reading the file, bail out
1151 * and continue with the other files.
1152 */
1153 break;
1154 }
1155
1156 /* Update the statistics for PagePrompt */
1157 dwSumReadBytes += dwReadBytes;
1158 dwSumReadChars += dwReadChars;
1159
1160 if ((Encoding == ENCODING_UTF16LE) || (Encoding == ENCODING_UTF16BE))
1161 {
1162 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
1163 FileCacheBuffer, dwReadChars);
1164 }
1165 else
1166 {
1167 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
1168 StringBuffer, dwReadChars);
1169 }
1170 if (!bContinue)
1171 {
1172 /* We stop displaying this file */
1173 break;
1174 }
1175 }
1176 while (bRet && dwReadBytes > 0);
1177
1178 /* Flush any cached pager buffers */
1179 if (bContinue)
1180 bContinue = ConWritePaging(&Pager, PagePrompt, FALSE, NULL, 0);
1181
1183
1184 /* Check whether we should stop displaying this file */
1185 if (!bContinue)
1186 {
1187 if (s_bDoNextFile)
1188 {
1189 /* Bail out and continue with the other files */
1190 continue;
1191 }
1192
1193 /* We Ctrl-C/Ctrl-Break, stop everything */
1194 goto Quit;
1195 }
1196 }
1197
1198Quit:
1200 HeapFree(GetProcessHeap(), 0, FileCacheBuffer);
1202 return 0;
1203}
1204
1205/* EOF */
struct test_data Tests[]
static int argc
Definition: ServiceArgs.c:12
#define IDS_USAGE
Definition: resource.h:3
void ConPuts(FILE *fp, LPCWSTR psz)
Definition: fc.c:16
#define StdOut
Definition: fc.c:14
void ConResPrintf(FILE *fp, UINT nID,...)
Definition: fc.c:33
#define StdErr
Definition: fc.c:15
void ConResPuts(FILE *fp, UINT nID)
Definition: fc.c:27
#define IDS_CONTINUE_OPTIONS
Definition: resource.h:10
#define IDS_CONTINUE_LINES
Definition: resource.h:11
#define IDS_CONTINUE_LINE_AT
Definition: resource.h:9
#define IDS_FILE_ACCESS
Definition: resource.h:5
#define IDS_CONTINUE_PROMPT
Definition: resource.h:7
#define IDS_BAD_FLAG
Definition: resource.h:4
#define IDS_CONTINUE_PERCENT
Definition: resource.h:8
BOOL WINAPI FlushConsoleInputBuffer(IN HANDLE hConsoleInput)
Definition: console.c:220
BOOL WINAPI SetConsoleCursorPosition(IN HANDLE hConsoleOutput, IN COORD dwCursorPosition)
Definition: console.c:641
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
#define RegCloseKey(hKey)
Definition: registry.h:49
Definition: bufpool.h:45
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ Screen
Definition: console.h:34
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
BOOL WINAPI IsTextUnicode(IN CONST VOID *lpv, IN INT iSize, IN OUT LPINT lpiResult OPTIONAL)
Definition: unicode.c:27
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define FILE_BEGIN
Definition: compat.h:761
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define MultiByteToWideChar
Definition: compat.h:110
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1569
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode)
Definition: console.c:1606
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2109
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2391
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
static const WCHAR szPercent[]
Definition: varformat.c:393
@ Success
Definition: eventcreate.c:712
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
FxAutoRegKey hKey
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define C1_SPACE
Definition: unicode.h:34
#define C1_BLANK
Definition: unicode.h:37
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ _CRTIMP long __cdecl _wtol(_In_z_ const wchar_t *_Str)
#define C_ASSERT(e)
Definition: intsafe.h:73
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define TEXT(s)
Definition: k32.h:26
BOOL WINAPI GetStringTypeW(DWORD type, LPCWSTR src, INT count, LPWORD chartype)
Definition: lang.c:1709
#define REG_SZ
Definition: layer.c:22
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define pch(ap)
Definition: match.c:418
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define FLAG_Tn
Definition: more.c:61
static BOOL __stdcall MorePagerLine(IN OUT PCON_PAGER Pager, IN PCWCH line, IN DWORD cch)
Definition: more.c:106
#define PROMPT_PERCENT
Definition: more.c:65
static VOID LoadRegistrySettings(HKEY hKeyRoot)
Definition: more.c:767
static BOOL ParseMoreVariable(BOOL *pbHasFiles)
Definition: more.c:907
static BOOL FileGetString(IN HANDLE hFile, IN ENCODING Encoding, IN OUT PVOID pCacheBuffer, IN DWORD CacheBufferLength, IN OUT PWCHAR *pBuffer, IN OUT PDWORD pnBufferLength, OUT PDWORD pdwReadBytes OPTIONAL, OUT PDWORD pdwReadChars OPTIONAL)
Definition: more.c:652
#define IS_TEXT_UNKNOWN_FLAGS_MASK
#define FLAG_P
Definition: more.c:59
DWORD dwSumReadBytes
Definition: more.c:41
static BOOL s_bPrevLineIsBlank
Definition: more.c:73
static BOOL __stdcall PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
Definition: more.c:160
#define PROMPT_LINE_AT
Definition: more.c:66
HANDLE hStdOut
Definition: more.c:49
ENCODING
Definition: more.c:492
@ ENCODING_UTF16BE
Definition: more.c:495
@ ENCODING_UTF8
Definition: more.c:496
@ ENCODING_UTF16LE
Definition: more.c:494
@ ENCODING_ANSI
Definition: more.c:493
#define FileCacheBufferSize
static BOOL IsBlankLine(IN PCWCH line, IN DWORD cch)
Definition: more.c:77
#define PROMPT_LINES
Definition: more.c:68
DWORD dwFileSize
Definition: more.c:40
#define PROMPT_OPTIONS
Definition: more.c:67
BOOL bEnableExtensions
Definition: more.c:53
HANDLE hStdIn
Definition: more.c:49
#define FLAG_S
Definition: more.c:60
#define FLAG_PLUSn
Definition: more.c:62
static LONG s_nTabWidth
Definition: more.c:71
static DWORD s_nNextLineNo
Definition: more.c:72
static BOOL IsFlag(PCWSTR param)
Definition: more.c:807
HANDLE hKeyboard
Definition: more.c:50
static BOOL IsDataUnicode(IN PVOID Buffer, IN DWORD BufferSize, OUT ENCODING *Encoding OPTIONAL, OUT PDWORD SkipBytes OPTIONAL)
Definition: more.c:500
static DWORD s_dwFlags
Definition: more.c:70
#define FLAG_C
Definition: more.c:58
#define FLAG_HELP
Definition: more.c:56
static BOOL ParseArgument(PCWSTR arg, BOOL *pbHasFiles)
Definition: more.c:827
DWORD dwSumReadChars
Definition: more.c:41
#define FLAG_E
Definition: more.c:57
static BOOL s_bDoNextFile
Definition: more.c:75
static WORD s_fPrompt
Definition: more.c:74
#define argv
Definition: mplay32.c:18
_In_ HANDLE hFile
Definition: mswsock.h:90
unsigned int UINT
Definition: ndis.h:50
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define GENERIC_WRITE
Definition: nt_native.h:90
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
#define L(x)
Definition: ntvdm.h:50
INT __cdecl ConResMsgPrintf(IN PCON_STREAM Stream, IN DWORD dwFlags, IN UINT uID,...)
Definition: outstream.c:1461
VOID ConClearLine(IN PCON_STREAM Stream)
Definition: outstream.c:1483
INT ConStreamWrite(IN PCON_STREAM Stream, IN PCTCH szStr, IN DWORD len)
Definition: outstream.c:398
#define CON_PAGER_EXPAND_TABS
Definition: pager.h:40
#define CON_PAGER_CACHE_INCOMPLETE_LINE
Definition: pager.h:43
#define CON_PAGER_EXPAND_FF
Definition: pager.h:41
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
PVOID pBuffer
int wmain()
@ Restart
Definition: sacdrv.h:269
#define REG_DWORD
Definition: sdbapi.c:596
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP wchar_t *__cdecl wcstok(_Inout_opt_z_ wchar_t *_Str, _In_z_ const wchar_t *_Delim)
#define CP_UTF8
Definition: nls.h:20
BOOL ConWritePaging(IN PCON_PAGER Pager, IN PAGE_PROMPT PagePrompt, IN BOOL StartPaging, IN PCTCH szStr, IN DWORD len)
Definition: pager.c:549
BOOL ConGetScreenInfo(IN PCON_SCREEN Screen, OUT PCONSOLE_SCREEN_BUFFER_INFO pcsbi)
Definition: screen.c:73
VOID ConClearScreen(IN PCON_SCREEN Screen)
Definition: screen.c:131
BOOL ConStreamSetOSHandle(IN PCON_STREAM Stream, IN HANDLE Handle)
Definition: stream.c:263
BOOL ConStreamInit(OUT PCON_STREAM Stream, IN PVOID Handle, IN CON_STREAM_MODE Mode, IN UINT CacheCodePage OPTIONAL)
Definition: stream.c:185
HANDLE ConStreamGetOSHandle(IN PCON_STREAM Stream)
Definition: stream.c:240
#define StdIn
Definition: stream.h:81
@ UTF8Text
Definition: stream.h:50
#define INVALID_CP
Definition: stream.h:53
INT WINAPI K32LoadStringW(IN HINSTANCE hInstance OPTIONAL, IN UINT uID, OUT LPWSTR lpBuffer, IN INT nBufferMax)
Definition: utils.c:173
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
DWORD dwFlags
Definition: pager.h:54
DWORD lineno
Definition: pager.h:70
LONG nTabWidth
Definition: pager.h:55
DWORD ScrollRows
Definition: pager.h:56
CON_PAGER_LINE_FN PagerLine
Definition: pager.h:53
PCON_SCREEN Screen
Definition: pager.h:48
PCON_STREAM Stream
Definition: screen.h:43
Definition: bl.h:1338
ULONG Y
Definition: bl.h:1340
ULONG X
Definition: bl.h:1339
WORD EventType
Definition: wincon.h:273
union _INPUT_RECORD::@3288 Event
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:275
union _KEY_EVENT_RECORD::@3287 uChar
DWORD dwControlKeyState
Definition: wincon.h:248
WORD wVirtualKeyCode
Definition: wincon.h:242
WCHAR UnicodeChar
Definition: wincon.h:245
Definition: parser.c:49
SHORT Y
Definition: blue.h:27
SHORT X
Definition: blue.h:26
SHORT Top
Definition: blue.h:33
SHORT Bottom
Definition: blue.h:35
#define towupper(c)
Definition: wctype.h:99
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
#define __stdcall
Definition: typedefs.h:25
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
#define OUT
Definition: typedefs.h:40
int ret
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define STD_INPUT_HANDLE
Definition: winbase.h:267
#define STD_ERROR_HANDLE
Definition: winbase.h:269
#define INVALID_FILE_SIZE
Definition: winbase.h:548
#define LEFT_CTRL_PRESSED
Definition: wincon.h:140
#define ReadConsoleInput
Definition: wincon.h:778
#define KEY_EVENT
Definition: wincon.h:128
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
#define CT_CTYPE1
Definition: winnls.h:237
#define IS_TEXT_UNICODE_ILLEGAL_CHARS
Definition: winnt_old.h:894
#define IS_TEXT_UNICODE_UNICODE_MASK
Definition: winnt_old.h:898
#define IS_TEXT_UNICODE_NOT_ASCII_MASK
Definition: winnt_old.h:901
#define IS_TEXT_UNICODE_NULL_BYTES
Definition: winnt_old.h:897
#define IS_TEXT_UNICODE_REVERSE_MASK
Definition: winnt_old.h:899
#define IS_TEXT_UNICODE_REVERSE_SIGNATURE
Definition: winnt_old.h:893
#define IS_TEXT_UNICODE_NOT_UNICODE_MASK
Definition: winnt_old.h:900
#define IS_TEXT_UNICODE_SIGNATURE
Definition: winnt_old.h:892
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define HKEY_CURRENT_USER
Definition: winreg.h:11
#define VK_SPACE
Definition: winuser.h:2218
#define VK_CONTROL
Definition: winuser.h:2202
#define VK_RETURN
Definition: winuser.h:2200
#define VK_BACK
Definition: winuser.h:2197
#define VK_SHIFT
Definition: winuser.h:2201
#define VK_ESCAPE
Definition: winuser.h:2213
#define VK_MENU
Definition: winuser.h:2203
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:227
char TCHAR
Definition: xmlstorage.h:189
__wchar_t WCHAR
Definition: xmlstorage.h:180