ReactOS  0.4.14-dev-1276-g8aa58c1
readwrite.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: dll/win32/kernel32/client/console/readwrite.c
5  * PURPOSE: Win32 Console Client read-write functions
6  * PROGRAMMERS: Emanuele Aliberti
7  * Marty Dill
8  * Filip Navara (xnavara@volny.cz)
9  * Thomas Weidenmueller (w3seek@reactos.org)
10  * Jeffrey Morlan
11  */
12 
13 /* INCLUDES *******************************************************************/
14 
15 #include <k32.h>
16 
17 #define NDEBUG
18 #include <debug.h>
19 
20 
21 /* See consrv/include/rect.h */
22 #define ConioRectHeight(Rect) \
23  (((Rect)->Top > (Rect)->Bottom) ? 0 : ((Rect)->Bottom - (Rect)->Top + 1))
24 #define ConioRectWidth(Rect) \
25  (((Rect)->Left > (Rect)->Right) ? 0 : ((Rect)->Right - (Rect)->Left + 1))
26 
27 
28 /* PRIVATE FUNCTIONS **********************************************************/
29 
30 /******************
31  * Read functions *
32  ******************/
33 
34 static
35 BOOL
36 IntReadConsole(IN HANDLE hConsoleInput,
39  OUT LPDWORD lpNumberOfCharsRead,
41  IN BOOLEAN bUnicode)
42 {
43  BOOL Success;
44  CONSOLE_API_MESSAGE ApiMessage;
45  PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
46  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
47  ULONG CharSize, SizeBytes;
48 
49  DPRINT("IntReadConsole\n");
50 
51  /* Set up the data to send to the Console Server */
52  ReadConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
53  ReadConsoleRequest->InputHandle = hConsoleInput;
54  ReadConsoleRequest->Unicode = bUnicode;
55 
56  /*
57  * Retrieve the (current) Input EXE name string and length,
58  * not NULL-terminated (always in UNICODE format).
59  */
60  ReadConsoleRequest->ExeLength =
61  GetCurrentExeName((PWCHAR)ReadConsoleRequest->StaticBuffer,
62  sizeof(ReadConsoleRequest->StaticBuffer));
63 
64  /*** For DEBUGGING purposes ***/
65  {
66  UNICODE_STRING ExeName;
67  ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
68  ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
69  DPRINT("IntReadConsole(ExeName = %wZ)\n", &ExeName);
70  }
71  /******************************/
72 
73  /* Determine the needed size */
74  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
75  SizeBytes = nNumberOfCharsToRead * CharSize;
76 
77  ReadConsoleRequest->CaptureBufferSize =
78  ReadConsoleRequest->NumBytes = SizeBytes;
79 
80  /*
81  * For optimization purposes, Windows (and hence ReactOS, too, for
82  * compatibility reasons) uses a static buffer if no more than eighty
83  * bytes are read. Otherwise a new buffer is allocated.
84  * This behaviour is also expected in the server-side.
85  */
86  if (SizeBytes <= sizeof(ReadConsoleRequest->StaticBuffer))
87  {
88  ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
89  // CaptureBuffer = NULL;
90  }
91  else
92  {
93  /* Allocate a Capture Buffer */
94  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
95  if (CaptureBuffer == NULL)
96  {
97  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
99  return FALSE;
100  }
101 
102  /* Allocate space in the Buffer */
103  CsrAllocateMessagePointer(CaptureBuffer,
104  SizeBytes,
105  (PVOID*)&ReadConsoleRequest->Buffer);
106  }
107 
108  ReadConsoleRequest->InitialNumBytes = 0;
109  ReadConsoleRequest->CtrlWakeupMask = 0;
110  ReadConsoleRequest->ControlKeyState = 0;
111 
112  /*
113  * From MSDN (ReadConsole function), the description
114  * for pInputControl says:
115  * "This parameter requires Unicode input by default.
116  * For ANSI mode, set this parameter to NULL."
117  */
118  _SEH2_TRY
119  {
120  if (bUnicode && pInputControl &&
122  {
123  /* Sanity check */
125  {
126  ReadConsoleRequest->InitialNumBytes =
127  pInputControl->nInitialChars * sizeof(WCHAR); // CharSize
128 
129  if (pInputControl->nInitialChars != 0)
130  {
131  /*
132  * It is possible here to overwrite the static buffer, in case
133  * the number of bytes to read was smaller than the static buffer.
134  * In this case, this means we are continuing a pending read,
135  * and we do not need in fact the executable name that was
136  * stored in the static buffer because it was first grabbed when
137  * we started the first read.
138  */
139  RtlCopyMemory(ReadConsoleRequest->Buffer,
140  lpBuffer,
141  ReadConsoleRequest->InitialNumBytes);
142  }
143 
144  ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
145  }
146  else
147  {
148  // Status = STATUS_INVALID_PARAMETER;
149  }
150  }
151  else
152  {
153  /* We are in a situation where pInputControl has no meaning */
155  }
156  }
158  {
159  // HACK
160  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
162  _SEH2_YIELD(return FALSE);
163  }
164  _SEH2_END;
165 
166  /* FIXME: Check for sanity */
167 /*
168  if (!NT_SUCCESS(Status) && pInputControl)
169  {
170  // Free CaptureBuffer if needed
171  // Set last error to last status
172  // Return FALSE
173  }
174 */
175 
176  /* Call the server */
178  CaptureBuffer,
180  sizeof(*ReadConsoleRequest));
181 
182  /* Check for success */
183  Success = NT_SUCCESS(ApiMessage.Status);
184 
185  /* Retrieve the results */
186  if (Success)
187  {
188  _SEH2_TRY
189  {
190  *lpNumberOfCharsRead = ReadConsoleRequest->NumBytes / CharSize;
191 
192  if (bUnicode && pInputControl)
193  pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
194 
196  ReadConsoleRequest->Buffer,
197  ReadConsoleRequest->NumBytes);
198  }
200  {
202  Success = FALSE;
203  }
204  _SEH2_END;
205  }
206  else
207  {
208  BaseSetLastNTError(ApiMessage.Status);
209  }
210 
211  /* Release the capture buffer if needed */
212  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
213 
214  if (Success)
215  {
216  /* Yield execution to another thread if Ctrl-C or Ctrl-Break happened */
217  if (ApiMessage.Status == STATUS_ALERTED /* || ApiMessage.Status == STATUS_CANCELLED */)
218  {
220  SetLastError(ERROR_OPERATION_ABORTED); // STATUS_CANCELLED
221  }
222  }
223 
224  /* Return success status */
225  return Success;
226 }
227 
228 
229 static
230 BOOL
233  IN DWORD nLength,
235  IN WORD wFlags,
236  IN BOOLEAN bUnicode)
237 {
238  BOOL Success;
239  CONSOLE_API_MESSAGE ApiMessage;
240  PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
241  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
242 
243  if (!IsConsoleHandle(hConsoleInput))
244  {
245  _SEH2_TRY
246  {
249  }
251  {
253  }
254  _SEH2_END;
255 
256  return FALSE;
257  }
258 
259  DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
260 
261  /* Set up the data to send to the Console Server */
262  GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
263  GetInputRequest->InputHandle = hConsoleInput;
264  GetInputRequest->NumRecords = nLength;
265  GetInputRequest->Flags = wFlags;
266  GetInputRequest->Unicode = bUnicode;
267 
268  /*
269  * For optimization purposes, Windows (and hence ReactOS, too, for
270  * compatibility reasons) uses a static buffer if no more than five
271  * input records are read. Otherwise a new buffer is allocated.
272  * This behaviour is also expected in the server-side.
273  */
274  if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
275  {
276  GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
277  // CaptureBuffer = NULL;
278  }
279  else
280  {
281  ULONG Size = nLength * sizeof(INPUT_RECORD);
282 
283  /* Allocate a Capture Buffer */
284  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
285  if (CaptureBuffer == NULL)
286  {
287  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
289  return FALSE;
290  }
291 
292  /* Allocate space in the Buffer */
293  CsrAllocateMessagePointer(CaptureBuffer,
294  Size,
295  (PVOID*)&GetInputRequest->RecordBufPtr);
296  }
297 
298  /* Call the server */
300  CaptureBuffer,
302  sizeof(*GetInputRequest));
303 
304  /* Check for success */
305  Success = NT_SUCCESS(ApiMessage.Status);
306 
307  /* Retrieve the results */
308  _SEH2_TRY
309  {
310  DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
311  *lpNumberOfEventsRead = GetInputRequest->NumRecords;
312 
313  if (Success)
314  {
316  GetInputRequest->RecordBufPtr,
317  GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
318  }
319  else
320  {
321  BaseSetLastNTError(ApiMessage.Status);
322  }
323  }
325  {
327  Success = FALSE;
328  }
329  _SEH2_END;
330 
331  /* Release the capture buffer if needed */
332  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
333 
334  /* Return success status */
335  return Success;
336 }
337 
338 
339 static
340 BOOL
343  IN COORD dwBufferSize,
344  IN COORD dwBufferCoord,
345  IN OUT PSMALL_RECT lpReadRegion,
346  IN BOOLEAN bUnicode)
347 {
348  BOOL Success;
349  CONSOLE_API_MESSAGE ApiMessage;
350  PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
351  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
352 
353  SHORT SizeX, SizeY;
354  ULONG NumCells;
355 
356  /* Set up the data to send to the Console Server */
357  ReadOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
358  ReadOutputRequest->OutputHandle = hConsoleOutput;
359  ReadOutputRequest->Unicode = bUnicode;
360 
361  /* Update lpReadRegion */
362  _SEH2_TRY
363  {
364  SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpReadRegion));
365  SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpReadRegion));
366  if (SizeX <= 0 || SizeY <= 0)
367  {
369  _SEH2_YIELD(return FALSE);
370  }
371  lpReadRegion->Right = lpReadRegion->Left + SizeX - 1;
372  lpReadRegion->Bottom = lpReadRegion->Top + SizeY - 1;
373 
374  ReadOutputRequest->ReadRegion = *lpReadRegion;
375  }
377  {
379  _SEH2_YIELD(return FALSE);
380  }
381  _SEH2_END;
382 
383  NumCells = SizeX * SizeY;
384  DPRINT("IntReadConsoleOutput: (%d x %d)\n", SizeX, SizeY);
385 
386  /*
387  * For optimization purposes, Windows (and hence ReactOS, too, for
388  * compatibility reasons) uses a static buffer if no more than one
389  * cell is read. Otherwise a new buffer is allocated.
390  * This behaviour is also expected in the server-side.
391  */
392  if (NumCells <= 1)
393  {
394  ReadOutputRequest->CharInfo = &ReadOutputRequest->StaticBuffer;
395  // CaptureBuffer = NULL;
396  }
397  else
398  {
399  ULONG Size = NumCells * sizeof(CHAR_INFO);
400 
401  /* Allocate a Capture Buffer */
402  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
403  if (CaptureBuffer == NULL)
404  {
405  DPRINT1("CsrAllocateCaptureBuffer failed with size %ld!\n", Size);
407  return FALSE;
408  }
409 
410  /* Allocate space in the Buffer */
411  CsrAllocateMessagePointer(CaptureBuffer,
412  Size,
413  (PVOID*)&ReadOutputRequest->CharInfo);
414  }
415 
416  /* Call the server */
418  CaptureBuffer,
420  sizeof(*ReadOutputRequest));
421 
422  /* Check for success */
423  Success = NT_SUCCESS(ApiMessage.Status);
424 
425  /* Retrieve the results */
426  _SEH2_TRY
427  {
428  *lpReadRegion = ReadOutputRequest->ReadRegion;
429 
430  if (Success)
431  {
432 #if 0
433  SHORT x, X;
434 #endif
435  SHORT y, Y;
436 
437  /* Copy into the buffer */
438 
439  SizeX = ConioRectWidth(&ReadOutputRequest->ReadRegion);
440 
441  for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <= ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y)
442  {
443  RtlCopyMemory(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
444  ReadOutputRequest->CharInfo + y * SizeX,
445  SizeX * sizeof(CHAR_INFO));
446 #if 0
447  for (x = 0, X = ReadOutputRequest->ReadRegion.Left; X <= ReadOutputRequest->ReadRegion.Right; ++x, ++X)
448  {
449  *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X)) =
450  *(ReadOutputRequest->CharInfo + y * SizeX + x);
451  }
452 #endif
453  }
454  }
455  else
456  {
457  BaseSetLastNTError(ApiMessage.Status);
458  }
459  }
461  {
463  Success = FALSE;
464  }
465  _SEH2_END;
466 
467  /* Release the capture buffer if needed */
468  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
469 
470  /* Return success status */
471  return Success;
472 }
473 
474 
475 static
476 BOOL
478  IN CODE_TYPE CodeType,
479  OUT PVOID pCode,
480  IN DWORD nLength,
481  IN COORD dwReadCoord,
482  OUT LPDWORD lpNumberOfCodesRead)
483 {
484  BOOL Success;
485  CONSOLE_API_MESSAGE ApiMessage;
486  PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
487  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
488  ULONG CodeSize, SizeBytes;
489 
490  DPRINT("IntReadConsoleOutputCode\n");
491 
492  if ( (CodeType != CODE_ASCII ) &&
493  (CodeType != CODE_UNICODE ) &&
494  (CodeType != CODE_ATTRIBUTE) )
495  {
497  return FALSE;
498  }
499 
500  /* Set up the data to send to the Console Server */
501  ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
502  ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
503  ReadOutputCodeRequest->Coord = dwReadCoord;
504  ReadOutputCodeRequest->NumCodes = nLength;
505 
506  /* Determine the needed size */
507  ReadOutputCodeRequest->CodeType = CodeType;
508  switch (CodeType)
509  {
510  case CODE_ASCII:
511  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
512  break;
513 
514  case CODE_UNICODE:
515  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
516  break;
517 
518  case CODE_ATTRIBUTE:
519  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
520  break;
521  }
522  SizeBytes = nLength * CodeSize;
523 
524  /*
525  * For optimization purposes, Windows (and hence ReactOS, too, for
526  * compatibility reasons) uses a static buffer if no more than eighty
527  * bytes are read. Otherwise a new buffer is allocated.
528  * This behaviour is also expected in the server-side.
529  */
530  if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
531  {
532  ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
533  // CaptureBuffer = NULL;
534  }
535  else
536  {
537  /* Allocate a Capture Buffer */
538  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
539  if (CaptureBuffer == NULL)
540  {
541  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
543  return FALSE;
544  }
545 
546  /* Allocate space in the Buffer */
547  CsrAllocateMessagePointer(CaptureBuffer,
548  SizeBytes,
549  (PVOID*)&ReadOutputCodeRequest->pCode);
550  }
551 
552  /* Call the server */
554  CaptureBuffer,
556  sizeof(*ReadOutputCodeRequest));
557 
558  /* Check for success */
559  Success = NT_SUCCESS(ApiMessage.Status);
560 
561  /* Retrieve the results */
562  _SEH2_TRY
563  {
564  *lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
565 
566  if (Success)
567  {
568  RtlCopyMemory(pCode,
569  ReadOutputCodeRequest->pCode,
570  ReadOutputCodeRequest->NumCodes * CodeSize);
571  }
572  else
573  {
574  BaseSetLastNTError(ApiMessage.Status);
575  }
576  }
578  {
580  Success = FALSE;
581  }
582  _SEH2_END;
583 
584  /* Release the capture buffer if needed */
585  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
586 
587  /* Return success status */
588  return Success;
589 }
590 
591 
592 /*******************
593  * Write functions *
594  *******************/
595 
596 static
597 BOOL
598 IntWriteConsole(IN HANDLE hConsoleOutput,
599  IN PVOID lpBuffer,
600  IN DWORD nNumberOfCharsToWrite,
601  OUT LPDWORD lpNumberOfCharsWritten,
602  LPVOID lpReserved,
603  IN BOOLEAN bUnicode)
604 {
605  BOOL Success;
606  CONSOLE_API_MESSAGE ApiMessage;
607  PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
608  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
609  ULONG CharSize, SizeBytes;
610 
611  DPRINT("IntWriteConsole\n");
612 
613  /* Set up the data to send to the Console Server */
614  WriteConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
615  WriteConsoleRequest->OutputHandle = hConsoleOutput;
616  WriteConsoleRequest->Unicode = bUnicode;
617 
618  /* Those members are unused by the client, on Windows */
619  WriteConsoleRequest->Reserved1 = 0;
620  // WriteConsoleRequest->Reserved2 = {0};
621 
622  /* Determine the needed size */
623  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
624  SizeBytes = nNumberOfCharsToWrite * CharSize;
625 
626  WriteConsoleRequest->NumBytes = SizeBytes;
627 
628  /*
629  * For optimization purposes, Windows (and hence ReactOS, too, for
630  * compatibility reasons) uses a static buffer if no more than eighty
631  * bytes are written. Otherwise a new buffer is allocated.
632  * This behaviour is also expected in the server-side.
633  */
634  if (SizeBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
635  {
636  WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
637  // CaptureBuffer = NULL;
638  WriteConsoleRequest->UsingStaticBuffer = TRUE;
639 
640  _SEH2_TRY
641  {
642  RtlCopyMemory(WriteConsoleRequest->Buffer,
643  lpBuffer,
644  SizeBytes);
645  }
647  {
649  _SEH2_YIELD(return FALSE);
650  }
651  _SEH2_END;
652  }
653  else
654  {
655  /* Allocate a Capture Buffer */
656  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
657  if (CaptureBuffer == NULL)
658  {
659  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
661  return FALSE;
662  }
663 
664  /* Capture the buffer to write */
665  CsrCaptureMessageBuffer(CaptureBuffer,
666  (PVOID)lpBuffer,
667  SizeBytes,
668  (PVOID*)&WriteConsoleRequest->Buffer);
669  WriteConsoleRequest->UsingStaticBuffer = FALSE;
670  }
671 
672  /* Call the server */
674  CaptureBuffer,
676  sizeof(*WriteConsoleRequest));
677 
678  /* Check for success */
679  Success = NT_SUCCESS(ApiMessage.Status);
680 
681  /* Release the capture buffer if needed */
682  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
683 
684  /* Retrieve the results */
685  if (Success)
686  {
687  _SEH2_TRY
688  {
689  *lpNumberOfCharsWritten = WriteConsoleRequest->NumBytes / CharSize;
690  }
692  {
694  Success = FALSE;
695  }
696  _SEH2_END;
697  }
698  else
699  {
700  BaseSetLastNTError(ApiMessage.Status);
701  }
702 
703  /* Return success status */
704  return Success;
705 }
706 
707 
708 static
709 BOOL
712  IN DWORD nLength,
713  OUT LPDWORD lpNumberOfEventsWritten,
714  IN BOOLEAN bUnicode,
715  IN BOOLEAN bAppendToEnd)
716 {
717  BOOL Success;
718  CONSOLE_API_MESSAGE ApiMessage;
719  PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
720  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
721 
722  DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
723 
724  /* Set up the data to send to the Console Server */
725  WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
726  WriteInputRequest->InputHandle = hConsoleInput;
727  WriteInputRequest->NumRecords = nLength;
728  WriteInputRequest->Unicode = bUnicode;
729  WriteInputRequest->AppendToEnd = bAppendToEnd;
730 
731  /*
732  * For optimization purposes, Windows (and hence ReactOS, too, for
733  * compatibility reasons) uses a static buffer if no more than five
734  * input records are written. Otherwise a new buffer is allocated.
735  * This behaviour is also expected in the server-side.
736  */
737  if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
738  {
739  WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
740  // CaptureBuffer = NULL;
741 
742  _SEH2_TRY
743  {
744  RtlCopyMemory(WriteInputRequest->RecordBufPtr,
745  lpBuffer,
746  nLength * sizeof(INPUT_RECORD));
747  }
749  {
751  _SEH2_YIELD(return FALSE);
752  }
753  _SEH2_END;
754  }
755  else
756  {
757  ULONG Size = nLength * sizeof(INPUT_RECORD);
758 
759  /* Allocate a Capture Buffer */
760  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
761  if (CaptureBuffer == NULL)
762  {
763  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
765  return FALSE;
766  }
767 
768  /* Capture the user buffer */
769  CsrCaptureMessageBuffer(CaptureBuffer,
770  lpBuffer,
771  Size,
772  (PVOID*)&WriteInputRequest->RecordBufPtr);
773  }
774 
775  /* Call the server */
777  CaptureBuffer,
779  sizeof(*WriteInputRequest));
780 
781  /* Check for success */
782  Success = NT_SUCCESS(ApiMessage.Status);
783 
784  /* Release the capture buffer if needed */
785  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
786 
787  /* Retrieve the results */
788  _SEH2_TRY
789  {
790  DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
791  *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
792 
793  if (!Success)
794  BaseSetLastNTError(ApiMessage.Status);
795  }
797  {
799  Success = FALSE;
800  }
801  _SEH2_END;
802 
803  /* Return success status */
804  return Success;
805 }
806 
807 
808 static
809 BOOL
812  IN COORD dwBufferSize,
813  IN COORD dwBufferCoord,
814  IN OUT PSMALL_RECT lpWriteRegion,
815  IN BOOLEAN bUnicode)
816 {
817  BOOL Success;
818  CONSOLE_API_MESSAGE ApiMessage;
819  PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
820  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
821 
822  SHORT SizeX, SizeY;
823  ULONG NumCells;
824 
825  /* Set up the data to send to the Console Server */
826  WriteOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
827  WriteOutputRequest->OutputHandle = hConsoleOutput;
828  WriteOutputRequest->Unicode = bUnicode;
829 
830  /* Update lpWriteRegion */
831  _SEH2_TRY
832  {
833  SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpWriteRegion));
834  SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpWriteRegion));
835  if (SizeX <= 0 || SizeY <= 0)
836  {
838  _SEH2_YIELD(return FALSE);
839  }
840  lpWriteRegion->Right = lpWriteRegion->Left + SizeX - 1;
841  lpWriteRegion->Bottom = lpWriteRegion->Top + SizeY - 1;
842 
843  WriteOutputRequest->WriteRegion = *lpWriteRegion;
844  }
846  {
848  _SEH2_YIELD(return FALSE);
849  }
850  _SEH2_END;
851 
852  NumCells = SizeX * SizeY;
853  DPRINT("IntWriteConsoleOutput: (%d x %d)\n", SizeX, SizeY);
854 
855  /*
856  * For optimization purposes, Windows (and hence ReactOS, too, for
857  * compatibility reasons) uses a static buffer if no more than one
858  * cell is written. Otherwise a new buffer is allocated.
859  * This behaviour is also expected in the server-side.
860  */
861  if (NumCells <= 1)
862  {
863  WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
864  // CaptureBuffer = NULL;
865  WriteOutputRequest->UseVirtualMemory = FALSE;
866  }
867  else
868  {
869  ULONG Size = NumCells * sizeof(CHAR_INFO);
870 
871  /* Allocate a Capture Buffer */
872  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
873  if (CaptureBuffer)
874  {
875  /* Allocate space in the Buffer */
876  CsrAllocateMessagePointer(CaptureBuffer,
877  Size,
878  (PVOID*)&WriteOutputRequest->CharInfo);
879  WriteOutputRequest->UseVirtualMemory = FALSE;
880  }
881  else
882  {
883  /*
884  * CsrAllocateCaptureBuffer failed because we tried to allocate
885  * a too large (>= 64 kB, size of the CSR heap) data buffer.
886  * To circumvent this, Windows uses a trick (that we reproduce for
887  * compatibility reasons): we allocate a heap buffer in the process'
888  * memory, and CSR will read it via NtReadVirtualMemory.
889  */
890  DPRINT1("CsrAllocateCaptureBuffer failed with size %ld, let's use local heap buffer...\n", Size);
891 
892  WriteOutputRequest->CharInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
893  WriteOutputRequest->UseVirtualMemory = TRUE;
894 
895  /* Bail out if we still cannot allocate memory */
896  if (WriteOutputRequest->CharInfo == NULL)
897  {
898  DPRINT1("Failed to allocate heap buffer with size %ld!\n", Size);
900  return FALSE;
901  }
902  }
903  }
904 
905  /* Capture the user buffer contents */
906  _SEH2_TRY
907  {
908 #if 0
909  SHORT x, X;
910 #endif
911  SHORT y, Y;
912 
913  /* Copy into the buffer */
914 
915  SizeX = ConioRectWidth(&WriteOutputRequest->WriteRegion);
916 
917  for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <= WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y)
918  {
919  RtlCopyMemory(WriteOutputRequest->CharInfo + y * SizeX,
920  lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
921  SizeX * sizeof(CHAR_INFO));
922 #if 0
923  for (x = 0, X = WriteOutputRequest->WriteRegion.Left; X <= WriteOutputRequest->WriteRegion.Right; ++x, ++X)
924  {
925  *(WriteOutputRequest->CharInfo + y * SizeX + x) =
926  *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X));
927  }
928 #endif
929  }
930  }
932  {
934  _SEH2_YIELD(return FALSE);
935  }
936  _SEH2_END;
937 
938  /* Call the server */
940  CaptureBuffer,
942  sizeof(*WriteOutputRequest));
943 
944  /* Check for success */
945  Success = NT_SUCCESS(ApiMessage.Status);
946 
947  /* Release the capture buffer if needed */
948  if (CaptureBuffer)
949  {
950  CsrFreeCaptureBuffer(CaptureBuffer);
951  }
952  else
953  {
954  /* If we used a heap buffer, free it */
955  if (WriteOutputRequest->UseVirtualMemory)
956  RtlFreeHeap(RtlGetProcessHeap(), 0, WriteOutputRequest->CharInfo);
957  }
958 
959  /* Retrieve the results */
960  _SEH2_TRY
961  {
962  *lpWriteRegion = WriteOutputRequest->WriteRegion;
963 
964  if (!Success)
965  BaseSetLastNTError(ApiMessage.Status);
966  }
968  {
970  Success = FALSE;
971  }
972  _SEH2_END;
973 
974  /* Return success status */
975  return Success;
976 }
977 
978 
979 static
980 BOOL
982  IN CODE_TYPE CodeType,
983  IN CONST VOID *pCode,
984  IN DWORD nLength,
985  IN COORD dwWriteCoord,
986  OUT LPDWORD lpNumberOfCodesWritten)
987 {
988  BOOL Success;
989  CONSOLE_API_MESSAGE ApiMessage;
990  PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
991  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
992  ULONG CodeSize, SizeBytes;
993 
994  if ( (CodeType != CODE_ASCII ) &&
995  (CodeType != CODE_UNICODE ) &&
996  (CodeType != CODE_ATTRIBUTE) )
997  {
999  return FALSE;
1000  }
1001 
1002  DPRINT("IntWriteConsoleOutputCode\n");
1003 
1004  /* Set up the data to send to the Console Server */
1005  WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1006  WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
1007  WriteOutputCodeRequest->Coord = dwWriteCoord;
1008  WriteOutputCodeRequest->NumCodes = nLength;
1009 
1010  /* Determine the needed size */
1011  WriteOutputCodeRequest->CodeType = CodeType;
1012  switch (CodeType)
1013  {
1014  case CODE_ASCII:
1015  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
1016  break;
1017 
1018  case CODE_UNICODE:
1019  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
1020  break;
1021 
1022  case CODE_ATTRIBUTE:
1023  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
1024  break;
1025  }
1026  SizeBytes = nLength * CodeSize;
1027 
1028  /*
1029  * For optimization purposes, Windows (and hence ReactOS, too, for
1030  * compatibility reasons) uses a static buffer if no more than eighty
1031  * bytes are written. Otherwise a new buffer is allocated.
1032  * This behaviour is also expected in the server-side.
1033  */
1034  if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
1035  {
1036  WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
1037  // CaptureBuffer = NULL;
1038 
1039  _SEH2_TRY
1040  {
1041  RtlCopyMemory(WriteOutputCodeRequest->pCode,
1042  pCode,
1043  SizeBytes);
1044  }
1046  {
1048  _SEH2_YIELD(return FALSE);
1049  }
1050  _SEH2_END;
1051  }
1052  else
1053  {
1054  /* Allocate a Capture Buffer */
1055  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
1056  if (CaptureBuffer == NULL)
1057  {
1058  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1060  return FALSE;
1061  }
1062 
1063  /* Capture the buffer to write */
1064  CsrCaptureMessageBuffer(CaptureBuffer,
1065  (PVOID)pCode,
1066  SizeBytes,
1067  (PVOID*)&WriteOutputCodeRequest->pCode);
1068  }
1069 
1070  /* Call the server */
1072  CaptureBuffer,
1074  sizeof(*WriteOutputCodeRequest));
1075 
1076  /* Check for success */
1077  Success = NT_SUCCESS(ApiMessage.Status);
1078 
1079  /* Release the capture buffer if needed */
1080  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
1081 
1082  /* Retrieve the results */
1083  _SEH2_TRY
1084  {
1085  *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
1086 
1087  if (!Success)
1088  BaseSetLastNTError(ApiMessage.Status);
1089  }
1091  {
1093  Success = FALSE;
1094  }
1095  _SEH2_END;
1096 
1097  /* Return success status */
1098  return Success;
1099 }
1100 
1101 
1102 static
1103 BOOL
1105  IN CODE_TYPE CodeType,
1107  IN DWORD nLength,
1108  IN COORD dwWriteCoord,
1109  OUT LPDWORD lpNumberOfCodesWritten)
1110 {
1111  BOOL Success;
1112  CONSOLE_API_MESSAGE ApiMessage;
1113  PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
1114 
1115  DPRINT("IntFillConsoleOutputCode\n");
1116 
1117  if ( (CodeType != CODE_ASCII ) &&
1118  (CodeType != CODE_UNICODE ) &&
1119  (CodeType != CODE_ATTRIBUTE) )
1120  {
1122  return FALSE;
1123  }
1124 
1125  /* Set up the data to send to the Console Server */
1126  FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1127  FillOutputRequest->OutputHandle = hConsoleOutput;
1128  FillOutputRequest->WriteCoord = dwWriteCoord;
1129  FillOutputRequest->CodeType = CodeType;
1130  FillOutputRequest->Code = Code;
1131  FillOutputRequest->NumCodes = nLength;
1132 
1133  /* Call the server */
1135  NULL,
1137  sizeof(*FillOutputRequest));
1138 
1139  /* Check for success */
1140  Success = NT_SUCCESS(ApiMessage.Status);
1141 
1142  /* Retrieve the results */
1143  _SEH2_TRY
1144  {
1145  *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
1146 
1147  if (!Success)
1148  BaseSetLastNTError(ApiMessage.Status);
1149  }
1151  {
1153  Success = FALSE;
1154  }
1155  _SEH2_END;
1156 
1157  /* Return success status */
1158  return Success;
1159 }
1160 
1161 
1162 /* FUNCTIONS ******************************************************************/
1163 
1164 /******************
1165  * Read functions *
1166  ******************/
1167 
1168 /*
1169  * @implemented
1170  */
1171 BOOL
1172 WINAPI
1174 ReadConsoleW(IN HANDLE hConsoleInput,
1177  OUT LPDWORD lpNumberOfCharsRead,
1179 {
1180  return IntReadConsole(hConsoleInput,
1181  lpBuffer,
1183  lpNumberOfCharsRead,
1184  pInputControl,
1185  TRUE);
1186 }
1187 
1188 
1189 /*
1190  * @implemented
1191  */
1192 BOOL
1193 WINAPI
1195 ReadConsoleA(IN HANDLE hConsoleInput,
1198  OUT LPDWORD lpNumberOfCharsRead,
1200 {
1201  return IntReadConsole(hConsoleInput,
1202  lpBuffer,
1204  lpNumberOfCharsRead,
1205  NULL,
1206  FALSE);
1207 }
1208 
1209 
1210 /*
1211  * @implemented
1212  */
1213 BOOL
1214 WINAPI
1218  IN DWORD nLength,
1220 {
1221  return IntGetConsoleInput(hConsoleInput,
1222  lpBuffer,
1223  nLength,
1226  TRUE);
1227 }
1228 
1229 
1230 /*
1231  * @implemented
1232  */
1233 BOOL
1234 WINAPI
1238  IN DWORD nLength,
1240 {
1241  return IntGetConsoleInput(hConsoleInput,
1242  lpBuffer,
1243  nLength,
1246  FALSE);
1247 }
1248 
1249 
1250 /*
1251  * @implemented
1252  */
1253 BOOL
1254 WINAPI
1258  IN DWORD nLength,
1260 {
1261  return IntGetConsoleInput(hConsoleInput,
1262  lpBuffer,
1263  nLength,
1265  0,
1266  TRUE);
1267 }
1268 
1269 
1270 /*
1271  * @implemented
1272  */
1273 BOOL
1274 WINAPI
1278  IN DWORD nLength,
1280 {
1281  return IntGetConsoleInput(hConsoleInput,
1282  lpBuffer,
1283  nLength,
1285  0,
1286  FALSE);
1287 }
1288 
1289 
1290 /*
1291  * @implemented
1292  */
1293 BOOL
1294 WINAPI
1298  IN DWORD nLength,
1300  IN WORD wFlags)
1301 {
1302  return IntGetConsoleInput(hConsoleInput,
1303  lpBuffer,
1304  nLength,
1306  wFlags,
1307  TRUE);
1308 }
1309 
1310 
1311 /*
1312  * @implemented
1313  */
1314 BOOL
1315 WINAPI
1319  IN DWORD nLength,
1321  IN WORD wFlags)
1322 {
1323  return IntGetConsoleInput(hConsoleInput,
1324  lpBuffer,
1325  nLength,
1327  wFlags,
1328  FALSE);
1329 }
1330 
1331 
1332 /*
1333  * @implemented
1334  */
1335 BOOL
1336 WINAPI
1340  IN COORD dwBufferSize,
1341  IN COORD dwBufferCoord,
1342  IN OUT PSMALL_RECT lpReadRegion)
1343 {
1344  return IntReadConsoleOutput(hConsoleOutput,
1345  lpBuffer,
1346  dwBufferSize,
1347  dwBufferCoord,
1348  lpReadRegion,
1349  TRUE);
1350 }
1351 
1352 
1353 /*
1354  * @implemented
1355  */
1356 BOOL
1357 WINAPI
1361  IN COORD dwBufferSize,
1362  IN COORD dwBufferCoord,
1363  IN OUT PSMALL_RECT lpReadRegion)
1364 {
1365  return IntReadConsoleOutput(hConsoleOutput,
1366  lpBuffer,
1367  dwBufferSize,
1368  dwBufferCoord,
1369  lpReadRegion,
1370  FALSE);
1371 }
1372 
1373 
1374 /*
1375  * @implemented
1376  */
1377 BOOL
1378 WINAPI
1381  OUT LPWSTR lpCharacter,
1382  IN DWORD nLength,
1383  IN COORD dwReadCoord,
1384  OUT LPDWORD lpNumberOfCharsRead)
1385 {
1386  return IntReadConsoleOutputCode(hConsoleOutput,
1387  CODE_UNICODE,
1388  lpCharacter,
1389  nLength,
1390  dwReadCoord,
1391  lpNumberOfCharsRead);
1392 }
1393 
1394 
1395 /*
1396  * @implemented
1397  */
1398 BOOL
1399 WINAPI
1402  OUT LPSTR lpCharacter,
1403  IN DWORD nLength,
1404  IN COORD dwReadCoord,
1405  OUT LPDWORD lpNumberOfCharsRead)
1406 {
1407  return IntReadConsoleOutputCode(hConsoleOutput,
1408  CODE_ASCII,
1409  lpCharacter,
1410  nLength,
1411  dwReadCoord,
1412  lpNumberOfCharsRead);
1413 }
1414 
1415 
1416 /*
1417  * @implemented
1418  */
1419 BOOL
1420 WINAPI
1423  OUT LPWORD lpAttribute,
1424  IN DWORD nLength,
1425  IN COORD dwReadCoord,
1426  OUT LPDWORD lpNumberOfAttrsRead)
1427 {
1428  return IntReadConsoleOutputCode(hConsoleOutput,
1430  lpAttribute,
1431  nLength,
1432  dwReadCoord,
1433  lpNumberOfAttrsRead);
1434 }
1435 
1436 
1437 /*******************
1438  * Write functions *
1439  *******************/
1440 
1441 /*
1442  * @implemented
1443  */
1444 BOOL
1445 WINAPI
1447 WriteConsoleW(IN HANDLE hConsoleOutput,
1448  IN CONST VOID *lpBuffer,
1449  IN DWORD nNumberOfCharsToWrite,
1450  OUT LPDWORD lpNumberOfCharsWritten,
1451  LPVOID lpReserved)
1452 {
1453  return IntWriteConsole(hConsoleOutput,
1454  (PVOID)lpBuffer,
1455  nNumberOfCharsToWrite,
1456  lpNumberOfCharsWritten,
1457  lpReserved,
1458  TRUE);
1459 }
1460 
1461 
1462 /*
1463  * @implemented
1464  */
1465 BOOL
1466 WINAPI
1468 WriteConsoleA(IN HANDLE hConsoleOutput,
1469  IN CONST VOID *lpBuffer,
1470  IN DWORD nNumberOfCharsToWrite,
1471  OUT LPDWORD lpNumberOfCharsWritten,
1472  LPVOID lpReserved)
1473 {
1474  return IntWriteConsole(hConsoleOutput,
1475  (PVOID)lpBuffer,
1476  nNumberOfCharsToWrite,
1477  lpNumberOfCharsWritten,
1478  lpReserved,
1479  FALSE);
1480 }
1481 
1482 
1483 /*
1484  * @implemented
1485  */
1486 BOOL
1487 WINAPI
1491  IN DWORD nLength,
1492  OUT LPDWORD lpNumberOfEventsWritten)
1493 {
1494  return IntWriteConsoleInput(hConsoleInput,
1496  nLength,
1497  lpNumberOfEventsWritten,
1498  TRUE,
1499  TRUE);
1500 }
1501 
1502 
1503 /*
1504  * @implemented
1505  */
1506 BOOL
1507 WINAPI
1511  IN DWORD nLength,
1512  OUT LPDWORD lpNumberOfEventsWritten)
1513 {
1514  return IntWriteConsoleInput(hConsoleInput,
1516  nLength,
1517  lpNumberOfEventsWritten,
1518  FALSE,
1519  TRUE);
1520 }
1521 
1522 
1523 /*
1524  * @implemented
1525  */
1526 BOOL
1527 WINAPI
1531  IN DWORD nLength,
1532  OUT LPDWORD lpNumberOfEventsWritten)
1533 {
1534  return IntWriteConsoleInput(hConsoleInput,
1536  nLength,
1537  lpNumberOfEventsWritten,
1538  TRUE,
1539  FALSE);
1540 }
1541 
1542 
1543 /*
1544  * @implemented
1545  */
1546 BOOL
1547 WINAPI
1551  IN DWORD nLength,
1552  OUT LPDWORD lpNumberOfEventsWritten)
1553 {
1554  return IntWriteConsoleInput(hConsoleInput,
1556  nLength,
1557  lpNumberOfEventsWritten,
1558  FALSE,
1559  FALSE);
1560 }
1561 
1562 
1563 /*
1564  * @implemented
1565  */
1566 BOOL
1567 WINAPI
1571  IN COORD dwBufferSize,
1572  IN COORD dwBufferCoord,
1573  IN OUT PSMALL_RECT lpWriteRegion)
1574 {
1575  return IntWriteConsoleOutput(hConsoleOutput,
1576  lpBuffer,
1577  dwBufferSize,
1578  dwBufferCoord,
1579  lpWriteRegion,
1580  TRUE);
1581 }
1582 
1583 
1584 /*
1585  * @implemented
1586  */
1587 BOOL
1588 WINAPI
1592  IN COORD dwBufferSize,
1593  IN COORD dwBufferCoord,
1594  IN OUT PSMALL_RECT lpWriteRegion)
1595 {
1596  return IntWriteConsoleOutput(hConsoleOutput,
1597  lpBuffer,
1598  dwBufferSize,
1599  dwBufferCoord,
1600  lpWriteRegion,
1601  FALSE);
1602 }
1603 
1604 
1605 /*
1606  * @implemented
1607  */
1608 BOOL
1609 WINAPI
1612  IN LPCWSTR lpCharacter,
1613  IN DWORD nLength,
1614  IN COORD dwWriteCoord,
1615  OUT LPDWORD lpNumberOfCharsWritten)
1616 {
1617  return IntWriteConsoleOutputCode(hConsoleOutput,
1618  CODE_UNICODE,
1619  lpCharacter,
1620  nLength,
1621  dwWriteCoord,
1622  lpNumberOfCharsWritten);
1623 }
1624 
1625 
1626 /*
1627  * @implemented
1628  */
1629 BOOL
1630 WINAPI
1633  IN LPCSTR lpCharacter,
1634  IN DWORD nLength,
1635  IN COORD dwWriteCoord,
1636  OUT LPDWORD lpNumberOfCharsWritten)
1637 {
1638  return IntWriteConsoleOutputCode(hConsoleOutput,
1639  CODE_ASCII,
1640  lpCharacter,
1641  nLength,
1642  dwWriteCoord,
1643  lpNumberOfCharsWritten);
1644 }
1645 
1646 
1647 /*
1648  * @implemented
1649  */
1650 BOOL
1651 WINAPI
1654  IN CONST WORD *lpAttribute,
1655  IN DWORD nLength,
1656  IN COORD dwWriteCoord,
1657  OUT LPDWORD lpNumberOfAttrsWritten)
1658 {
1659  return IntWriteConsoleOutputCode(hConsoleOutput,
1661  lpAttribute,
1662  nLength,
1663  dwWriteCoord,
1664  lpNumberOfAttrsWritten);
1665 }
1666 
1667 
1668 /*
1669  * @implemented
1670  */
1671 BOOL
1672 WINAPI
1675  IN WCHAR cCharacter,
1676  IN DWORD nLength,
1677  IN COORD dwWriteCoord,
1678  OUT LPDWORD lpNumberOfCharsWritten)
1679 {
1681  Code.UnicodeChar = cCharacter;
1682  return IntFillConsoleOutputCode(hConsoleOutput,
1683  CODE_UNICODE,
1684  Code,
1685  nLength,
1686  dwWriteCoord,
1687  lpNumberOfCharsWritten);
1688 }
1689 
1690 
1691 /*
1692  * @implemented
1693  */
1694 BOOL
1695 WINAPI
1698  IN CHAR cCharacter,
1699  IN DWORD nLength,
1700  IN COORD dwWriteCoord,
1701  LPDWORD lpNumberOfCharsWritten)
1702 {
1704  Code.AsciiChar = cCharacter;
1705  return IntFillConsoleOutputCode(hConsoleOutput,
1706  CODE_ASCII,
1707  Code,
1708  nLength,
1709  dwWriteCoord,
1710  lpNumberOfCharsWritten);
1711 }
1712 
1713 
1714 /*
1715  * @implemented
1716  */
1717 BOOL
1718 WINAPI
1721  IN WORD wAttribute,
1722  IN DWORD nLength,
1723  IN COORD dwWriteCoord,
1724  OUT LPDWORD lpNumberOfAttrsWritten)
1725 {
1727  Code.Attribute = wAttribute;
1728  return IntFillConsoleOutputCode(hConsoleOutput,
1730  Code,
1731  nLength,
1732  dwWriteCoord,
1733  lpNumberOfAttrsWritten);
1734 }
1735 
1736 /* EOF */
HANDLE OutputHandle
Definition: conmsg.h:587
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
HANDLE ConsoleHandle
Definition: conmsg.h:598
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputA(IN HANDLE hConsoleOutput, IN CONST CHAR_INFO *lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpWriteRegion)
Definition: readwrite.c:1590
VOID NTAPI CsrFreeCaptureBuffer(IN PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:189
#define RTL_FIELD_SIZE(type, field)
Definition: kdb_expr.c:84
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN WORD wAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: readwrite.c:1720
#define IN
Definition: typedefs.h:39
ULONG NumRecords
Definition: conmsg.h:568
#define TRUE
Definition: types.h:120
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputExW(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead, IN WORD wFlags)
Definition: readwrite.c:1296
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput, IN LPCSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1632
static BOOL IntGetConsoleInput(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead, IN WORD wFlags, IN BOOLEAN bUnicode)
Definition: readwrite.c:231
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputW(IN HANDLE hConsoleOutput, IN CONST CHAR_INFO *lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpWriteRegion)
Definition: readwrite.c:1569
#define Y(I)
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ DWORD _Out_ LPDWORD lpNumberOfEventsRead
Definition: wincon.h:476
HANDLE InputHandle
Definition: conmsg.h:256
ULONG NTAPI CsrAllocateMessagePointer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN ULONG MessageLength, OUT PVOID *CapturedData)
Definition: capture.c:133
PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(IN ULONG ArgumentCount, IN ULONG BufferSize)
Definition: capture.c:90
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput, IN CHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1697
USHORT GetCurrentExeName(OUT PWCHAR ExeName, IN USHORT BufferSize)
Definition: console.c:316
CODE_TYPE CodeType
Definition: conmsg.h:535
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1447
NTSTATUS NTAPI CsrClientCallServer(IN OUT PCSR_API_MESSAGE ApiMessage, IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer OPTIONAL, IN CSR_API_NUMBER ApiNumber, IN ULONG DataLength)
Definition: connect.c:365
static BOOL IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput, IN CODE_TYPE CodeType, IN CONST VOID *pCode, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCodesWritten)
Definition: readwrite.c:981
char CHAR
Definition: xmlstorage.h:175
HANDLE ConsoleHandle
Definition: conmsg.h:564
ULONG ControlKeyState
Definition: conmsg.h:268
#define ERROR_INVALID_HANDLE
Definition: compat.h:88
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputW(IN HANDLE hConsoleOutput, OUT PCHAR_INFO lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpReadRegion)
Definition: readwrite.c:1338
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
_In_ DWORD nLength
Definition: wincon.h:476
HANDLE InputHandle
Definition: conmsg.h:576
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
static BOOL IntWriteConsole(IN HANDLE hConsoleOutput, IN PVOID lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved, IN BOOLEAN bUnicode)
Definition: readwrite.c:598
BOOLEAN Unicode
Definition: conmsg.h:593
uint16_t * PWCHAR
Definition: typedefs.h:55
static ULONG SizeX
Definition: display.c:138
CODE_ELEMENT Code
Definition: conmsg.h:557
char * LPSTR
Definition: xmlstorage.h:182
#define STATUS_ALERTED
Definition: ntstatus.h:80
INPUT_RECORD RecordStaticBuffer[5]
Definition: conmsg.h:566
HANDLE InputHandle
Definition: conmsg.h:565
CHAR StaticBuffer[80]
Definition: conmsg.h:260
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleInputVDMW(IN HANDLE hConsoleInput, IN CONST INPUT_RECORD *lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten)
Definition: readwrite.c:1529
_SEH2_TRY
Definition: create.c:4250
#define ERROR_OPERATION_ABORTED
Definition: winerror.h:575
BOOLEAN UseVirtualMemory
Definition: conmsg.h:612
CONSOLE_WRITEOUTPUT WriteOutputRequest
Definition: conmsg.h:970
NTSTATUS Status
Definition: csrmsg.h:112
VOID NTAPI CsrCaptureMessageBuffer(IN OUT PCSR_CAPTURE_BUFFER CaptureBuffer, IN PVOID MessageBuffer OPTIONAL, IN ULONG MessageLength, OUT PVOID *CapturedData)
Definition: capture.c:169
ULONG CtrlWakeupMask
Definition: conmsg.h:267
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1468
unsigned int BOOL
Definition: ntddk_ex.h:94
CONSOLE_READOUTPUT ReadOutputRequest
Definition: conmsg.h:963
short SHORT
Definition: pedump.c:59
#define ConioRectWidth(Rect)
Definition: readwrite.c:24
CODE_TYPE CodeType
Definition: conmsg.h:556
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputA(IN HANDLE hConsoleOutput, OUT PCHAR_INFO lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpReadRegion)
Definition: readwrite.c:1359
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:173
static BOOL IntReadConsole(IN HANDLE hConsoleInput, OUT PVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL, IN BOOLEAN bUnicode)
Definition: readwrite.c:36
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleInputW(IN HANDLE hConsoleInput, IN CONST INPUT_RECORD *lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten)
Definition: readwrite.c:1489
unsigned char BOOLEAN
struct _CHAR_INFO CHAR_INFO
smooth NULL
Definition: ftsmooth.c:416
static BOOL IntReadConsoleOutputCode(IN HANDLE hConsoleOutput, IN CODE_TYPE CodeType, OUT PVOID pCode, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCodesRead)
Definition: readwrite.c:477
#define ConioRectHeight(Rect)
Definition: readwrite.c:22
ULONG CaptureBufferSize
Definition: conmsg.h:264
void DPRINT(...)
Definition: polytest.cpp:61
_In_ DWORD nNumberOfCharsToRead
Definition: wincon.h:494
HANDLE OutputHandle
Definition: conmsg.h:599
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleInputA(IN HANDLE hConsoleInput, IN CONST INPUT_RECORD *lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten)
Definition: readwrite.c:1509
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput, OUT LPSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1401
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
const char * LPCSTR
Definition: xmlstorage.h:183
union _CONSOLE_API_MESSAGE::@3429 Data
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1276
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputExA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead, IN WORD wFlags)
Definition: readwrite.c:1317
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
SHORT Left
Definition: blue.h:32
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:242
#define Code
Definition: deflate.h:80
CHAR_INFO StaticBuffer
Definition: conmsg.h:601
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleW(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1174
BOOL WINAPI DECLSPEC_HOTPATCH PeekConsoleInputW(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1216
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleInputVDMA(IN HANDLE hConsoleInput, IN CONST INPUT_RECORD *lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten)
Definition: readwrite.c:1549
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
static BOOL IntFillConsoleOutputCode(IN HANDLE hConsoleOutput, IN CODE_TYPE CodeType, IN CODE_ELEMENT Code, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCodesWritten)
Definition: readwrite.c:1104
CONSOLE_GETINPUT GetInputRequest
Definition: conmsg.h:962
__wchar_t WCHAR
Definition: xmlstorage.h:180
SMALL_RECT WriteRegion
Definition: conmsg.h:604
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSTATUS NTAPI NtYieldExecution(VOID)
Definition: thrdschd.c:744
CONSOLE_READOUTPUTCODE ReadOutputCodeRequest
Definition: conmsg.h:964
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput, OUT LPWORD lpAttribute, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfAttrsRead)
Definition: readwrite.c:1422
ULONG InitialNumBytes
Definition: conmsg.h:266
#define WINAPI
Definition: msvc.h:6
CHAR CodeStaticBuffer[80]
Definition: conmsg.h:536
static BOOL IntWriteConsoleInput(IN HANDLE hConsoleInput, IN PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten, IN BOOLEAN bUnicode, IN BOOLEAN bAppendToEnd)
Definition: readwrite.c:710
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleA(IN HANDLE hConsoleInput, OUT LPVOID lpBuffer, IN DWORD nNumberOfCharsToRead, OUT LPDWORD lpNumberOfCharsRead, IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
Definition: readwrite.c:1195
PINPUT_RECORD RecordBufPtr
Definition: conmsg.h:567
CONSOLE_FILLOUTPUTCODE FillOutputRequest
Definition: conmsg.h:973
PCHAR_INFO CharInfo
Definition: conmsg.h:590
#define SetLastError(x)
Definition: compat.h:417
SHORT Top
Definition: blue.h:33
PINPUT_RECORD RecordBufPtr
Definition: conmsg.h:578
#define IsConsoleHandle(h)
Definition: console.h:14
INPUT_RECORD RecordStaticBuffer[5]
Definition: conmsg.h:577
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN LPCWSTR lpCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1611
CONSOLE_READCONSOLE ReadConsoleRequest
Definition: conmsg.h:961
BOOLEAN AppendToEnd
Definition: conmsg.h:581
SMALL_RECT ReadRegion
Definition: conmsg.h:592
CONSOLE_WRITECONSOLE WriteConsoleRequest
Definition: conmsg.h:968
#define ERROR_INVALID_ACCESS
Definition: winerror.h:115
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
static BOOL IntWriteConsoleOutput(IN HANDLE hConsoleOutput, IN CONST CHAR_INFO *lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpWriteRegion, IN BOOLEAN bUnicode)
Definition: readwrite.c:810
Definition: bl.h:1338
HANDLE ConsoleHandle
Definition: conmsg.h:236
#define CONSOLE_READ_KEEPEVENT
Definition: wincon.h:122
BOOLEAN UsingStaticBuffer
Definition: conmsg.h:246
uint16_t * LPWORD
Definition: typedefs.h:55
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:534
_In_ DWORD _Out_ _In_opt_ PCONSOLE_READCONSOLE_CONTROL pInputControl
Definition: wincon.h:496
BOOL WINAPI DECLSPEC_HOTPATCH PeekConsoleInputA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1236
BOOLEAN Unicode
Definition: conmsg.h:580
BOOLEAN Unicode
Definition: conmsg.h:570
#define CONSOLE_READ_CONTINUE
Definition: wincon.h:123
_SEH2_END
Definition: create.c:4424
#define NtCurrentPeb()
Definition: FLS.c:20
HANDLE ConsoleHandle
Definition: conmsg.h:575
#define min(a, b)
Definition: monoChain.cc:55
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput, OUT LPWSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1380
HANDLE ConsoleHandle
Definition: conmsg.h:255
#define DPRINT1
Definition: precomp.h:8
CONSOLE_WRITEINPUT WriteInputRequest
Definition: conmsg.h:969
#define OUT
Definition: typedefs.h:40
uint32_t * LPDWORD
Definition: typedefs.h:58
CHAR StaticBuffer[80]
Definition: conmsg.h:239
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput, IN CONST WORD *lpAttribute, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfAttrsWritten)
Definition: readwrite.c:1653
CONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest
Definition: conmsg.h:971
static BOOL IntReadConsoleOutput(IN HANDLE hConsoleOutput, OUT PCHAR_INFO lpBuffer, IN COORD dwBufferSize, IN COORD dwBufferCoord, IN OUT PSMALL_RECT lpReadRegion, IN BOOLEAN bUnicode)
Definition: readwrite.c:341
HANDLE OutputHandle
Definition: conmsg.h:532
WCHAR * LPWSTR
Definition: xmlstorage.h:184
HANDLE ConsoleHandle
Definition: conmsg.h:586
enum _CODE_TYPE CODE_TYPE
#define CONST
Definition: pedump.c:81
HANDLE ConsoleHandle
Definition: conmsg.h:531
static ULONG SizeY
Definition: display.c:139
CHAR_INFO StaticBuffer
Definition: conmsg.h:589
#define X(b, s)
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputW(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1256
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1674
PCHAR_INFO CharInfo
Definition: conmsg.h:602
#define CONSRV_SERVERDLL_INDEX
Definition: conmsg.h:15
struct _INPUT_RECORD INPUT_RECORD
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68