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
8 * Filip Navara (xnavara@volny.cz)
9 * Thomas Weidenmueller (w3seek@reactos.org)
13 /* INCLUDES *******************************************************************/
21 /* PRIVATE FUNCTIONS **********************************************************/
29 IntReadConsole(HANDLE hConsoleInput
,
31 DWORD nNumberOfCharsToRead
,
32 LPDWORD lpNumberOfCharsRead
,
33 PCONSOLE_READCONSOLE_CONTROL pInputControl
,
36 CONSOLE_API_MESSAGE ApiMessage
;
37 PCONSOLE_READCONSOLE ReadConsoleRequest
= &ApiMessage
.Data
.ReadConsoleRequest
;
38 PCSR_CAPTURE_BUFFER CaptureBuffer
;
41 /* Determine the needed size */
42 CharSize
= (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
43 ReadConsoleRequest
->BufferSize
= nNumberOfCharsToRead
* CharSize
;
45 /* Allocate a Capture Buffer */
46 CaptureBuffer
= CsrAllocateCaptureBuffer(1, ReadConsoleRequest
->BufferSize
);
47 if (CaptureBuffer
== NULL
)
49 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
50 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
54 /* Allocate space in the Buffer */
55 CsrAllocateMessagePointer(CaptureBuffer
,
56 ReadConsoleRequest
->BufferSize
,
57 (PVOID
*)&ReadConsoleRequest
->Buffer
);
59 /* Set up the data to send to the Console Server */
60 ReadConsoleRequest
->InputHandle
= hConsoleInput
;
61 ReadConsoleRequest
->Unicode
= bUnicode
;
62 ReadConsoleRequest
->NrCharactersToRead
= nNumberOfCharsToRead
;
63 ReadConsoleRequest
->NrCharactersRead
= 0;
64 ReadConsoleRequest
->CtrlWakeupMask
= 0;
65 if (pInputControl
&& pInputControl
->nLength
== sizeof(CONSOLE_READCONSOLE_CONTROL
))
68 * From MSDN (ReadConsole function), the description
69 * for pInputControl says:
70 * "This parameter requires Unicode input by default.
71 * For ANSI mode, set this parameter to NULL."
73 ReadConsoleRequest
->NrCharactersRead
= pInputControl
->nInitialChars
;
74 RtlCopyMemory(ReadConsoleRequest
->Buffer
,
76 pInputControl
->nInitialChars
* sizeof(WCHAR
));
77 ReadConsoleRequest
->CtrlWakeupMask
= pInputControl
->dwCtrlWakeupMask
;
81 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
83 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsole
),
84 sizeof(*ReadConsoleRequest
));
86 /* Check for success */
87 if (NT_SUCCESS(ApiMessage
.Status
))
89 RtlCopyMemory(lpBuffer
,
90 ReadConsoleRequest
->Buffer
,
91 ReadConsoleRequest
->NrCharactersRead
* CharSize
);
93 if (lpNumberOfCharsRead
!= NULL
)
94 *lpNumberOfCharsRead
= ReadConsoleRequest
->NrCharactersRead
;
96 if (pInputControl
&& pInputControl
->nLength
== sizeof(CONSOLE_READCONSOLE_CONTROL
))
97 pInputControl
->dwControlKeyState
= ReadConsoleRequest
->ControlKeyState
;
101 DPRINT1("CSR returned error in ReadConsole\n");
103 if (lpNumberOfCharsRead
!= NULL
)
104 *lpNumberOfCharsRead
= 0;
107 BaseSetLastNTError(ApiMessage
.Status
);
110 CsrFreeCaptureBuffer(CaptureBuffer
);
112 /* Return TRUE or FALSE */
114 return (ReadConsoleRequest
->NrCharactersRead
> 0);
115 // return NT_SUCCESS(ApiMessage.Status);
121 IntGetConsoleInput(HANDLE hConsoleInput
,
122 PINPUT_RECORD lpBuffer
,
124 LPDWORD lpNumberOfEventsRead
,
128 CONSOLE_API_MESSAGE ApiMessage
;
129 PCONSOLE_GETINPUT GetInputRequest
= &ApiMessage
.Data
.GetInputRequest
;
130 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
132 if (lpBuffer
== NULL
)
134 SetLastError(ERROR_INVALID_ACCESS
);
138 if (!IsConsoleHandle(hConsoleInput
))
140 SetLastError(ERROR_INVALID_HANDLE
);
142 if (lpNumberOfEventsRead
!= NULL
)
143 *lpNumberOfEventsRead
= 0;
148 DPRINT("IntGetConsoleInput: %lx %p\n", nLength
, lpNumberOfEventsRead
);
150 /* Set up the data to send to the Console Server */
151 GetInputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
152 GetInputRequest
->InputHandle
= hConsoleInput
;
153 GetInputRequest
->NumRecords
= nLength
;
154 GetInputRequest
->Flags
= wFlags
;
155 GetInputRequest
->Unicode
= bUnicode
;
158 * For optimization purposes, Windows (and hence ReactOS, too, for
159 * compatibility reasons) uses a static buffer if no more than five
160 * input records are read. Otherwise a new buffer is allocated.
161 * This behaviour is also expected in the server-side.
163 if (nLength
<= sizeof(GetInputRequest
->RecordStaticBuffer
)/sizeof(INPUT_RECORD
))
165 GetInputRequest
->RecordBufPtr
= GetInputRequest
->RecordStaticBuffer
;
166 // CaptureBuffer = NULL;
170 ULONG Size
= nLength
* sizeof(INPUT_RECORD
);
172 /* Allocate a Capture Buffer */
173 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
174 if (CaptureBuffer
== NULL
)
176 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
177 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
181 /* Allocate space in the Buffer */
182 CsrAllocateMessagePointer(CaptureBuffer
,
184 (PVOID
*)&GetInputRequest
->RecordBufPtr
);
187 /* Call the server */
188 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
190 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetConsoleInput
),
191 sizeof(*GetInputRequest
));
193 /* Check for success */
194 if (NT_SUCCESS(ApiMessage
.Status
))
196 /* Return the number of events read */
197 DPRINT("Events read: %lx\n", GetInputRequest
->NumRecords
);
199 if (lpNumberOfEventsRead
!= NULL
)
200 *lpNumberOfEventsRead
= GetInputRequest
->NumRecords
;
202 /* Copy into the buffer */
203 RtlCopyMemory(lpBuffer
,
204 GetInputRequest
->RecordBufPtr
,
205 GetInputRequest
->NumRecords
* sizeof(INPUT_RECORD
));
209 if (lpNumberOfEventsRead
!= NULL
)
210 *lpNumberOfEventsRead
= 0;
213 BaseSetLastNTError(ApiMessage
.Status
);
216 /* Release the capture buffer if needed */
217 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
219 /* Return TRUE or FALSE */
220 return NT_SUCCESS(ApiMessage
.Status
);
226 IntReadConsoleOutput(HANDLE hConsoleOutput
,
230 PSMALL_RECT lpReadRegion
,
233 CONSOLE_API_MESSAGE ApiMessage
;
234 PCONSOLE_READOUTPUT ReadOutputRequest
= &ApiMessage
.Data
.ReadOutputRequest
;
235 PCSR_CAPTURE_BUFFER CaptureBuffer
;
236 DWORD Size
, SizeX
, SizeY
;
238 if (lpBuffer
== NULL
)
240 SetLastError(ERROR_INVALID_ACCESS
);
244 Size
= dwBufferSize
.X
* dwBufferSize
.Y
* sizeof(CHAR_INFO
);
246 DPRINT("IntReadConsoleOutput: %lx %p\n", Size
, lpReadRegion
);
248 /* Allocate a Capture Buffer */
249 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
250 if (CaptureBuffer
== NULL
)
252 DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size
);
253 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
257 /* Allocate space in the Buffer */
258 CsrAllocateMessagePointer(CaptureBuffer
,
260 (PVOID
*)&ReadOutputRequest
->CharInfo
);
262 /* Set up the data to send to the Console Server */
263 ReadOutputRequest
->OutputHandle
= hConsoleOutput
;
264 ReadOutputRequest
->Unicode
= bUnicode
;
265 ReadOutputRequest
->BufferSize
= dwBufferSize
;
266 ReadOutputRequest
->BufferCoord
= dwBufferCoord
;
267 ReadOutputRequest
->ReadRegion
= *lpReadRegion
;
269 /* Call the server */
270 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
272 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsoleOutput
),
273 sizeof(*ReadOutputRequest
));
275 /* Check for success */
276 if (NT_SUCCESS(ApiMessage
.Status
))
278 /* Copy into the buffer */
279 DPRINT("Copying to buffer\n");
280 SizeX
= ReadOutputRequest
->ReadRegion
.Right
-
281 ReadOutputRequest
->ReadRegion
.Left
+ 1;
282 SizeY
= ReadOutputRequest
->ReadRegion
.Bottom
-
283 ReadOutputRequest
->ReadRegion
.Top
+ 1;
284 RtlCopyMemory(lpBuffer
,
285 ReadOutputRequest
->CharInfo
,
286 sizeof(CHAR_INFO
) * SizeX
* SizeY
);
291 BaseSetLastNTError(ApiMessage
.Status
);
294 /* Return the read region */
295 DPRINT("read region: %p\n", ReadOutputRequest
->ReadRegion
);
296 *lpReadRegion
= ReadOutputRequest
->ReadRegion
;
298 /* Release the capture buffer */
299 CsrFreeCaptureBuffer(CaptureBuffer
);
301 /* Return TRUE or FALSE */
302 return NT_SUCCESS(ApiMessage
.Status
);
308 IntReadConsoleOutputCode(HANDLE hConsoleOutput
,
313 LPDWORD lpNumberOfCodesRead
)
315 CONSOLE_API_MESSAGE ApiMessage
;
316 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest
= &ApiMessage
.Data
.ReadOutputCodeRequest
;
317 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
318 ULONG SizeBytes
, CodeSize
;
320 DPRINT("IntReadConsoleOutputCode\n");
322 /* Set up the data to send to the Console Server */
323 ReadOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
324 ReadOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
325 ReadOutputCodeRequest
->Coord
= dwReadCoord
;
326 ReadOutputCodeRequest
->NumCodes
= nLength
;
328 /* Determine the needed size */
329 ReadOutputCodeRequest
->CodeType
= CodeType
;
333 CodeSize
= sizeof(CHAR
);
337 CodeSize
= sizeof(WCHAR
);
341 CodeSize
= sizeof(WORD
);
345 SetLastError(ERROR_INVALID_PARAMETER
);
348 SizeBytes
= nLength
* CodeSize
;
351 * For optimization purposes, Windows (and hence ReactOS, too, for
352 * compatibility reasons) uses a static buffer if no more than eighty
353 * bytes are read. Otherwise a new buffer is allocated.
354 * This behaviour is also expected in the server-side.
356 if (SizeBytes
<= sizeof(ReadOutputCodeRequest
->CodeStaticBuffer
))
358 ReadOutputCodeRequest
->pCode
.pCode
= ReadOutputCodeRequest
->CodeStaticBuffer
;
359 // CaptureBuffer = NULL;
363 /* Allocate a Capture Buffer */
364 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
365 if (CaptureBuffer
== NULL
)
367 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
368 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
372 /* Allocate space in the Buffer */
373 CsrAllocateMessagePointer(CaptureBuffer
,
375 (PVOID
*)&ReadOutputCodeRequest
->pCode
.pCode
);
378 /* Call the server */
379 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
381 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsoleOutputString
),
382 sizeof(*ReadOutputCodeRequest
));
384 /* Check for success */
385 if (NT_SUCCESS(ApiMessage
.Status
))
387 DWORD NumCodes
= ReadOutputCodeRequest
->NumCodes
;
389 ReadOutputCodeRequest
->pCode
.pCode
,
390 NumCodes
* CodeSize
);
392 if (lpNumberOfCodesRead
!= NULL
)
393 *lpNumberOfCodesRead
= NumCodes
;
397 if (lpNumberOfCodesRead
!= NULL
)
398 *lpNumberOfCodesRead
= 0;
401 BaseSetLastNTError(ApiMessage
.Status
);
404 /* Release the capture buffer if needed */
405 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
407 /* Return TRUE or FALSE */
408 return NT_SUCCESS(ApiMessage
.Status
);
418 IntWriteConsole(HANDLE hConsoleOutput
,
420 DWORD nNumberOfCharsToWrite
,
421 LPDWORD lpNumberOfCharsWritten
,
426 CONSOLE_API_MESSAGE ApiMessage
;
427 PCONSOLE_WRITECONSOLE WriteConsoleRequest
= &ApiMessage
.Data
.WriteConsoleRequest
;
428 PCSR_CAPTURE_BUFFER CaptureBuffer
;
431 /* Determine the needed size */
432 CharSize
= (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
433 WriteConsoleRequest
->BufferSize
= nNumberOfCharsToWrite
* CharSize
;
435 /* Allocate a Capture Buffer */
436 CaptureBuffer
= CsrAllocateCaptureBuffer(1, WriteConsoleRequest
->BufferSize
);
437 if (CaptureBuffer
== NULL
)
439 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
440 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
444 /* Capture the buffer to write */
445 CsrCaptureMessageBuffer(CaptureBuffer
,
447 WriteConsoleRequest
->BufferSize
,
448 (PVOID
*)&WriteConsoleRequest
->Buffer
);
451 WriteConsoleRequest
->NrCharactersToWrite
= nNumberOfCharsToWrite
;
452 WriteConsoleRequest
->OutputHandle
= hConsoleOutput
;
453 WriteConsoleRequest
->Unicode
= bUnicode
;
455 /* Call the server */
456 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
458 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsole
),
459 sizeof(*WriteConsoleRequest
));
461 /* Check for success */
462 if (NT_SUCCESS(ApiMessage
.Status
))
464 if (lpNumberOfCharsWritten
!= NULL
)
465 *lpNumberOfCharsWritten
= WriteConsoleRequest
->NrCharactersWritten
;
471 if (lpNumberOfCharsWritten
!= NULL
)
472 *lpNumberOfCharsWritten
= 0;
475 BaseSetLastNTError(ApiMessage
.Status
);
479 CsrFreeCaptureBuffer(CaptureBuffer
);
487 IntWriteConsoleInput(HANDLE hConsoleInput
,
488 PINPUT_RECORD lpBuffer
,
490 LPDWORD lpNumberOfEventsWritten
,
492 BOOLEAN bAppendToEnd
)
494 CONSOLE_API_MESSAGE ApiMessage
;
495 PCONSOLE_WRITEINPUT WriteInputRequest
= &ApiMessage
.Data
.WriteInputRequest
;
496 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
498 if (lpBuffer
== NULL
)
500 SetLastError(ERROR_INVALID_ACCESS
);
504 DPRINT("IntWriteConsoleInput: %lx %p\n", nLength
, lpNumberOfEventsWritten
);
506 /* Set up the data to send to the Console Server */
507 WriteInputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
508 WriteInputRequest
->InputHandle
= hConsoleInput
;
509 WriteInputRequest
->NumRecords
= nLength
;
510 WriteInputRequest
->Unicode
= bUnicode
;
511 WriteInputRequest
->AppendToEnd
= bAppendToEnd
;
514 * For optimization purposes, Windows (and hence ReactOS, too, for
515 * compatibility reasons) uses a static buffer if no more than five
516 * input records are written. Otherwise a new buffer is allocated.
517 * This behaviour is also expected in the server-side.
519 if (nLength
<= sizeof(WriteInputRequest
->RecordStaticBuffer
)/sizeof(INPUT_RECORD
))
521 WriteInputRequest
->RecordBufPtr
= WriteInputRequest
->RecordStaticBuffer
;
522 // CaptureBuffer = NULL;
524 RtlCopyMemory(WriteInputRequest
->RecordBufPtr
,
526 nLength
* sizeof(INPUT_RECORD
));
530 ULONG Size
= nLength
* sizeof(INPUT_RECORD
);
532 /* Allocate a Capture Buffer */
533 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
534 if (CaptureBuffer
== NULL
)
536 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
537 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
541 /* Capture the user buffer */
542 CsrCaptureMessageBuffer(CaptureBuffer
,
545 (PVOID
*)&WriteInputRequest
->RecordBufPtr
);
548 /* Call the server */
549 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
551 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleInput
),
552 sizeof(*WriteInputRequest
));
554 /* Release the capture buffer if needed */
555 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
557 /* Check for success */
558 if (NT_SUCCESS(ApiMessage
.Status
))
560 /* Return the number of events written */
561 DPRINT("Events written: %lx\n", WriteInputRequest
->NumRecords
);
563 if (lpNumberOfEventsWritten
!= NULL
)
564 *lpNumberOfEventsWritten
= WriteInputRequest
->NumRecords
;
568 if (lpNumberOfEventsWritten
!= NULL
)
569 *lpNumberOfEventsWritten
= 0;
572 BaseSetLastNTError(ApiMessage
.Status
);
575 /* Return TRUE or FALSE */
576 return NT_SUCCESS(ApiMessage
.Status
);
582 IntWriteConsoleOutput(HANDLE hConsoleOutput
,
583 CONST CHAR_INFO
*lpBuffer
,
586 PSMALL_RECT lpWriteRegion
,
589 CONSOLE_API_MESSAGE ApiMessage
;
590 PCONSOLE_WRITEOUTPUT WriteOutputRequest
= &ApiMessage
.Data
.WriteOutputRequest
;
591 PCSR_CAPTURE_BUFFER CaptureBuffer
;
594 if ((lpBuffer
== NULL
) || (lpWriteRegion
== NULL
))
596 SetLastError(ERROR_INVALID_ACCESS
);
600 if (lpWriteRegion == NULL)
602 SetLastError(ERROR_INVALID_PARAMETER);
607 Size
= dwBufferSize
.Y
* dwBufferSize
.X
* sizeof(CHAR_INFO
);
609 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size
, lpWriteRegion
);
611 /* Allocate a Capture Buffer */
612 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
613 if (CaptureBuffer
== NULL
)
615 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
616 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
620 /* Capture the user buffer */
621 CsrCaptureMessageBuffer(CaptureBuffer
,
624 (PVOID
*)&WriteOutputRequest
->CharInfo
);
626 /* Set up the data to send to the Console Server */
627 WriteOutputRequest
->OutputHandle
= hConsoleOutput
;
628 WriteOutputRequest
->Unicode
= bUnicode
;
629 WriteOutputRequest
->BufferSize
= dwBufferSize
;
630 WriteOutputRequest
->BufferCoord
= dwBufferCoord
;
631 WriteOutputRequest
->WriteRegion
= *lpWriteRegion
;
633 /* Call the server */
634 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
636 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutput
),
637 sizeof(*WriteOutputRequest
));
639 /* Check for success */
640 if (!NT_SUCCESS(ApiMessage
.Status
))
643 BaseSetLastNTError(ApiMessage
.Status
);
646 /* Return the read region */
647 DPRINT("read region: %p\n", WriteOutputRequest
->WriteRegion
);
648 *lpWriteRegion
= WriteOutputRequest
->WriteRegion
;
650 /* Release the capture buffer */
651 CsrFreeCaptureBuffer(CaptureBuffer
);
653 /* Return TRUE or FALSE */
654 return NT_SUCCESS(ApiMessage
.Status
);
660 IntWriteConsoleOutputCode(HANDLE hConsoleOutput
,
665 LPDWORD lpNumberOfCodesWritten
)
667 CONSOLE_API_MESSAGE ApiMessage
;
668 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest
= &ApiMessage
.Data
.WriteOutputCodeRequest
;
669 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
670 ULONG SizeBytes
, CodeSize
;
674 SetLastError(ERROR_INVALID_ACCESS
);
678 DPRINT("IntWriteConsoleOutputCode\n");
680 /* Set up the data to send to the Console Server */
681 WriteOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
682 WriteOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
683 WriteOutputCodeRequest
->Coord
= dwWriteCoord
;
684 WriteOutputCodeRequest
->NumCodes
= nLength
;
686 /* Determine the needed size */
687 WriteOutputCodeRequest
->CodeType
= CodeType
;
691 CodeSize
= sizeof(CHAR
);
695 CodeSize
= sizeof(WCHAR
);
699 CodeSize
= sizeof(WORD
);
703 SetLastError(ERROR_INVALID_PARAMETER
);
706 SizeBytes
= nLength
* CodeSize
;
709 * For optimization purposes, Windows (and hence ReactOS, too, for
710 * compatibility reasons) uses a static buffer if no more than eighty
711 * bytes are written. Otherwise a new buffer is allocated.
712 * This behaviour is also expected in the server-side.
714 if (SizeBytes
<= sizeof(WriteOutputCodeRequest
->CodeStaticBuffer
))
716 WriteOutputCodeRequest
->pCode
.pCode
= WriteOutputCodeRequest
->CodeStaticBuffer
;
717 // CaptureBuffer = NULL;
719 RtlCopyMemory(WriteOutputCodeRequest
->pCode
.pCode
,
725 /* Allocate a Capture Buffer */
726 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
727 if (CaptureBuffer
== NULL
)
729 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
730 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
734 /* Capture the buffer to write */
735 CsrCaptureMessageBuffer(CaptureBuffer
,
738 (PVOID
*)&WriteOutputCodeRequest
->pCode
.pCode
);
741 /* Call the server */
742 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
744 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutputString
),
745 sizeof(*WriteOutputCodeRequest
));
747 /* Release the capture buffer if needed */
748 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
750 /* Check for success */
751 if (NT_SUCCESS(ApiMessage
.Status
))
753 if (lpNumberOfCodesWritten
!= NULL
)
754 *lpNumberOfCodesWritten
= WriteOutputCodeRequest
->NumCodes
;
758 if (lpNumberOfCodesWritten
!= NULL
)
759 *lpNumberOfCodesWritten
= 0;
762 BaseSetLastNTError(ApiMessage
.Status
);
765 /* Return TRUE or FALSE */
766 return NT_SUCCESS(ApiMessage
.Status
);
772 IntFillConsoleOutputCode(HANDLE hConsoleOutput
,
777 LPDWORD lpNumberOfCodesWritten
)
779 CONSOLE_API_MESSAGE ApiMessage
;
780 PCONSOLE_FILLOUTPUTCODE FillOutputRequest
= &ApiMessage
.Data
.FillOutputRequest
;
782 if ( (CodeType
!= CODE_ASCII
) &&
783 (CodeType
!= CODE_UNICODE
) &&
784 (CodeType
!= CODE_ATTRIBUTE
) )
786 SetLastError(ERROR_INVALID_PARAMETER
);
790 /* Set up the data to send to the Console Server */
791 FillOutputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
792 FillOutputRequest
->OutputHandle
= hConsoleOutput
;
793 FillOutputRequest
->WriteCoord
= dwWriteCoord
;
794 FillOutputRequest
->CodeType
= CodeType
;
795 FillOutputRequest
->Code
= Code
;
796 FillOutputRequest
->NumCodes
= nLength
;
798 /* Call the server */
799 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
801 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFillConsoleOutput
),
802 sizeof(*FillOutputRequest
));
804 /* Check for success */
805 if (NT_SUCCESS(ApiMessage
.Status
))
807 if (lpNumberOfCodesWritten
!= NULL
)
808 *lpNumberOfCodesWritten
= FillOutputRequest
->NumCodes
;
812 if (lpNumberOfCodesWritten
!= NULL
)
813 *lpNumberOfCodesWritten
= 0;
815 BaseSetLastNTError(ApiMessage
.Status
);
818 /* Return TRUE or FALSE */
819 return NT_SUCCESS(ApiMessage
.Status
);
823 /* FUNCTIONS ******************************************************************/
829 /*--------------------------------------------------------------
836 ReadConsoleW(HANDLE hConsoleInput
,
838 DWORD nNumberOfCharsToRead
,
839 LPDWORD lpNumberOfCharsRead
,
840 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
842 return IntReadConsole(hConsoleInput
,
844 nNumberOfCharsToRead
,
851 /*--------------------------------------------------------------
858 ReadConsoleA(HANDLE hConsoleInput
,
860 DWORD nNumberOfCharsToRead
,
861 LPDWORD lpNumberOfCharsRead
,
862 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
864 return IntReadConsole(hConsoleInput
,
866 nNumberOfCharsToRead
,
873 /*--------------------------------------------------------------
880 PeekConsoleInputW(HANDLE hConsoleInput
,
881 PINPUT_RECORD lpBuffer
,
883 LPDWORD lpNumberOfEventsRead
)
885 return IntGetConsoleInput(hConsoleInput
,
888 lpNumberOfEventsRead
,
889 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
894 /*--------------------------------------------------------------
901 PeekConsoleInputA(HANDLE hConsoleInput
,
902 PINPUT_RECORD lpBuffer
,
904 LPDWORD lpNumberOfEventsRead
)
906 return IntGetConsoleInput(hConsoleInput
,
909 lpNumberOfEventsRead
,
910 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
915 /*--------------------------------------------------------------
922 ReadConsoleInputW(HANDLE hConsoleInput
,
923 PINPUT_RECORD lpBuffer
,
925 LPDWORD lpNumberOfEventsRead
)
927 return IntGetConsoleInput(hConsoleInput
,
930 lpNumberOfEventsRead
,
936 /*--------------------------------------------------------------
943 ReadConsoleInputA(HANDLE hConsoleInput
,
944 PINPUT_RECORD lpBuffer
,
946 LPDWORD lpNumberOfEventsRead
)
948 return IntGetConsoleInput(hConsoleInput
,
951 lpNumberOfEventsRead
,
957 /*--------------------------------------------------------------
958 * ReadConsoleInputExW
964 ReadConsoleInputExW(HANDLE hConsoleInput
,
965 PINPUT_RECORD lpBuffer
,
967 LPDWORD lpNumberOfEventsRead
,
970 return IntGetConsoleInput(hConsoleInput
,
973 lpNumberOfEventsRead
,
979 /*--------------------------------------------------------------
980 * ReadConsoleInputExA
986 ReadConsoleInputExA(HANDLE hConsoleInput
,
987 PINPUT_RECORD lpBuffer
,
989 LPDWORD lpNumberOfEventsRead
,
992 return IntGetConsoleInput(hConsoleInput
,
995 lpNumberOfEventsRead
,
1001 /*--------------------------------------------------------------
1002 * ReadConsoleOutputW
1008 ReadConsoleOutputW(HANDLE hConsoleOutput
,
1009 PCHAR_INFO lpBuffer
,
1011 COORD dwBufferCoord
,
1012 PSMALL_RECT lpReadRegion
)
1014 return IntReadConsoleOutput(hConsoleOutput
,
1023 /*--------------------------------------------------------------
1024 * ReadConsoleOutputA
1030 ReadConsoleOutputA(HANDLE hConsoleOutput
,
1031 PCHAR_INFO lpBuffer
,
1033 COORD dwBufferCoord
,
1034 PSMALL_RECT lpReadRegion
)
1036 return IntReadConsoleOutput(hConsoleOutput
,
1045 /*--------------------------------------------------------------
1046 * ReadConsoleOutputCharacterW
1052 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1056 LPDWORD lpNumberOfCharsRead
)
1058 return IntReadConsoleOutputCode(hConsoleOutput
,
1063 lpNumberOfCharsRead
);
1067 /*--------------------------------------------------------------
1068 * ReadConsoleOutputCharacterA
1074 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1078 LPDWORD lpNumberOfCharsRead
)
1080 return IntReadConsoleOutputCode(hConsoleOutput
,
1085 lpNumberOfCharsRead
);
1089 /*--------------------------------------------------------------
1090 * ReadConsoleOutputAttribute
1096 ReadConsoleOutputAttribute(HANDLE hConsoleOutput
,
1100 LPDWORD lpNumberOfAttrsRead
)
1102 return IntReadConsoleOutputCode(hConsoleOutput
,
1107 lpNumberOfAttrsRead
);
1111 /*******************
1113 *******************/
1115 /*--------------------------------------------------------------
1122 WriteConsoleW(HANDLE hConsoleOutput
,
1123 CONST VOID
*lpBuffer
,
1124 DWORD nNumberOfCharsToWrite
,
1125 LPDWORD lpNumberOfCharsWritten
,
1128 return IntWriteConsole(hConsoleOutput
,
1130 nNumberOfCharsToWrite
,
1131 lpNumberOfCharsWritten
,
1137 /*--------------------------------------------------------------
1144 WriteConsoleA(HANDLE hConsoleOutput
,
1145 CONST VOID
*lpBuffer
,
1146 DWORD nNumberOfCharsToWrite
,
1147 LPDWORD lpNumberOfCharsWritten
,
1150 return IntWriteConsole(hConsoleOutput
,
1152 nNumberOfCharsToWrite
,
1153 lpNumberOfCharsWritten
,
1159 /*--------------------------------------------------------------
1160 * WriteConsoleInputW
1166 WriteConsoleInputW(HANDLE hConsoleInput
,
1167 CONST INPUT_RECORD
*lpBuffer
,
1169 LPDWORD lpNumberOfEventsWritten
)
1171 return IntWriteConsoleInput(hConsoleInput
,
1172 (PINPUT_RECORD
)lpBuffer
,
1174 lpNumberOfEventsWritten
,
1180 /*--------------------------------------------------------------
1181 * WriteConsoleInputA
1187 WriteConsoleInputA(HANDLE hConsoleInput
,
1188 CONST INPUT_RECORD
*lpBuffer
,
1190 LPDWORD lpNumberOfEventsWritten
)
1192 return IntWriteConsoleInput(hConsoleInput
,
1193 (PINPUT_RECORD
)lpBuffer
,
1195 lpNumberOfEventsWritten
,
1201 /*--------------------------------------------------------------
1202 * WriteConsoleInputVDMW
1208 WriteConsoleInputVDMW(HANDLE hConsoleInput
,
1209 CONST INPUT_RECORD
*lpBuffer
,
1211 LPDWORD lpNumberOfEventsWritten
)
1213 return IntWriteConsoleInput(hConsoleInput
,
1214 (PINPUT_RECORD
)lpBuffer
,
1216 lpNumberOfEventsWritten
,
1222 /*--------------------------------------------------------------
1223 * WriteConsoleInputVDMA
1229 WriteConsoleInputVDMA(HANDLE hConsoleInput
,
1230 CONST INPUT_RECORD
*lpBuffer
,
1232 LPDWORD lpNumberOfEventsWritten
)
1234 return IntWriteConsoleInput(hConsoleInput
,
1235 (PINPUT_RECORD
)lpBuffer
,
1237 lpNumberOfEventsWritten
,
1243 /*--------------------------------------------------------------
1244 * WriteConsoleOutputW
1250 WriteConsoleOutputW(HANDLE hConsoleOutput
,
1251 CONST CHAR_INFO
*lpBuffer
,
1253 COORD dwBufferCoord
,
1254 PSMALL_RECT lpWriteRegion
)
1256 return IntWriteConsoleOutput(hConsoleOutput
,
1265 /*--------------------------------------------------------------
1266 * WriteConsoleOutputA
1272 WriteConsoleOutputA(HANDLE hConsoleOutput
,
1273 CONST CHAR_INFO
*lpBuffer
,
1275 COORD dwBufferCoord
,
1276 PSMALL_RECT lpWriteRegion
)
1278 return IntWriteConsoleOutput(hConsoleOutput
,
1287 /*--------------------------------------------------------------
1288 * WriteConsoleOutputCharacterW
1294 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1295 LPCWSTR lpCharacter
,
1298 LPDWORD lpNumberOfCharsWritten
)
1300 return IntWriteConsoleOutputCode(hConsoleOutput
,
1305 lpNumberOfCharsWritten
);
1309 /*--------------------------------------------------------------
1310 * WriteConsoleOutputCharacterA
1316 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1320 LPDWORD lpNumberOfCharsWritten
)
1322 return IntWriteConsoleOutputCode(hConsoleOutput
,
1327 lpNumberOfCharsWritten
);
1331 /*--------------------------------------------------------------
1332 * WriteConsoleOutputAttribute
1338 WriteConsoleOutputAttribute(HANDLE hConsoleOutput
,
1339 CONST WORD
*lpAttribute
,
1342 LPDWORD lpNumberOfAttrsWritten
)
1344 return IntWriteConsoleOutputCode(hConsoleOutput
,
1349 lpNumberOfAttrsWritten
);
1353 /*--------------------------------------------------------------
1354 * FillConsoleOutputCharacterW
1360 FillConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1364 LPDWORD lpNumberOfCharsWritten
)
1367 Code
.UnicodeChar
= cCharacter
;
1368 return IntFillConsoleOutputCode(hConsoleOutput
,
1373 lpNumberOfCharsWritten
);
1377 /*--------------------------------------------------------------
1378 * FillConsoleOutputCharacterA
1384 FillConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1388 LPDWORD lpNumberOfCharsWritten
)
1391 Code
.AsciiChar
= cCharacter
;
1392 return IntFillConsoleOutputCode(hConsoleOutput
,
1397 lpNumberOfCharsWritten
);
1401 /*--------------------------------------------------------------
1402 * FillConsoleOutputAttribute
1408 FillConsoleOutputAttribute(HANDLE hConsoleOutput
,
1412 LPDWORD lpNumberOfAttrsWritten
)
1415 Code
.Attribute
= wAttribute
;
1416 return IntFillConsoleOutputCode(hConsoleOutput
,
1421 lpNumberOfAttrsWritten
);