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