ReactOS  0.4.15-dev-1184-g23e04ae
more.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS More Command
4  * FILE: base/applications/cmdutils/more/more.c
5  * PURPOSE: Displays text stream from STDIN or from an arbitrary number
6  * of files to STDOUT, with screen capabilities (more than CAT,
7  * but less than LESS ^^).
8  * PROGRAMMERS: Paolo Pantaleo
9  * Timothy Schepens
10  * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
11  * Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
12  */
13 /*
14  * MORE.C - external command.
15  *
16  * clone from 4nt more command
17  *
18  * 26 Sep 1999 - Paolo Pantaleo <paolopan@freemail.it>
19  * started
20  *
21  * Oct 2003 - Timothy Schepens <tischepe at fastmail dot fm>
22  * use window size instead of buffer size.
23  */
24 
25 #include <stdio.h>
26 
27 #include <windef.h>
28 #include <winbase.h>
29 #include <winnls.h>
30 #include <winuser.h>
31 
32 #include <conutils.h>
33 
34 #include "resource.h"
35 
36 /* PagePrompt statistics for the current file */
37 DWORD dwFileSize; // In bytes
39 // The average number of bytes per character is equal to
40 // dwSumReadBytes / dwSumReadChars. Note that dwSumReadChars
41 // will never be == 0 when ConWritePaging (and possibly PagePrompt)
42 // is called.
43 
44 /* Handles for file and console */
48 
49 
50 static BOOL
52 PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
53 {
55  DWORD dwMode;
56  KEY_EVENT_RECORD KeyEvent;
57 
58  /*
59  * Just use the simple prompt if the file being displayed is the STDIN,
60  * otherwise use the prompt with progress percentage.
61  *
62  * The progress percentage is evaluated as follows.
63  * So far we have read a total of 'dwSumReadBytes' bytes from the file.
64  * Amongst those is the latest read chunk of 'dwReadBytes' bytes, to which
65  * correspond a number of 'dwReadChars' characters with which we have called
66  * ConWritePaging who called PagePrompt. We then have: Total == dwReadChars.
67  * During this ConWritePaging call the PagePrompt was called after 'Done'
68  * number of characters over 'Total'.
69  * It should be noted that for 'dwSumReadBytes' number of bytes read it
70  * *roughly* corresponds 'dwSumReadChars' number of characters. This is
71  * because there may be some failures happening during the conversion of
72  * the bytes read to the character string for a given encoding.
73  * Therefore the number of characters displayed on screen is equal to:
74  * dwSumReadChars - Total + Done ,
75  * but the best corresponding approximed number of bytes would be:
76  * dwSumReadBytes - (Total - Done) * (dwSumReadBytes / dwSumReadChars) ,
77  * where the ratio is the average number of bytes per character.
78  * The percentage is then computed relative to the total file size.
79  */
80  if (hFile == hStdIn)
81  {
83  }
84  else
85  {
87  // (dwSumReadChars - Total + Done) * 100 / dwFileSize
88  (dwSumReadBytes - (Total - Done) *
90  );
91  }
92 
93  // TODO: Implement prompt read line!
94 
95  // FIXME: Does not support TTY yet!
96 
97  /* RemoveBreakHandler */
99  /* ConInDisable */
100  GetConsoleMode(hInput, &dwMode);
101  dwMode &= ~ENABLE_PROCESSED_INPUT;
102  SetConsoleMode(hInput, dwMode);
103 
104  do
105  {
106  // FIXME: Does not support TTY yet!
107 
108  // ConInKey(&KeyEvent);
109  INPUT_RECORD ir;
110  DWORD dwRead;
111  do
112  {
113  ReadConsoleInput(hInput, &ir, 1, &dwRead);
114  }
115  while ((ir.EventType != KEY_EVENT) || (!ir.Event.KeyEvent.bKeyDown));
116 
117  /* Got our key, return to caller */
118  KeyEvent = ir.Event.KeyEvent;
119  }
120  while ((KeyEvent.wVirtualKeyCode == VK_SHIFT) ||
121  (KeyEvent.wVirtualKeyCode == VK_MENU) ||
122  (KeyEvent.wVirtualKeyCode == VK_CONTROL));
123 
124  /* AddBreakHandler */
126  /* ConInEnable */
127  GetConsoleMode(hInput, &dwMode);
128  dwMode |= ENABLE_PROCESSED_INPUT;
129  SetConsoleMode(hInput, dwMode);
130 
131  /*
132  * Erase the full line where the cursor is, and move
133  * the cursor back to the beginning of the line.
134  */
135  ConClearLine(Pager->Screen->Stream);
136 
137  /* Ctrl+C or Ctrl+Esc: Control Break */
138  if ((KeyEvent.wVirtualKeyCode == VK_ESCAPE) ||
139  ((KeyEvent.wVirtualKeyCode == L'C') &&
141  {
142  /* We break, output a newline */
143  WCHAR ch = L'\n';
144  ConStreamWrite(Pager->Screen->Stream, &ch, 1);
145  return FALSE;
146  }
147 
148  /* 'Q': Quit */
149  // FIXME: Available only when command extensions are enabled.
150  if ((KeyEvent.wVirtualKeyCode == L'Q') &&
152  {
153  /* We break, output a newline */
154  WCHAR ch = L'\n';
155  ConStreamWrite(Pager->Screen->Stream, &ch, 1);
156  return FALSE;
157  }
158 
159  return TRUE;
160 }
161 
162 /*
163  * See base/applications/cmdutils/clip/clip.c!IsDataUnicode()
164  * and base/applications/notepad/text.c!ReadText() for more details.
165  * Also some good code example can be found at:
166  * https://github.com/AutoIt/text-encoding-detect
167  */
168 typedef enum
169 {
174 } ENCODING;
175 
176 static BOOL
178  IN PVOID Buffer,
180  OUT ENCODING* Encoding OPTIONAL,
182 {
183  PBYTE pBytes = Buffer;
184  ENCODING encFile = ENCODING_ANSI;
185  DWORD dwPos = 0;
186 
187  /*
188  * See http://archives.miloush.net/michkap/archive/2007/04/22/2239345.html
189  * for more details about the algorithm and the pitfalls behind it.
190  * Of course it would be actually great to make a nice function that
191  * would work, once and for all, and put it into a library.
192  */
193 
194  /* Look for Byte Order Marks */
195  if ((BufferSize >= 2) && (pBytes[0] == 0xFF) && (pBytes[1] == 0xFE))
196  {
197  encFile = ENCODING_UTF16LE;
198  dwPos = 2;
199  }
200  else if ((BufferSize >= 2) && (pBytes[0] == 0xFE) && (pBytes[1] == 0xFF))
201  {
202  encFile = ENCODING_UTF16BE;
203  dwPos = 2;
204  }
205  else if ((BufferSize >= 3) && (pBytes[0] == 0xEF) && (pBytes[1] == 0xBB) && (pBytes[2] == 0xBF))
206  {
207  encFile = ENCODING_UTF8;
208  dwPos = 3;
209  }
210  else
211  {
212  /*
213  * Try using statistical analysis. Do not rely on the return value of
214  * IsTextUnicode as we can get FALSE even if the text is in UTF-16 BE
215  * (i.e. we have some of the IS_TEXT_UNICODE_REVERSE_MASK bits set).
216  * Instead, set all the tests we want to perform, then just check
217  * the passed tests and try to deduce the string properties.
218  */
219 
220 /*
221  * This mask contains the 3 highest bits from IS_TEXT_UNICODE_NOT_ASCII_MASK
222  * and the 1st highest bit from IS_TEXT_UNICODE_NOT_UNICODE_MASK.
223  */
224 #define IS_TEXT_UNKNOWN_FLAGS_MASK ((7 << 13) | (1 << 11))
225 
226  /* Flag out the unknown flags here, the passed tests will not have them either */
231  INT Results;
232 
234  Results = Tests;
235 
236  /*
237  * As the IS_TEXT_UNICODE_NULL_BYTES or IS_TEXT_UNICODE_ILLEGAL_CHARS
238  * flags are expected to be potentially present in the result without
239  * modifying our expectations, filter them out now.
240  */
242 
243  /*
244  * NOTE: The flags IS_TEXT_UNICODE_ASCII16 and
245  * IS_TEXT_UNICODE_REVERSE_ASCII16 are not reliable.
246  *
247  * NOTE2: Check for potential "bush hid the facts" effect by also
248  * checking the original results (in 'Tests') for the absence of
249  * the IS_TEXT_UNICODE_NULL_BYTES flag, as we may presumably expect
250  * that in UTF-16 text there will be at some point some NULL bytes.
251  * If not, fall back to ANSI. This shows the limitations of using the
252  * IsTextUnicode API to perform such tests, and the usage of a more
253  * improved encoding detection algorithm would be really welcome.
254  */
255  if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
256  !(Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
257  (Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
259  {
260  encFile = ENCODING_UTF16LE;
261  dwPos = (Results & IS_TEXT_UNICODE_SIGNATURE) ? 2 : 0;
262  }
263  else
264  if (!(Results & IS_TEXT_UNICODE_NOT_UNICODE_MASK) &&
265  !(Results & IS_TEXT_UNICODE_UNICODE_MASK) &&
266  (Results & IS_TEXT_UNICODE_REVERSE_MASK) &&
268  {
269  encFile = ENCODING_UTF16BE;
270  dwPos = (Results & IS_TEXT_UNICODE_REVERSE_SIGNATURE) ? 2 : 0;
271  }
272  else
273  {
274  /*
275  * Either 'Results' has neither of those masks set, as it can be
276  * the case for UTF-8 text (or ANSI), or it has both as can be the
277  * case when analysing pure binary data chunk. This is therefore
278  * invalid and we fall back to ANSI encoding.
279  * FIXME: In case of failure, assume ANSI (as long as we do not have
280  * correct tests for UTF8, otherwise we should do them, and at the
281  * very end, assume ANSI).
282  */
283  encFile = ENCODING_ANSI; // ENCODING_UTF8;
284  dwPos = 0;
285  }
286  }
287 
288  if (Encoding)
289  *Encoding = encFile;
290  if (SkipBytes)
291  *SkipBytes = dwPos;
292 
293  return (encFile != ENCODING_ANSI);
294 }
295 
296 /*
297  * Adapted from base/shell/cmd/misc.c!FileGetString(), but with correct
298  * text encoding support. Also please note that similar code should be
299  * also used in the CMD.EXE 'TYPE' command.
300  * Contrary to CMD's FileGetString() we do not stop at new-lines.
301  *
302  * Read text data from a file and convert it from a given encoding to UTF-16.
303  *
304  * IN OUT PVOID pCacheBuffer and IN DWORD CacheBufferLength :
305  * Implementation detail so that the function uses an external user-provided
306  * buffer to store the data temporarily read from the file. The function
307  * could have used an internal buffer instead. The length is in number of bytes.
308  *
309  * IN OUT PWSTR* pBuffer and IN OUT PDWORD pnBufferLength :
310  * Reallocated buffer containing the string data converted to UTF-16.
311  * In input, contains a pointer to the original buffer and its length.
312  * In output, contains a pointer to the reallocated buffer and its length.
313  * The length is in number of characters.
314  *
315  * At first call to this function, pBuffer can be set to NULL, in which case
316  * when the function returns the pointer will point to a valid buffer.
317  * After the last call to this function, free the pBuffer pointer with:
318  * HeapFree(GetProcessHeap(), 0, *pBuffer);
319  *
320  * If Encoding is set to ENCODING_UTF16LE or ENCODING_UTF16BE, since we are
321  * compiled in UNICODE, no extra conversion is performed and therefore
322  * pBuffer is unused (remains unallocated) and one can directly use the
323  * contents of pCacheBuffer as it is expected to contain valid UTF-16 text.
324  *
325  * OUT PDWORD pdwReadBytes : Number of bytes read from the file (optional).
326  * OUT PDWORD pdwReadChars : Corresponding number of characters read (optional).
327  */
328 static BOOL
330  IN HANDLE hFile,
331  IN ENCODING Encoding,
332  IN OUT PVOID pCacheBuffer,
333  IN DWORD CacheBufferLength,
334  IN OUT PWCHAR* pBuffer,
335  IN OUT PDWORD pnBufferLength,
336  OUT PDWORD pdwReadBytes OPTIONAL,
337  OUT PDWORD pdwReadChars OPTIONAL)
338 {
339  BOOL Success;
340  UINT CodePage = (UINT)-1;
341  DWORD dwReadBytes;
342  INT len;
343 
344  // ASSERT(pCacheBuffer && (CacheBufferLength > 0));
345  // ASSERT(CacheBufferLength % 2 == 0); // Cache buffer length MUST BE even!
346  // ASSERT(pBuffer && pnBufferLength);
347 
348  /* Always reset the retrieved number of bytes/characters */
349  if (pdwReadBytes) *pdwReadBytes = 0;
350  if (pdwReadChars) *pdwReadChars = 0;
351 
352  Success = ReadFile(hFile, pCacheBuffer, CacheBufferLength, &dwReadBytes, NULL);
353  if (!Success || dwReadBytes == 0)
354  return FALSE;
355 
356  if (pdwReadBytes) *pdwReadBytes = dwReadBytes;
357 
358  if ((Encoding == ENCODING_ANSI) || (Encoding == ENCODING_UTF8))
359  {
360  /* Conversion is needed */
361 
362  if (Encoding == ENCODING_ANSI)
363  CodePage = GetConsoleCP(); // CP_ACP; // FIXME: Cache GetConsoleCP() value.
364  else // if (Encoding == ENCODING_UTF8)
365  CodePage = CP_UTF8;
366 
367  /* Retrieve the needed buffer size */
368  len = MultiByteToWideChar(CodePage, 0, pCacheBuffer, dwReadBytes,
369  NULL, 0);
370  if (len == 0)
371  {
372  /* Failure, bail out */
373  return FALSE;
374  }
375 
376  /* Initialize the conversion buffer if needed... */
377  if (*pBuffer == NULL)
378  {
379  *pnBufferLength = len;
380  *pBuffer = HeapAlloc(GetProcessHeap(), 0, *pnBufferLength * sizeof(WCHAR));
381  if (*pBuffer == NULL)
382  {
383  // *pBuffer = NULL;
384  *pnBufferLength = 0;
385  // WARN("DEBUG: Cannot allocate memory for *pBuffer!\n");
386  // ConErrFormatMessage(GetLastError());
387  return FALSE;
388  }
389  }
390  /* ... or reallocate only if the new length is greater than the old one */
391  else if (len > *pnBufferLength)
392  {
393  PWSTR OldBuffer = *pBuffer;
394 
395  *pnBufferLength = len;
396  *pBuffer = HeapReAlloc(GetProcessHeap(), 0, *pBuffer, *pnBufferLength * sizeof(WCHAR));
397  if (*pBuffer == NULL)
398  {
399  /* Do not leak old buffer */
400  HeapFree(GetProcessHeap(), 0, OldBuffer);
401  // *pBuffer = NULL;
402  *pnBufferLength = 0;
403  // WARN("DEBUG: Cannot reallocate memory for *pBuffer!\n");
404  // ConErrFormatMessage(GetLastError());
405  return FALSE;
406  }
407  }
408 
409  /* Now perform the conversion proper */
410  len = MultiByteToWideChar(CodePage, 0, pCacheBuffer, dwReadBytes,
411  *pBuffer, len);
412  dwReadBytes = len;
413  }
414  else
415  {
416  /*
417  * No conversion needed, just convert from big to little endian if needed.
418  * pBuffer and pnBufferLength are left untouched and pCacheBuffer can be
419  * directly used.
420  */
421  PWCHAR pWChars = pCacheBuffer;
422  DWORD i;
423 
424  dwReadBytes /= sizeof(WCHAR);
425 
426  if (Encoding == ENCODING_UTF16BE)
427  {
428  for (i = 0; i < dwReadBytes; i++)
429  {
430  /* Equivalent to RtlUshortByteSwap: reverse high/low bytes */
431  pWChars[i] = MAKEWORD(HIBYTE(pWChars[i]), LOBYTE(pWChars[i]));
432  }
433  }
434  // else if (Encoding == ENCODING_UTF16LE), we are good, nothing to do.
435  }
436 
437  /* Return the number of characters (dwReadBytes is converted) */
438  if (pdwReadChars) *pdwReadChars = dwReadBytes;
439 
440  return TRUE;
441 }
442 
443 // INT CommandMore(LPTSTR cmd, LPTSTR param)
444 int wmain(int argc, WCHAR* argv[])
445 {
446  // FIXME this stuff!
448  CON_PAGER Pager = {&Screen, 0};
449 
450  int i;
451 
452  BOOL bRet, bContinue;
453 
454  ENCODING Encoding;
455  DWORD SkipBytes = 0;
456 
457 #define FileCacheBufferSize 4096
458  PVOID FileCacheBuffer = NULL;
460  DWORD StringBufferLength = 0;
461  DWORD dwReadBytes, dwReadChars;
462 
463  TCHAR szFullPath[MAX_PATH];
464 
467 
468  /* Initialize the Console Standard Streams */
472 
473  /*
474  * Bad usage (too much options) or we use the /? switch.
475  * Display help for the MORE command.
476  */
477  if (argc > 1 && wcscmp(argv[1], L"/?") == 0)
478  {
480  return 0;
481  }
482 
483  // FIXME: Parse all the remaining parameters.
484  // Then the file list can be found at the very end.
485  // FIXME2: Use the PARSER api that can be found in EVENTCREATE.
486 
487  // NOTE: We might try to duplicate the ConOut for read access... ?
490  OPEN_EXISTING, 0, NULL);
493 
494 
495  FileCacheBuffer = HeapAlloc(GetProcessHeap(), 0, FileCacheBufferSize);
496  if (!FileCacheBuffer)
497  {
498  ConPuts(StdErr, L"Error: no memory\n");
500  return 1;
501  }
502 
503  /* Special case where we run 'MORE' without any argument: we use STDIN */
504  if (argc <= 1)
505  {
506  /*
507  * Assign STDIN handle to hFile so that the page prompt function will
508  * know the data comes from STDIN, and will take different actions.
509  */
510  hFile = hStdIn;
511 
512  /* Update the statistics for PagePrompt */
513  dwFileSize = 0;
515 
516  /* We suppose we read text from the file */
517 
518  /* For STDIN we always suppose we are in ANSI mode */
519  // SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
520  Encoding = ENCODING_ANSI; // ENCODING_UTF8;
521 
522  bContinue = ConPutsPaging(&Pager, PagePrompt, TRUE, L"");
523  if (!bContinue)
524  goto Quit;
525 
526  do
527  {
528  bRet = FileGetString(hFile, Encoding,
529  FileCacheBuffer, FileCacheBufferSize,
530  &StringBuffer, &StringBufferLength,
531  &dwReadBytes, &dwReadChars);
532  if (!bRet || dwReadBytes == 0 || dwReadChars == 0)
533  {
534  /* We failed at reading the file, bail out */
535  break;
536  }
537 
538  /* Update the statistics for PagePrompt */
539  dwSumReadBytes += dwReadBytes;
540  dwSumReadChars += dwReadChars;
541 
542  bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
543  StringBuffer, dwReadChars);
544  /* If we Ctrl-C/Ctrl-Break, stop everything */
545  if (!bContinue)
546  goto Quit;
547  }
548  while (bRet && dwReadBytes > 0);
549  goto Quit;
550  }
551 
552  /* We have files: read them and output them to STDOUT */
553  for (i = 1; i < argc; i++)
554  {
555  GetFullPathNameW(argv[i], ARRAYSIZE(szFullPath), szFullPath, NULL);
556  hFile = CreateFileW(szFullPath,
557  GENERIC_READ,
559  NULL,
561  0, // FILE_ATTRIBUTE_NORMAL,
562  NULL);
564  {
565  ConResPrintf(StdErr, IDS_FILE_ACCESS, szFullPath);
566  continue;
567  }
568 
569  /* We currently do not support files too big */
572  {
573  ConPuts(StdErr, L"ERROR: Invalid file size!\n");
575  continue;
576  }
577 
578  /* We suppose we read text from the file */
579 
580  /* Check whether the file is UNICODE and retrieve its encoding */
582  bRet = ReadFile(hFile, FileCacheBuffer, FileCacheBufferSize, &dwReadBytes, NULL);
583  IsDataUnicode(FileCacheBuffer, dwReadBytes, &Encoding, &SkipBytes);
585 
586  /* Update the statistics for PagePrompt */
588 
589  bContinue = ConPutsPaging(&Pager, PagePrompt, TRUE, L"");
590  if (!bContinue)
591  {
593  goto Quit;
594  }
595 
596  do
597  {
598  bRet = FileGetString(hFile, Encoding,
599  FileCacheBuffer, FileCacheBufferSize,
600  &StringBuffer, &StringBufferLength,
601  &dwReadBytes, &dwReadChars);
602  if (!bRet || dwReadBytes == 0 || dwReadChars == 0)
603  {
604  /*
605  * We failed at reading the file, bail out and
606  * continue with the other files.
607  */
608  break;
609  }
610 
611  /* Update the statistics for PagePrompt */
612  dwSumReadBytes += dwReadBytes;
613  dwSumReadChars += dwReadChars;
614 
615  if ((Encoding == ENCODING_UTF16LE) || (Encoding == ENCODING_UTF16BE))
616  {
617  bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
618  FileCacheBuffer, dwReadChars);
619  }
620  else
621  {
622  bContinue = ConWritePaging(&Pager, PagePrompt, FALSE,
623  StringBuffer, dwReadChars);
624  }
625  /* If we Ctrl-C/Ctrl-Break, stop everything */
626  if (!bContinue)
627  {
629  goto Quit;
630  }
631  }
632  while (bRet && dwReadBytes > 0);
633 
635  }
636 
637 Quit:
639  HeapFree(GetProcessHeap(), 0, FileCacheBuffer);
641  return 0;
642 }
643 
644 /* EOF */
PCON_STREAM Stream
Definition: screen.h:43
static int argc
Definition: ServiceArgs.c:12
#define IN
Definition: typedefs.h:39
#define IDS_CONTINUE
Definition: resource.h:4
static BOOL __stdcall PagePrompt(PCON_PAGER Pager, DWORD Done, DWORD Total)
Definition: more.c:52
#define CloseHandle
Definition: compat.h:487
#define LOBYTE(W)
Definition: jmemdos.c:487
BOOL ConWritePaging(IN PCON_PAGER Pager, IN PAGE_PROMPT PagePrompt, IN BOOL StartPaging, IN PCTCH szStr, IN DWORD len)
Definition: pager.c:38
#define MAKEWORD(a, b)
Definition: typedefs.h:248
#define TRUE
Definition: types.h:120
uint16_t * PWSTR
Definition: typedefs.h:56
DWORD dwSumReadBytes
Definition: more.c:38
BOOL WINAPI GetConsoleMode(HANDLE hConsoleHandle, LPDWORD lpMode)
Definition: console.c:1571
DWORD dwFileSize
Definition: more.c:37
#define IS_TEXT_UNICODE_NOT_ASCII_MASK
Definition: winnt_old.h:934
INT ConPuts(IN PCON_STREAM Stream, IN PCWSTR szStr)
Definition: outstream.c:427
DWORD dwControlKeyState
Definition: wincon.h:248
#define HIBYTE(W)
Definition: jmemdos.c:486
VOID ConClearLine(IN PCON_STREAM Stream)
Definition: outstream.c:1483
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:479
BOOL WINAPI FlushConsoleInputBuffer(IN HANDLE hConsoleInput)
Definition: console.c:217
#define FileCacheBufferSize
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1105
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:200
#define IS_TEXT_UNKNOWN_FLAGS_MASK
#define IDS_USAGE
Definition: resource.h:3
#define INVALID_FILE_SIZE
Definition: winbase.h:529
#define VK_MENU
Definition: winuser.h:2179
#define FILE_BEGIN
Definition: compat.h:509
uint16_t * PWCHAR
Definition: typedefs.h:56
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define argv
Definition: mplay32.c:18
#define VK_ESCAPE
Definition: winuser.h:2189
int32_t INT
Definition: typedefs.h:58
#define FILE_SHARE_READ
Definition: compat.h:136
#define IS_TEXT_UNICODE_SIGNATURE
Definition: winnt_old.h:925
WORD wVirtualKeyCode
Definition: wincon.h:242
PCON_SCREEN Screen
Definition: pager.h:35
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 CP_UTF8
Definition: nls.h:20
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ReadConsoleInput
Definition: wincon.h:781
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleMode(HANDLE hConsoleHandle, DWORD dwMode)
Definition: console.c:1608
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, BOOL Add)
Definition: console.c:2111
#define GENERIC_WRITE
Definition: nt_native.h:90
HANDLE hStdOut
Definition: more.c:46
#define KEY_EVENT
Definition: wincon.h:128
#define VK_SHIFT
Definition: winuser.h:2177
smooth NULL
Definition: ftsmooth.c:416
PVOID pBuffer
INT ConStreamWrite(IN PCON_STREAM Stream, IN PCTCH szStr, IN DWORD len)
Definition: outstream.c:398
Definition: bufpool.h:45
UINT WINAPI DECLSPEC_HOTPATCH GetConsoleCP(VOID)
Definition: console.c:2393
#define STD_INPUT_HANDLE
Definition: winbase.h:264
_Must_inspect_result_ _In_ PHYSICAL_ADDRESS _In_ PHYSICAL_ADDRESS SkipBytes
Definition: mmfuncs.h:226
#define OPEN_EXISTING
Definition: compat.h:523
INT __cdecl ConResPrintf(IN PCON_STREAM Stream, IN UINT uID,...)
Definition: outstream.c:781
HANDLE ConStreamGetOSHandle(IN PCON_STREAM Stream)
Definition: stream.c:240
#define IS_TEXT_UNICODE_REVERSE_SIGNATURE
Definition: winnt_old.h:926
char TCHAR
Definition: xmlstorage.h:189
BOOL ConStreamInit(OUT PCON_STREAM Stream, IN PVOID Handle, IN CON_STREAM_MODE Mode, IN UINT CacheCodePage OPTIONAL)
Definition: stream.c:185
static BOOL IsDataUnicode(IN PVOID Buffer, IN DWORD BufferSize, OUT ENCODING *Encoding OPTIONAL, OUT PDWORD SkipBytes OPTIONAL)
Definition: more.c:177
BOOL WINAPI IsTextUnicode(IN CONST VOID *lpv, IN INT iSize, IN OUT LPINT lpiResult OPTIONAL)
Definition: unicode.c:27
#define GetProcessHeap()
Definition: compat.h:484
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define STD_ERROR_HANDLE
Definition: winbase.h:266
#define MAX_PATH
Definition: compat.h:34
KEY_EVENT_RECORD KeyEvent
Definition: wincon.h:278
#define BufferSize
Definition: mmc.h:75
unsigned long DWORD
Definition: ntddk_ex.h:95
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
Definition: fileinfo.c:331
#define __stdcall
Definition: typedefs.h:25
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:329
#define StdErr
Definition: stream.h:83
#define INVALID_CP
Definition: stream.h:53
INT ConResPuts(IN PCON_STREAM Stream, IN UINT uID)
Definition: outstream.c:610
int wmain(int argc, WCHAR *argv[])
Definition: more.c:444
#define LEFT_CTRL_PRESSED
Definition: wincon.h:140
static const WCHAR L[]
Definition: oid.c:1250
BOOL ConStreamSetOSHandle(IN PCON_STREAM Stream, IN HANDLE Handle)
Definition: stream.c:263
GLenum GLsizei len
Definition: glext.h:6722
#define GENERIC_READ
Definition: compat.h:135
#define STD_OUTPUT_HANDLE
Definition: winbase.h:265
_In_ HANDLE hFile
Definition: mswsock.h:90
#define IS_TEXT_UNICODE_ILLEGAL_CHARS
Definition: winnt_old.h:927
BOOL ConPutsPaging(IN PCON_PAGER Pager, IN PAGE_PROMPT PagePrompt, IN BOOL StartPaging, IN PCTSTR szStr)
Definition: pager.c:120
DWORD dwSumReadChars
Definition: more.c:38
#define ENABLE_PROCESSED_INPUT
Definition: wincon.h:78
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
ENCODING
Definition: more.c:168
HANDLE hStdIn
Definition: more.c:46
#define HeapReAlloc
Definition: compat.h:482
#define ReadFile(a, b, c, d, e)
Definition: compat.h:490
unsigned int UINT
Definition: ndis.h:50
DWORD * PDWORD
Definition: pedump.c:68
#define MultiByteToWideChar
Definition: compat.h:110
#define VK_CONTROL
Definition: winuser.h:2178
WORD EventType
Definition: wincon.h:276
#define CreateFileW
Definition: compat.h:489
union _INPUT_RECORD::@3242 Event
#define OUT
Definition: typedefs.h:40
#define StdOut
Definition: stream.h:82
#define IS_TEXT_UNICODE_REVERSE_MASK
Definition: winnt_old.h:932
#define IDS_FILE_ACCESS
Definition: resource.h:6
Definition: console.h:34
HANDLE hKeyboard
Definition: more.c:47
#define RIGHT_CTRL_PRESSED
Definition: wincon.h:139
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
#define IS_TEXT_UNICODE_NULL_BYTES
Definition: winnt_old.h:930
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
#define IDS_CONTINUE_PROGRESS
Definition: resource.h:5
BYTE * PBYTE
Definition: pedump.c:66
#define IS_TEXT_UNICODE_UNICODE_MASK
Definition: winnt_old.h:931
#define HeapFree(x, y, z)
Definition: compat.h:483
struct test_data Tests[]
#define SetFilePointer
Definition: compat.h:491
#define StdIn
Definition: stream.h:81
#define IS_TEXT_UNICODE_NOT_UNICODE_MASK
Definition: winnt_old.h:933
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68