ReactOS  0.4.10-dev-486-g11b7619
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 */
124  if (pInputControl->nInitialChars <= nNumberOfCharsToRead)
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 
195  RtlCopyMemory(lpBuffer,
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  {
247  *lpNumberOfEventsRead = 0;
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  {
315  RtlCopyMemory(lpBuffer,
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 = ReadOutputRequest->ReadRegion.Right -
440  ReadOutputRequest->ReadRegion.Left + 1;
441 
442  for (y = 0, Y = ReadOutputRequest->ReadRegion.Top; Y <= ReadOutputRequest->ReadRegion.Bottom; ++y, ++Y)
443  {
444  RtlCopyMemory(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
445  ReadOutputRequest->CharInfo + y * SizeX,
446  SizeX * sizeof(CHAR_INFO));
447 #if 0
448  for (x = 0, X = ReadOutputRequest->ReadRegion.Left; X <= ReadOutputRequest->ReadRegion.Right; ++x, ++X)
449  {
450  *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X)) =
451  *(ReadOutputRequest->CharInfo + y * SizeX + x);
452  }
453 #endif
454  }
455  }
456  else
457  {
458  BaseSetLastNTError(ApiMessage.Status);
459  }
460  }
462  {
464  Success = FALSE;
465  }
466  _SEH2_END;
467 
468  /* Release the capture buffer if needed */
469  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
470 
471  /* Return success status */
472  return Success;
473 }
474 
475 
476 static
477 BOOL
479  IN CODE_TYPE CodeType,
480  OUT PVOID pCode,
481  IN DWORD nLength,
482  IN COORD dwReadCoord,
483  OUT LPDWORD lpNumberOfCodesRead)
484 {
485  BOOL Success;
486  CONSOLE_API_MESSAGE ApiMessage;
487  PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
488  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
489  ULONG CodeSize, SizeBytes;
490 
491  DPRINT("IntReadConsoleOutputCode\n");
492 
493  if ( (CodeType != CODE_ASCII ) &&
494  (CodeType != CODE_UNICODE ) &&
495  (CodeType != CODE_ATTRIBUTE) )
496  {
498  return FALSE;
499  }
500 
501  /* Set up the data to send to the Console Server */
502  ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
503  ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
504  ReadOutputCodeRequest->Coord = dwReadCoord;
505  ReadOutputCodeRequest->NumCodes = nLength;
506 
507  /* Determine the needed size */
508  ReadOutputCodeRequest->CodeType = CodeType;
509  switch (CodeType)
510  {
511  case CODE_ASCII:
512  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
513  break;
514 
515  case CODE_UNICODE:
516  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
517  break;
518 
519  case CODE_ATTRIBUTE:
521  break;
522  }
523  SizeBytes = nLength * CodeSize;
524 
525  /*
526  * For optimization purposes, Windows (and hence ReactOS, too, for
527  * compatibility reasons) uses a static buffer if no more than eighty
528  * bytes are read. Otherwise a new buffer is allocated.
529  * This behaviour is also expected in the server-side.
530  */
531  if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
532  {
533  ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
534  // CaptureBuffer = NULL;
535  }
536  else
537  {
538  /* Allocate a Capture Buffer */
539  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
540  if (CaptureBuffer == NULL)
541  {
542  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
544  return FALSE;
545  }
546 
547  /* Allocate space in the Buffer */
548  CsrAllocateMessagePointer(CaptureBuffer,
549  SizeBytes,
550  (PVOID*)&ReadOutputCodeRequest->pCode);
551  }
552 
553  /* Call the server */
555  CaptureBuffer,
557  sizeof(*ReadOutputCodeRequest));
558 
559  /* Check for success */
560  Success = NT_SUCCESS(ApiMessage.Status);
561 
562  /* Retrieve the results */
563  _SEH2_TRY
564  {
565  *lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
566 
567  if (Success)
568  {
569  RtlCopyMemory(pCode,
570  ReadOutputCodeRequest->pCode,
571  ReadOutputCodeRequest->NumCodes * CodeSize);
572  }
573  else
574  {
575  BaseSetLastNTError(ApiMessage.Status);
576  }
577  }
579  {
581  Success = FALSE;
582  }
583  _SEH2_END;
584 
585  /* Release the capture buffer if needed */
586  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
587 
588  /* Return success status */
589  return Success;
590 }
591 
592 
593 /*******************
594  * Write functions *
595  *******************/
596 
597 static
598 BOOL
599 IntWriteConsole(IN HANDLE hConsoleOutput,
600  IN PVOID lpBuffer,
601  IN DWORD nNumberOfCharsToWrite,
602  OUT LPDWORD lpNumberOfCharsWritten,
603  LPVOID lpReserved,
604  IN BOOLEAN bUnicode)
605 {
606  BOOL Success;
607  CONSOLE_API_MESSAGE ApiMessage;
608  PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
609  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
610  ULONG CharSize, SizeBytes;
611 
612  DPRINT("IntWriteConsole\n");
613 
614  /* Set up the data to send to the Console Server */
615  WriteConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
616  WriteConsoleRequest->OutputHandle = hConsoleOutput;
617  WriteConsoleRequest->Unicode = bUnicode;
618 
619  /* Those members are unused by the client, on Windows */
620  WriteConsoleRequest->Reserved1 = 0;
621  // WriteConsoleRequest->Reserved2 = {0};
622 
623  /* Determine the needed size */
624  CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
625  SizeBytes = nNumberOfCharsToWrite * CharSize;
626 
627  WriteConsoleRequest->NumBytes = SizeBytes;
628 
629  /*
630  * For optimization purposes, Windows (and hence ReactOS, too, for
631  * compatibility reasons) uses a static buffer if no more than eighty
632  * bytes are written. Otherwise a new buffer is allocated.
633  * This behaviour is also expected in the server-side.
634  */
635  if (SizeBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
636  {
637  WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
638  // CaptureBuffer = NULL;
639  WriteConsoleRequest->UsingStaticBuffer = TRUE;
640 
641  _SEH2_TRY
642  {
643  RtlCopyMemory(WriteConsoleRequest->Buffer,
644  lpBuffer,
645  SizeBytes);
646  }
648  {
650  _SEH2_YIELD(return FALSE);
651  }
652  _SEH2_END;
653  }
654  else
655  {
656  /* Allocate a Capture Buffer */
657  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
658  if (CaptureBuffer == NULL)
659  {
660  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
662  return FALSE;
663  }
664 
665  /* Capture the buffer to write */
666  CsrCaptureMessageBuffer(CaptureBuffer,
667  (PVOID)lpBuffer,
668  SizeBytes,
669  (PVOID*)&WriteConsoleRequest->Buffer);
670  WriteConsoleRequest->UsingStaticBuffer = FALSE;
671  }
672 
673  /* Call the server */
675  CaptureBuffer,
677  sizeof(*WriteConsoleRequest));
678 
679  /* Check for success */
680  Success = NT_SUCCESS(ApiMessage.Status);
681 
682  /* Release the capture buffer if needed */
683  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
684 
685  /* Retrieve the results */
686  if (Success)
687  {
688  _SEH2_TRY
689  {
690  *lpNumberOfCharsWritten = WriteConsoleRequest->NumBytes / CharSize;
691  }
693  {
695  Success = FALSE;
696  }
697  _SEH2_END;
698  }
699  else
700  {
701  BaseSetLastNTError(ApiMessage.Status);
702  }
703 
704  /* Return success status */
705  return Success;
706 }
707 
708 
709 static
710 BOOL
713  IN DWORD nLength,
714  OUT LPDWORD lpNumberOfEventsWritten,
715  IN BOOLEAN bUnicode,
716  IN BOOLEAN bAppendToEnd)
717 {
718  BOOL Success;
719  CONSOLE_API_MESSAGE ApiMessage;
720  PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
721  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
722 
723  DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
724 
725  /* Set up the data to send to the Console Server */
726  WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
727  WriteInputRequest->InputHandle = hConsoleInput;
728  WriteInputRequest->NumRecords = nLength;
729  WriteInputRequest->Unicode = bUnicode;
730  WriteInputRequest->AppendToEnd = bAppendToEnd;
731 
732  /*
733  * For optimization purposes, Windows (and hence ReactOS, too, for
734  * compatibility reasons) uses a static buffer if no more than five
735  * input records are written. Otherwise a new buffer is allocated.
736  * This behaviour is also expected in the server-side.
737  */
738  if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
739  {
740  WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
741  // CaptureBuffer = NULL;
742 
743  _SEH2_TRY
744  {
745  RtlCopyMemory(WriteInputRequest->RecordBufPtr,
746  lpBuffer,
747  nLength * sizeof(INPUT_RECORD));
748  }
750  {
752  _SEH2_YIELD(return FALSE);
753  }
754  _SEH2_END;
755  }
756  else
757  {
758  ULONG Size = nLength * sizeof(INPUT_RECORD);
759 
760  /* Allocate a Capture Buffer */
761  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
762  if (CaptureBuffer == NULL)
763  {
764  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
766  return FALSE;
767  }
768 
769  /* Capture the user buffer */
770  CsrCaptureMessageBuffer(CaptureBuffer,
771  lpBuffer,
772  Size,
773  (PVOID*)&WriteInputRequest->RecordBufPtr);
774  }
775 
776  /* Call the server */
778  CaptureBuffer,
780  sizeof(*WriteInputRequest));
781 
782  /* Check for success */
783  Success = NT_SUCCESS(ApiMessage.Status);
784 
785  /* Release the capture buffer if needed */
786  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
787 
788  /* Retrieve the results */
789  _SEH2_TRY
790  {
791  DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
792  *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
793 
794  if (!Success)
795  BaseSetLastNTError(ApiMessage.Status);
796  }
798  {
800  Success = FALSE;
801  }
802  _SEH2_END;
803 
804  /* Return success status */
805  return Success;
806 }
807 
808 
809 static
810 BOOL
813  IN COORD dwBufferSize,
814  IN COORD dwBufferCoord,
815  IN OUT PSMALL_RECT lpWriteRegion,
816  IN BOOLEAN bUnicode)
817 {
818  BOOL Success;
819  CONSOLE_API_MESSAGE ApiMessage;
820  PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
821  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
822 
823  SHORT SizeX, SizeY;
824  ULONG NumCells;
825 
826  /* Set up the data to send to the Console Server */
827  WriteOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
828  WriteOutputRequest->OutputHandle = hConsoleOutput;
829  WriteOutputRequest->Unicode = bUnicode;
830 
831  /* Update lpWriteRegion */
832  _SEH2_TRY
833  {
834  SizeX = min(dwBufferSize.X - dwBufferCoord.X, ConioRectWidth(lpWriteRegion));
835  SizeY = min(dwBufferSize.Y - dwBufferCoord.Y, ConioRectHeight(lpWriteRegion));
836  if (SizeX <= 0 || SizeY <= 0)
837  {
839  _SEH2_YIELD(return FALSE);
840  }
841  lpWriteRegion->Right = lpWriteRegion->Left + SizeX - 1;
842  lpWriteRegion->Bottom = lpWriteRegion->Top + SizeY - 1;
843 
844  WriteOutputRequest->WriteRegion = *lpWriteRegion;
845  }
847  {
849  _SEH2_YIELD(return FALSE);
850  }
851  _SEH2_END;
852 
853  NumCells = SizeX * SizeY;
854  DPRINT("IntWriteConsoleOutput: (%d x %d)\n", SizeX, SizeY);
855 
856  /*
857  * For optimization purposes, Windows (and hence ReactOS, too, for
858  * compatibility reasons) uses a static buffer if no more than one
859  * cell is written. Otherwise a new buffer is allocated.
860  * This behaviour is also expected in the server-side.
861  */
862  if (NumCells <= 1)
863  {
864  WriteOutputRequest->CharInfo = &WriteOutputRequest->StaticBuffer;
865  // CaptureBuffer = NULL;
866  WriteOutputRequest->UseVirtualMemory = FALSE;
867  }
868  else
869  {
870  ULONG Size = NumCells * sizeof(CHAR_INFO);
871 
872  /* Allocate a Capture Buffer */
873  CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
874  if (CaptureBuffer)
875  {
876  /* Allocate space in the Buffer */
877  CsrAllocateMessagePointer(CaptureBuffer,
878  Size,
879  (PVOID*)&WriteOutputRequest->CharInfo);
880  WriteOutputRequest->UseVirtualMemory = FALSE;
881  }
882  else
883  {
884  /*
885  * CsrAllocateCaptureBuffer failed because we tried to allocate
886  * a too large (>= 64 kB, size of the CSR heap) data buffer.
887  * To circumvent this, Windows uses a trick (that we reproduce for
888  * compatibility reasons): we allocate a heap buffer in the process'
889  * memory, and CSR will read it via NtReadVirtualMemory.
890  */
891  DPRINT1("CsrAllocateCaptureBuffer failed with size %ld, let's use local heap buffer...\n", Size);
892 
893  WriteOutputRequest->CharInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, Size);
894  WriteOutputRequest->UseVirtualMemory = TRUE;
895 
896  /* Bail out if we still cannot allocate memory */
897  if (WriteOutputRequest->CharInfo == NULL)
898  {
899  DPRINT1("Failed to allocate heap buffer with size %ld!\n", Size);
901  return FALSE;
902  }
903  }
904  }
905 
906  /* Capture the user buffer contents */
907  _SEH2_TRY
908  {
909 #if 0
910  SHORT x, X;
911 #endif
912  SHORT y, Y;
913 
914  /* Copy into the buffer */
915 
916  SizeX = WriteOutputRequest->WriteRegion.Right -
917  WriteOutputRequest->WriteRegion.Left + 1;
918 
919  for (y = 0, Y = WriteOutputRequest->WriteRegion.Top; Y <= WriteOutputRequest->WriteRegion.Bottom; ++y, ++Y)
920  {
921  RtlCopyMemory(WriteOutputRequest->CharInfo + y * SizeX,
922  lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + dwBufferCoord.X,
923  SizeX * sizeof(CHAR_INFO));
924 #if 0
925  for (x = 0, X = WriteOutputRequest->WriteRegion.Left; X <= WriteOutputRequest->WriteRegion.Right; ++x, ++X)
926  {
927  *(WriteOutputRequest->CharInfo + y * SizeX + x) =
928  *(lpBuffer + (y + dwBufferCoord.Y) * dwBufferSize.X + (x + dwBufferCoord.X));
929  }
930 #endif
931  }
932  }
934  {
936  _SEH2_YIELD(return FALSE);
937  }
938  _SEH2_END;
939 
940  /* Call the server */
942  CaptureBuffer,
944  sizeof(*WriteOutputRequest));
945 
946  /* Check for success */
947  Success = NT_SUCCESS(ApiMessage.Status);
948 
949  /* Release the capture buffer if needed */
950  if (CaptureBuffer)
951  {
952  CsrFreeCaptureBuffer(CaptureBuffer);
953  }
954  else
955  {
956  /* If we used a heap buffer, free it */
957  if (WriteOutputRequest->UseVirtualMemory)
958  RtlFreeHeap(RtlGetProcessHeap(), 0, WriteOutputRequest->CharInfo);
959  }
960 
961  /* Retrieve the results */
962  _SEH2_TRY
963  {
964  *lpWriteRegion = WriteOutputRequest->WriteRegion;
965 
966  if (!Success)
967  BaseSetLastNTError(ApiMessage.Status);
968  }
970  {
972  Success = FALSE;
973  }
974  _SEH2_END;
975 
976  /* Return success status */
977  return Success;
978 }
979 
980 
981 static
982 BOOL
984  IN CODE_TYPE CodeType,
985  IN CONST VOID *pCode,
986  IN DWORD nLength,
987  IN COORD dwWriteCoord,
988  OUT LPDWORD lpNumberOfCodesWritten)
989 {
990  BOOL Success;
991  CONSOLE_API_MESSAGE ApiMessage;
992  PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
993  PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
994  ULONG CodeSize, SizeBytes;
995 
996  if ( (CodeType != CODE_ASCII ) &&
997  (CodeType != CODE_UNICODE ) &&
998  (CodeType != CODE_ATTRIBUTE) )
999  {
1001  return FALSE;
1002  }
1003 
1004  DPRINT("IntWriteConsoleOutputCode\n");
1005 
1006  /* Set up the data to send to the Console Server */
1007  WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1008  WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
1009  WriteOutputCodeRequest->Coord = dwWriteCoord;
1010  WriteOutputCodeRequest->NumCodes = nLength;
1011 
1012  /* Determine the needed size */
1013  WriteOutputCodeRequest->CodeType = CodeType;
1014  switch (CodeType)
1015  {
1016  case CODE_ASCII:
1017  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
1018  break;
1019 
1020  case CODE_UNICODE:
1021  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
1022  break;
1023 
1024  case CODE_ATTRIBUTE:
1025  CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
1026  break;
1027  }
1028  SizeBytes = nLength * CodeSize;
1029 
1030  /*
1031  * For optimization purposes, Windows (and hence ReactOS, too, for
1032  * compatibility reasons) uses a static buffer if no more than eighty
1033  * bytes are written. Otherwise a new buffer is allocated.
1034  * This behaviour is also expected in the server-side.
1035  */
1036  if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
1037  {
1038  WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
1039  // CaptureBuffer = NULL;
1040 
1041  _SEH2_TRY
1042  {
1043  RtlCopyMemory(WriteOutputCodeRequest->pCode,
1044  pCode,
1045  SizeBytes);
1046  }
1048  {
1050  _SEH2_YIELD(return FALSE);
1051  }
1052  _SEH2_END;
1053  }
1054  else
1055  {
1056  /* Allocate a Capture Buffer */
1057  CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
1058  if (CaptureBuffer == NULL)
1059  {
1060  DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1062  return FALSE;
1063  }
1064 
1065  /* Capture the buffer to write */
1066  CsrCaptureMessageBuffer(CaptureBuffer,
1067  (PVOID)pCode,
1068  SizeBytes,
1069  (PVOID*)&WriteOutputCodeRequest->pCode);
1070  }
1071 
1072  /* Call the server */
1074  CaptureBuffer,
1076  sizeof(*WriteOutputCodeRequest));
1077 
1078  /* Check for success */
1079  Success = NT_SUCCESS(ApiMessage.Status);
1080 
1081  /* Release the capture buffer if needed */
1082  if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
1083 
1084  /* Retrieve the results */
1085  _SEH2_TRY
1086  {
1087  *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
1088 
1089  if (!Success)
1090  BaseSetLastNTError(ApiMessage.Status);
1091  }
1093  {
1095  Success = FALSE;
1096  }
1097  _SEH2_END;
1098 
1099  /* Return success status */
1100  return Success;
1101 }
1102 
1103 
1104 static
1105 BOOL
1107  IN CODE_TYPE CodeType,
1109  IN DWORD nLength,
1110  IN COORD dwWriteCoord,
1111  OUT LPDWORD lpNumberOfCodesWritten)
1112 {
1113  BOOL Success;
1114  CONSOLE_API_MESSAGE ApiMessage;
1115  PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
1116 
1117  DPRINT("IntFillConsoleOutputCode\n");
1118 
1119  if ( (CodeType != CODE_ASCII ) &&
1120  (CodeType != CODE_UNICODE ) &&
1121  (CodeType != CODE_ATTRIBUTE) )
1122  {
1124  return FALSE;
1125  }
1126 
1127  /* Set up the data to send to the Console Server */
1128  FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1129  FillOutputRequest->OutputHandle = hConsoleOutput;
1130  FillOutputRequest->WriteCoord = dwWriteCoord;
1131  FillOutputRequest->CodeType = CodeType;
1132  FillOutputRequest->Code = Code;
1133  FillOutputRequest->NumCodes = nLength;
1134 
1135  /* Call the server */
1137  NULL,
1139  sizeof(*FillOutputRequest));
1140 
1141  /* Check for success */
1142  Success = NT_SUCCESS(ApiMessage.Status);
1143 
1144  /* Retrieve the results */
1145  _SEH2_TRY
1146  {
1147  *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
1148 
1149  if (!Success)
1150  BaseSetLastNTError(ApiMessage.Status);
1151  }
1153  {
1155  Success = FALSE;
1156  }
1157  _SEH2_END;
1158 
1159  /* Return success status */
1160  return Success;
1161 }
1162 
1163 
1164 /* FUNCTIONS ******************************************************************/
1165 
1166 /******************
1167  * Read functions *
1168  ******************/
1169 
1170 /*
1171  * @implemented
1172  */
1173 BOOL
1174 WINAPI
1176 ReadConsoleW(IN HANDLE hConsoleInput,
1179  OUT LPDWORD lpNumberOfCharsRead,
1181 {
1182  return IntReadConsole(hConsoleInput,
1183  lpBuffer,
1184  nNumberOfCharsToRead,
1185  lpNumberOfCharsRead,
1186  pInputControl,
1187  TRUE);
1188 }
1189 
1190 
1191 /*
1192  * @implemented
1193  */
1194 BOOL
1195 WINAPI
1197 ReadConsoleA(IN HANDLE hConsoleInput,
1200  OUT LPDWORD lpNumberOfCharsRead,
1202 {
1203  return IntReadConsole(hConsoleInput,
1204  lpBuffer,
1205  nNumberOfCharsToRead,
1206  lpNumberOfCharsRead,
1207  NULL,
1208  FALSE);
1209 }
1210 
1211 
1212 /*
1213  * @implemented
1214  */
1215 BOOL
1216 WINAPI
1220  IN DWORD nLength,
1222 {
1223  return IntGetConsoleInput(hConsoleInput,
1224  lpBuffer,
1225  nLength,
1226  lpNumberOfEventsRead,
1228  TRUE);
1229 }
1230 
1231 
1232 /*
1233  * @implemented
1234  */
1235 BOOL
1236 WINAPI
1240  IN DWORD nLength,
1242 {
1243  return IntGetConsoleInput(hConsoleInput,
1244  lpBuffer,
1245  nLength,
1246  lpNumberOfEventsRead,
1248  FALSE);
1249 }
1250 
1251 
1252 /*
1253  * @implemented
1254  */
1255 BOOL
1256 WINAPI
1260  IN DWORD nLength,
1262 {
1263  return IntGetConsoleInput(hConsoleInput,
1264  lpBuffer,
1265  nLength,
1266  lpNumberOfEventsRead,
1267  0,
1268  TRUE);
1269 }
1270 
1271 
1272 /*
1273  * @implemented
1274  */
1275 BOOL
1276 WINAPI
1280  IN DWORD nLength,
1282 {
1283  return IntGetConsoleInput(hConsoleInput,
1284  lpBuffer,
1285  nLength,
1286  lpNumberOfEventsRead,
1287  0,
1288  FALSE);
1289 }
1290 
1291 
1292 /*
1293  * @implemented
1294  */
1295 BOOL
1296 WINAPI
1300  IN DWORD nLength,
1302  IN WORD wFlags)
1303 {
1304  return IntGetConsoleInput(hConsoleInput,
1305  lpBuffer,
1306  nLength,
1307  lpNumberOfEventsRead,
1308  wFlags,
1309  TRUE);
1310 }
1311 
1312 
1313 /*
1314  * @implemented
1315  */
1316 BOOL
1317 WINAPI
1321  IN DWORD nLength,
1323  IN WORD wFlags)
1324 {
1325  return IntGetConsoleInput(hConsoleInput,
1326  lpBuffer,
1327  nLength,
1328  lpNumberOfEventsRead,
1329  wFlags,
1330  FALSE);
1331 }
1332 
1333 
1334 /*
1335  * @implemented
1336  */
1337 BOOL
1338 WINAPI
1342  IN COORD dwBufferSize,
1343  IN COORD dwBufferCoord,
1344  IN OUT PSMALL_RECT lpReadRegion)
1345 {
1346  return IntReadConsoleOutput(hConsoleOutput,
1347  lpBuffer,
1348  dwBufferSize,
1349  dwBufferCoord,
1350  lpReadRegion,
1351  TRUE);
1352 }
1353 
1354 
1355 /*
1356  * @implemented
1357  */
1358 BOOL
1359 WINAPI
1363  IN COORD dwBufferSize,
1364  IN COORD dwBufferCoord,
1365  IN OUT PSMALL_RECT lpReadRegion)
1366 {
1367  return IntReadConsoleOutput(hConsoleOutput,
1368  lpBuffer,
1369  dwBufferSize,
1370  dwBufferCoord,
1371  lpReadRegion,
1372  FALSE);
1373 }
1374 
1375 
1376 /*
1377  * @implemented
1378  */
1379 BOOL
1380 WINAPI
1383  OUT LPWSTR lpCharacter,
1384  IN DWORD nLength,
1385  IN COORD dwReadCoord,
1386  OUT LPDWORD lpNumberOfCharsRead)
1387 {
1388  return IntReadConsoleOutputCode(hConsoleOutput,
1389  CODE_UNICODE,
1390  lpCharacter,
1391  nLength,
1392  dwReadCoord,
1393  lpNumberOfCharsRead);
1394 }
1395 
1396 
1397 /*
1398  * @implemented
1399  */
1400 BOOL
1401 WINAPI
1404  OUT LPSTR lpCharacter,
1405  IN DWORD nLength,
1406  IN COORD dwReadCoord,
1407  OUT LPDWORD lpNumberOfCharsRead)
1408 {
1409  return IntReadConsoleOutputCode(hConsoleOutput,
1410  CODE_ASCII,
1411  lpCharacter,
1412  nLength,
1413  dwReadCoord,
1414  lpNumberOfCharsRead);
1415 }
1416 
1417 
1418 /*
1419  * @implemented
1420  */
1421 BOOL
1422 WINAPI
1425  OUT LPWORD lpAttribute,
1426  IN DWORD nLength,
1427  IN COORD dwReadCoord,
1428  OUT LPDWORD lpNumberOfAttrsRead)
1429 {
1430  return IntReadConsoleOutputCode(hConsoleOutput,
1432  lpAttribute,
1433  nLength,
1434  dwReadCoord,
1435  lpNumberOfAttrsRead);
1436 }
1437 
1438 
1439 /*******************
1440  * Write functions *
1441  *******************/
1442 
1443 /*
1444  * @implemented
1445  */
1446 BOOL
1447 WINAPI
1449 WriteConsoleW(IN HANDLE hConsoleOutput,
1450  IN CONST VOID *lpBuffer,
1451  IN DWORD nNumberOfCharsToWrite,
1452  OUT LPDWORD lpNumberOfCharsWritten,
1453  LPVOID lpReserved)
1454 {
1455  return IntWriteConsole(hConsoleOutput,
1456  (PVOID)lpBuffer,
1457  nNumberOfCharsToWrite,
1458  lpNumberOfCharsWritten,
1459  lpReserved,
1460  TRUE);
1461 }
1462 
1463 
1464 /*
1465  * @implemented
1466  */
1467 BOOL
1468 WINAPI
1470 WriteConsoleA(IN HANDLE hConsoleOutput,
1471  IN CONST VOID *lpBuffer,
1472  IN DWORD nNumberOfCharsToWrite,
1473  OUT LPDWORD lpNumberOfCharsWritten,
1474  LPVOID lpReserved)
1475 {
1476  return IntWriteConsole(hConsoleOutput,
1477  (PVOID)lpBuffer,
1478  nNumberOfCharsToWrite,
1479  lpNumberOfCharsWritten,
1480  lpReserved,
1481  FALSE);
1482 }
1483 
1484 
1485 /*
1486  * @implemented
1487  */
1488 BOOL
1489 WINAPI
1493  IN DWORD nLength,
1494  OUT LPDWORD lpNumberOfEventsWritten)
1495 {
1496  return IntWriteConsoleInput(hConsoleInput,
1497  (PINPUT_RECORD)lpBuffer,
1498  nLength,
1499  lpNumberOfEventsWritten,
1500  TRUE,
1501  TRUE);
1502 }
1503 
1504 
1505 /*
1506  * @implemented
1507  */
1508 BOOL
1509 WINAPI
1513  IN DWORD nLength,
1514  OUT LPDWORD lpNumberOfEventsWritten)
1515 {
1516  return IntWriteConsoleInput(hConsoleInput,
1517  (PINPUT_RECORD)lpBuffer,
1518  nLength,
1519  lpNumberOfEventsWritten,
1520  FALSE,
1521  TRUE);
1522 }
1523 
1524 
1525 /*
1526  * @implemented
1527  */
1528 BOOL
1529 WINAPI
1533  IN DWORD nLength,
1534  OUT LPDWORD lpNumberOfEventsWritten)
1535 {
1536  return IntWriteConsoleInput(hConsoleInput,
1537  (PINPUT_RECORD)lpBuffer,
1538  nLength,
1539  lpNumberOfEventsWritten,
1540  TRUE,
1541  FALSE);
1542 }
1543 
1544 
1545 /*
1546  * @implemented
1547  */
1548 BOOL
1549 WINAPI
1553  IN DWORD nLength,
1554  OUT LPDWORD lpNumberOfEventsWritten)
1555 {
1556  return IntWriteConsoleInput(hConsoleInput,
1557  (PINPUT_RECORD)lpBuffer,
1558  nLength,
1559  lpNumberOfEventsWritten,
1560  FALSE,
1561  FALSE);
1562 }
1563 
1564 
1565 /*
1566  * @implemented
1567  */
1568 BOOL
1569 WINAPI
1573  IN COORD dwBufferSize,
1574  IN COORD dwBufferCoord,
1575  IN OUT PSMALL_RECT lpWriteRegion)
1576 {
1577  return IntWriteConsoleOutput(hConsoleOutput,
1578  lpBuffer,
1579  dwBufferSize,
1580  dwBufferCoord,
1581  lpWriteRegion,
1582  TRUE);
1583 }
1584 
1585 
1586 /*
1587  * @implemented
1588  */
1589 BOOL
1590 WINAPI
1594  IN COORD dwBufferSize,
1595  IN COORD dwBufferCoord,
1596  IN OUT PSMALL_RECT lpWriteRegion)
1597 {
1598  return IntWriteConsoleOutput(hConsoleOutput,
1599  lpBuffer,
1600  dwBufferSize,
1601  dwBufferCoord,
1602  lpWriteRegion,
1603  FALSE);
1604 }
1605 
1606 
1607 /*
1608  * @implemented
1609  */
1610 BOOL
1611 WINAPI
1614  IN LPCWSTR lpCharacter,
1615  IN DWORD nLength,
1616  IN COORD dwWriteCoord,
1617  OUT LPDWORD lpNumberOfCharsWritten)
1618 {
1619  return IntWriteConsoleOutputCode(hConsoleOutput,
1620  CODE_UNICODE,
1621  lpCharacter,
1622  nLength,
1623  dwWriteCoord,
1624  lpNumberOfCharsWritten);
1625 }
1626 
1627 
1628 /*
1629  * @implemented
1630  */
1631 BOOL
1632 WINAPI
1635  IN LPCSTR lpCharacter,
1636  IN DWORD nLength,
1637  IN COORD dwWriteCoord,
1638  OUT LPDWORD lpNumberOfCharsWritten)
1639 {
1640  return IntWriteConsoleOutputCode(hConsoleOutput,
1641  CODE_ASCII,
1642  lpCharacter,
1643  nLength,
1644  dwWriteCoord,
1645  lpNumberOfCharsWritten);
1646 }
1647 
1648 
1649 /*
1650  * @implemented
1651  */
1652 BOOL
1653 WINAPI
1656  IN CONST WORD *lpAttribute,
1657  IN DWORD nLength,
1658  IN COORD dwWriteCoord,
1659  OUT LPDWORD lpNumberOfAttrsWritten)
1660 {
1661  return IntWriteConsoleOutputCode(hConsoleOutput,
1663  lpAttribute,
1664  nLength,
1665  dwWriteCoord,
1666  lpNumberOfAttrsWritten);
1667 }
1668 
1669 
1670 /*
1671  * @implemented
1672  */
1673 BOOL
1674 WINAPI
1677  IN WCHAR cCharacter,
1678  IN DWORD nLength,
1679  IN COORD dwWriteCoord,
1680  OUT LPDWORD lpNumberOfCharsWritten)
1681 {
1683  Code.UnicodeChar = cCharacter;
1684  return IntFillConsoleOutputCode(hConsoleOutput,
1685  CODE_UNICODE,
1686  Code,
1687  nLength,
1688  dwWriteCoord,
1689  lpNumberOfCharsWritten);
1690 }
1691 
1692 
1693 /*
1694  * @implemented
1695  */
1696 BOOL
1697 WINAPI
1700  IN CHAR cCharacter,
1701  IN DWORD nLength,
1702  IN COORD dwWriteCoord,
1703  LPDWORD lpNumberOfCharsWritten)
1704 {
1706  Code.AsciiChar = cCharacter;
1707  return IntFillConsoleOutputCode(hConsoleOutput,
1708  CODE_ASCII,
1709  Code,
1710  nLength,
1711  dwWriteCoord,
1712  lpNumberOfCharsWritten);
1713 }
1714 
1715 
1716 /*
1717  * @implemented
1718  */
1719 BOOL
1720 WINAPI
1723  IN WORD wAttribute,
1724  IN DWORD nLength,
1725  IN COORD dwWriteCoord,
1726  OUT LPDWORD lpNumberOfAttrsWritten)
1727 {
1729  Code.Attribute = wAttribute;
1730  return IntFillConsoleOutputCode(hConsoleOutput,
1732  Code,
1733  nLength,
1734  dwWriteCoord,
1735  lpNumberOfAttrsWritten);
1736 }
1737 
1738 /* EOF */
HANDLE OutputHandle
Definition: conmsg.h:587
DWORD *typedef PVOID
Definition: winlogon.h:60
union _CONSOLE_API_MESSAGE::@3324 Data
#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:1592
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:1722
#define IN
Definition: typedefs.h:38
unsigned short WORD
Definition: ntddk_ex.h:93
ULONG NumRecords
Definition: conmsg.h:568
UINTN Attribute
Definition: acefiex.h:227
#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:1298
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:1634
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:1571
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ DWORD _Out_ LPDWORD lpNumberOfEventsRead
Definition: wincon.h:461
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:1699
__wchar_t WCHAR
Definition: xmlstorage.h:180
USHORT GetCurrentExeName(OUT PWCHAR ExeName, IN USHORT BufferSize)
Definition: console.c:316
CODE_TYPE CodeType
Definition: conmsg.h:535
WCHAR UnicodeChar
Definition: conmsg.h:525
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleW(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1449
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:360
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:983
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:1340
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
_In_ DWORD nLength
Definition: wincon.h:461
HANDLE InputHandle
Definition: conmsg.h:576
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static BOOL IntWriteConsole(IN HANDLE hConsoleOutput, IN PVOID lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved, IN BOOLEAN bUnicode)
Definition: readwrite.c:599
#define Y(i)
Definition: t_vb_render.c:49
BOOLEAN Unicode
Definition: conmsg.h:593
uint16_t * PWCHAR
Definition: typedefs.h:54
static ULONG SizeX
Definition: display.c:138
CODE_ELEMENT Code
Definition: conmsg.h:557
char * LPSTR
Definition: xmlstorage.h:182
#define WCHAR
Definition: msvc.h:43
#define STATUS_ALERTED
Definition: ntstatus.h:80
INPUT_RECORD RecordStaticBuffer[5]
Definition: conmsg.h:566
HANDLE InputHandle
Definition: conmsg.h:565
DWORD DWORD
Definition: winlogon.h:83
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:1531
_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
#define FALSE
Definition: types.h:117
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA(IN HANDLE hConsoleOutput, IN CONST VOID *lpBuffer, IN DWORD nNumberOfCharsToWrite, OUT LPDWORD lpNumberOfCharsWritten, LPVOID lpReserved)
Definition: readwrite.c:1470
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:1361
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:163
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:1491
struct _CHAR_INFO CHAR_INFO
smooth NULL
Definition: ftsmooth.c:416
CHAR AsciiChar
Definition: conmsg.h:524
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:478
#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:479
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:1511
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput, OUT LPSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1403
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
const char * LPCSTR
Definition: xmlstorage.h:183
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1278
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputExA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead, IN WORD wFlags)
Definition: readwrite.c:1319
#define CONST
Definition: compiler.h:170
UINTN Size
Definition: acefiex.h:555
#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:585
SHORT Left
Definition: blue.h:25
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:224
#define Code
Definition: deflate.h:80
CHAR_INFO StaticBuffer
Definition: conmsg.h:601
unsigned char BOOLEAN
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:1176
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI DECLSPEC_HOTPATCH PeekConsoleInputW(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1218
BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleInputVDMA(IN HANDLE hConsoleInput, IN CONST INPUT_RECORD *lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsWritten)
Definition: readwrite.c:1551
#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:1106
CONSOLE_GETINPUT GetInputRequest
Definition: conmsg.h:962
SMALL_RECT WriteRegion
Definition: conmsg.h:604
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
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:1424
ULONG InitialNumBytes
Definition: conmsg.h:266
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:711
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:1197
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:409
SHORT Top
Definition: blue.h:26
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:1613
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
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:811
#define WINAPI
Definition: msvc.h:20
Definition: bl.h:1338
HANDLE ConsoleHandle
Definition: conmsg.h:236
#define CONSOLE_READ_KEEPEVENT
Definition: wincon.h:116
BOOLEAN UsingStaticBuffer
Definition: conmsg.h:246
uint16_t * LPWORD
Definition: typedefs.h:54
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
_In_ DWORD _Out_ _In_opt_ PCONSOLE_READCONSOLE_CONTROL pInputControl
Definition: wincon.h:481
BOOL WINAPI DECLSPEC_HOTPATCH PeekConsoleInputA(IN HANDLE hConsoleInput, OUT PINPUT_RECORD lpBuffer, IN DWORD nLength, OUT LPDWORD lpNumberOfEventsRead)
Definition: readwrite.c:1238
BOOLEAN Unicode
Definition: conmsg.h:580
BOOLEAN Unicode
Definition: conmsg.h:570
#define CONSOLE_READ_CONTINUE
Definition: wincon.h:117
DWORD *typedef HANDLE
Definition: winlogon.h:60
_SEH2_END
Definition: create.c:4424
HANDLE ConsoleHandle
Definition: conmsg.h:575
#define min(a, b)
Definition: monoChain.cc:55
BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput, OUT LPWSTR lpCharacter, IN DWORD nLength, IN COORD dwReadCoord, OUT LPDWORD lpNumberOfCharsRead)
Definition: readwrite.c:1382
HANDLE ConsoleHandle
Definition: conmsg.h:255
#define DPRINT1
Definition: precomp.h:8
CONSOLE_WRITEINPUT WriteInputRequest
Definition: conmsg.h:969
#define OUT
Definition: typedefs.h:39
uint32_t * LPDWORD
Definition: typedefs.h:57
CHAR StaticBuffer[80]
Definition: conmsg.h:239
unsigned int ULONG
Definition: retypes.h:1
WORD Attribute
Definition: conmsg.h:526
#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:1655
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
SHORT Right
Definition: blue.h:27
HANDLE ConsoleHandle
Definition: conmsg.h:586
INT INT y
Definition: msvc.h:62
WCHAR * LPWSTR
Definition: xmlstorage.h:184
enum _CODE_TYPE CODE_TYPE
IN HDEVINFO IN PSP_DEVINFO_DATA DeviceInfoData OPTIONAL
Definition: devinst.c:44
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:1258
#define NtCurrentPeb()
Definition: rtlfuncs.h:1073
BOOL WINAPI DECLSPEC_HOTPATCH FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput, IN WCHAR cCharacter, IN DWORD nLength, IN COORD dwWriteCoord, OUT LPDWORD lpNumberOfCharsWritten)
Definition: readwrite.c:1676
PCHAR_INFO CharInfo
Definition: conmsg.h:602
#define CONSRV_SERVERDLL_INDEX
Definition: conmsg.h:15
INT x
Definition: msvc.h:62
struct _INPUT_RECORD INPUT_RECORD