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 if ( (CodeType
!= CODE_ASCII
) &&
323 (CodeType
!= CODE_UNICODE
) &&
324 (CodeType
!= CODE_ATTRIBUTE
) )
326 SetLastError(ERROR_INVALID_PARAMETER
);
330 /* Set up the data to send to the Console Server */
331 ReadOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
332 ReadOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
333 ReadOutputCodeRequest
->Coord
= dwReadCoord
;
334 ReadOutputCodeRequest
->NumCodes
= nLength
;
336 /* Determine the needed size */
337 ReadOutputCodeRequest
->CodeType
= CodeType
;
341 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, AsciiChar
);
345 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, UnicodeChar
);
349 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, Attribute
);
352 SizeBytes
= nLength
* CodeSize
;
355 * For optimization purposes, Windows (and hence ReactOS, too, for
356 * compatibility reasons) uses a static buffer if no more than eighty
357 * bytes are read. Otherwise a new buffer is allocated.
358 * This behaviour is also expected in the server-side.
360 if (SizeBytes
<= sizeof(ReadOutputCodeRequest
->CodeStaticBuffer
))
362 ReadOutputCodeRequest
->pCode
= ReadOutputCodeRequest
->CodeStaticBuffer
;
363 // CaptureBuffer = NULL;
367 /* Allocate a Capture Buffer */
368 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
369 if (CaptureBuffer
== NULL
)
371 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
372 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
376 /* Allocate space in the Buffer */
377 CsrAllocateMessagePointer(CaptureBuffer
,
379 (PVOID
*)&ReadOutputCodeRequest
->pCode
);
382 /* Call the server */
383 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
385 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsoleOutputString
),
386 sizeof(*ReadOutputCodeRequest
));
388 /* Check for success */
389 if (NT_SUCCESS(ApiMessage
.Status
))
391 DWORD NumCodes
= ReadOutputCodeRequest
->NumCodes
;
393 ReadOutputCodeRequest
->pCode
,
394 NumCodes
* CodeSize
);
396 if (lpNumberOfCodesRead
!= NULL
)
397 *lpNumberOfCodesRead
= NumCodes
;
401 if (lpNumberOfCodesRead
!= NULL
)
402 *lpNumberOfCodesRead
= 0;
405 BaseSetLastNTError(ApiMessage
.Status
);
408 /* Release the capture buffer if needed */
409 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
411 /* Return TRUE or FALSE */
412 return NT_SUCCESS(ApiMessage
.Status
);
422 IntWriteConsole(HANDLE hConsoleOutput
,
424 DWORD nNumberOfCharsToWrite
,
425 LPDWORD lpNumberOfCharsWritten
,
430 CONSOLE_API_MESSAGE ApiMessage
;
431 PCONSOLE_WRITECONSOLE WriteConsoleRequest
= &ApiMessage
.Data
.WriteConsoleRequest
;
432 PCSR_CAPTURE_BUFFER CaptureBuffer
;
435 /* Determine the needed size */
436 CharSize
= (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
437 WriteConsoleRequest
->BufferSize
= nNumberOfCharsToWrite
* CharSize
;
439 /* Allocate a Capture Buffer */
440 CaptureBuffer
= CsrAllocateCaptureBuffer(1, WriteConsoleRequest
->BufferSize
);
441 if (CaptureBuffer
== NULL
)
443 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
444 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
448 /* Capture the buffer to write */
449 CsrCaptureMessageBuffer(CaptureBuffer
,
451 WriteConsoleRequest
->BufferSize
,
452 (PVOID
*)&WriteConsoleRequest
->Buffer
);
455 WriteConsoleRequest
->NrCharactersToWrite
= nNumberOfCharsToWrite
;
456 WriteConsoleRequest
->OutputHandle
= hConsoleOutput
;
457 WriteConsoleRequest
->Unicode
= bUnicode
;
459 /* Call the server */
460 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
462 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsole
),
463 sizeof(*WriteConsoleRequest
));
465 /* Check for success */
466 if (NT_SUCCESS(ApiMessage
.Status
))
468 if (lpNumberOfCharsWritten
!= NULL
)
469 *lpNumberOfCharsWritten
= WriteConsoleRequest
->NrCharactersWritten
;
475 if (lpNumberOfCharsWritten
!= NULL
)
476 *lpNumberOfCharsWritten
= 0;
479 BaseSetLastNTError(ApiMessage
.Status
);
483 CsrFreeCaptureBuffer(CaptureBuffer
);
491 IntWriteConsoleInput(HANDLE hConsoleInput
,
492 PINPUT_RECORD lpBuffer
,
494 LPDWORD lpNumberOfEventsWritten
,
496 BOOLEAN bAppendToEnd
)
498 CONSOLE_API_MESSAGE ApiMessage
;
499 PCONSOLE_WRITEINPUT WriteInputRequest
= &ApiMessage
.Data
.WriteInputRequest
;
500 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
502 if (lpBuffer
== NULL
)
504 SetLastError(ERROR_INVALID_ACCESS
);
508 DPRINT("IntWriteConsoleInput: %lx %p\n", nLength
, lpNumberOfEventsWritten
);
510 /* Set up the data to send to the Console Server */
511 WriteInputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
512 WriteInputRequest
->InputHandle
= hConsoleInput
;
513 WriteInputRequest
->NumRecords
= nLength
;
514 WriteInputRequest
->Unicode
= bUnicode
;
515 WriteInputRequest
->AppendToEnd
= bAppendToEnd
;
518 * For optimization purposes, Windows (and hence ReactOS, too, for
519 * compatibility reasons) uses a static buffer if no more than five
520 * input records are written. Otherwise a new buffer is allocated.
521 * This behaviour is also expected in the server-side.
523 if (nLength
<= sizeof(WriteInputRequest
->RecordStaticBuffer
)/sizeof(INPUT_RECORD
))
525 WriteInputRequest
->RecordBufPtr
= WriteInputRequest
->RecordStaticBuffer
;
526 // CaptureBuffer = NULL;
528 RtlCopyMemory(WriteInputRequest
->RecordBufPtr
,
530 nLength
* sizeof(INPUT_RECORD
));
534 ULONG Size
= nLength
* sizeof(INPUT_RECORD
);
536 /* Allocate a Capture Buffer */
537 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
538 if (CaptureBuffer
== NULL
)
540 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
541 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
545 /* Capture the user buffer */
546 CsrCaptureMessageBuffer(CaptureBuffer
,
549 (PVOID
*)&WriteInputRequest
->RecordBufPtr
);
552 /* Call the server */
553 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
555 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleInput
),
556 sizeof(*WriteInputRequest
));
558 /* Release the capture buffer if needed */
559 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
561 /* Check for success */
562 if (NT_SUCCESS(ApiMessage
.Status
))
564 /* Return the number of events written */
565 DPRINT("Events written: %lx\n", WriteInputRequest
->NumRecords
);
567 if (lpNumberOfEventsWritten
!= NULL
)
568 *lpNumberOfEventsWritten
= WriteInputRequest
->NumRecords
;
572 if (lpNumberOfEventsWritten
!= NULL
)
573 *lpNumberOfEventsWritten
= 0;
576 BaseSetLastNTError(ApiMessage
.Status
);
579 /* Return TRUE or FALSE */
580 return NT_SUCCESS(ApiMessage
.Status
);
586 IntWriteConsoleOutput(HANDLE hConsoleOutput
,
587 CONST CHAR_INFO
*lpBuffer
,
590 PSMALL_RECT lpWriteRegion
,
593 CONSOLE_API_MESSAGE ApiMessage
;
594 PCONSOLE_WRITEOUTPUT WriteOutputRequest
= &ApiMessage
.Data
.WriteOutputRequest
;
595 PCSR_CAPTURE_BUFFER CaptureBuffer
;
598 if ((lpBuffer
== NULL
) || (lpWriteRegion
== NULL
))
600 SetLastError(ERROR_INVALID_ACCESS
);
604 if (lpWriteRegion == NULL)
606 SetLastError(ERROR_INVALID_PARAMETER);
611 Size
= dwBufferSize
.Y
* dwBufferSize
.X
* sizeof(CHAR_INFO
);
613 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size
, lpWriteRegion
);
615 /* Allocate a Capture Buffer */
616 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
617 if (CaptureBuffer
== NULL
)
619 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
620 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
624 /* Capture the user buffer */
625 CsrCaptureMessageBuffer(CaptureBuffer
,
628 (PVOID
*)&WriteOutputRequest
->CharInfo
);
630 /* Set up the data to send to the Console Server */
631 WriteOutputRequest
->OutputHandle
= hConsoleOutput
;
632 WriteOutputRequest
->Unicode
= bUnicode
;
633 WriteOutputRequest
->BufferSize
= dwBufferSize
;
634 WriteOutputRequest
->BufferCoord
= dwBufferCoord
;
635 WriteOutputRequest
->WriteRegion
= *lpWriteRegion
;
637 /* Call the server */
638 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
640 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutput
),
641 sizeof(*WriteOutputRequest
));
643 /* Check for success */
644 if (!NT_SUCCESS(ApiMessage
.Status
))
647 BaseSetLastNTError(ApiMessage
.Status
);
650 /* Return the read region */
651 DPRINT("read region: %p\n", WriteOutputRequest
->WriteRegion
);
652 *lpWriteRegion
= WriteOutputRequest
->WriteRegion
;
654 /* Release the capture buffer */
655 CsrFreeCaptureBuffer(CaptureBuffer
);
657 /* Return TRUE or FALSE */
658 return NT_SUCCESS(ApiMessage
.Status
);
664 IntWriteConsoleOutputCode(HANDLE hConsoleOutput
,
669 LPDWORD lpNumberOfCodesWritten
)
671 CONSOLE_API_MESSAGE ApiMessage
;
672 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest
= &ApiMessage
.Data
.WriteOutputCodeRequest
;
673 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
674 ULONG SizeBytes
, CodeSize
;
678 SetLastError(ERROR_INVALID_ACCESS
);
682 if ( (CodeType
!= CODE_ASCII
) &&
683 (CodeType
!= CODE_UNICODE
) &&
684 (CodeType
!= CODE_ATTRIBUTE
) )
686 SetLastError(ERROR_INVALID_PARAMETER
);
690 DPRINT("IntWriteConsoleOutputCode\n");
692 /* Set up the data to send to the Console Server */
693 WriteOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
694 WriteOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
695 WriteOutputCodeRequest
->Coord
= dwWriteCoord
;
696 WriteOutputCodeRequest
->NumCodes
= nLength
;
698 /* Determine the needed size */
699 WriteOutputCodeRequest
->CodeType
= CodeType
;
703 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, AsciiChar
);
707 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, UnicodeChar
);
711 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, Attribute
);
714 SizeBytes
= nLength
* CodeSize
;
717 * For optimization purposes, Windows (and hence ReactOS, too, for
718 * compatibility reasons) uses a static buffer if no more than eighty
719 * bytes are written. Otherwise a new buffer is allocated.
720 * This behaviour is also expected in the server-side.
722 if (SizeBytes
<= sizeof(WriteOutputCodeRequest
->CodeStaticBuffer
))
724 WriteOutputCodeRequest
->pCode
= WriteOutputCodeRequest
->CodeStaticBuffer
;
725 // CaptureBuffer = NULL;
727 RtlCopyMemory(WriteOutputCodeRequest
->pCode
,
733 /* Allocate a Capture Buffer */
734 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
735 if (CaptureBuffer
== NULL
)
737 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
738 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
742 /* Capture the buffer to write */
743 CsrCaptureMessageBuffer(CaptureBuffer
,
746 (PVOID
*)&WriteOutputCodeRequest
->pCode
);
749 /* Call the server */
750 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
752 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutputString
),
753 sizeof(*WriteOutputCodeRequest
));
755 /* Release the capture buffer if needed */
756 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
758 /* Check for success */
759 if (NT_SUCCESS(ApiMessage
.Status
))
761 if (lpNumberOfCodesWritten
!= NULL
)
762 *lpNumberOfCodesWritten
= WriteOutputCodeRequest
->NumCodes
;
766 if (lpNumberOfCodesWritten
!= NULL
)
767 *lpNumberOfCodesWritten
= 0;
770 BaseSetLastNTError(ApiMessage
.Status
);
773 /* Return TRUE or FALSE */
774 return NT_SUCCESS(ApiMessage
.Status
);
780 IntFillConsoleOutputCode(HANDLE hConsoleOutput
,
785 LPDWORD lpNumberOfCodesWritten
)
787 CONSOLE_API_MESSAGE ApiMessage
;
788 PCONSOLE_FILLOUTPUTCODE FillOutputRequest
= &ApiMessage
.Data
.FillOutputRequest
;
790 DPRINT("IntFillConsoleOutputCode\n");
792 if ( (CodeType
!= CODE_ASCII
) &&
793 (CodeType
!= CODE_UNICODE
) &&
794 (CodeType
!= CODE_ATTRIBUTE
) )
796 SetLastError(ERROR_INVALID_PARAMETER
);
800 /* Set up the data to send to the Console Server */
801 FillOutputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
802 FillOutputRequest
->OutputHandle
= hConsoleOutput
;
803 FillOutputRequest
->WriteCoord
= dwWriteCoord
;
804 FillOutputRequest
->CodeType
= CodeType
;
805 FillOutputRequest
->Code
= Code
;
806 FillOutputRequest
->NumCodes
= nLength
;
808 /* Call the server */
809 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
811 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFillConsoleOutput
),
812 sizeof(*FillOutputRequest
));
814 /* Check for success */
815 if (NT_SUCCESS(ApiMessage
.Status
))
817 if (lpNumberOfCodesWritten
!= NULL
)
818 *lpNumberOfCodesWritten
= FillOutputRequest
->NumCodes
;
822 if (lpNumberOfCodesWritten
!= NULL
)
823 *lpNumberOfCodesWritten
= 0;
825 BaseSetLastNTError(ApiMessage
.Status
);
828 /* Return TRUE or FALSE */
829 return NT_SUCCESS(ApiMessage
.Status
);
833 /* FUNCTIONS ******************************************************************/
839 /*--------------------------------------------------------------
846 ReadConsoleW(HANDLE hConsoleInput
,
848 DWORD nNumberOfCharsToRead
,
849 LPDWORD lpNumberOfCharsRead
,
850 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
852 return IntReadConsole(hConsoleInput
,
854 nNumberOfCharsToRead
,
861 /*--------------------------------------------------------------
868 ReadConsoleA(HANDLE hConsoleInput
,
870 DWORD nNumberOfCharsToRead
,
871 LPDWORD lpNumberOfCharsRead
,
872 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
874 return IntReadConsole(hConsoleInput
,
876 nNumberOfCharsToRead
,
883 /*--------------------------------------------------------------
890 PeekConsoleInputW(HANDLE hConsoleInput
,
891 PINPUT_RECORD lpBuffer
,
893 LPDWORD lpNumberOfEventsRead
)
895 return IntGetConsoleInput(hConsoleInput
,
898 lpNumberOfEventsRead
,
899 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
904 /*--------------------------------------------------------------
911 PeekConsoleInputA(HANDLE hConsoleInput
,
912 PINPUT_RECORD lpBuffer
,
914 LPDWORD lpNumberOfEventsRead
)
916 return IntGetConsoleInput(hConsoleInput
,
919 lpNumberOfEventsRead
,
920 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
925 /*--------------------------------------------------------------
932 ReadConsoleInputW(HANDLE hConsoleInput
,
933 PINPUT_RECORD lpBuffer
,
935 LPDWORD lpNumberOfEventsRead
)
937 return IntGetConsoleInput(hConsoleInput
,
940 lpNumberOfEventsRead
,
946 /*--------------------------------------------------------------
953 ReadConsoleInputA(HANDLE hConsoleInput
,
954 PINPUT_RECORD lpBuffer
,
956 LPDWORD lpNumberOfEventsRead
)
958 return IntGetConsoleInput(hConsoleInput
,
961 lpNumberOfEventsRead
,
967 /*--------------------------------------------------------------
968 * ReadConsoleInputExW
974 ReadConsoleInputExW(HANDLE hConsoleInput
,
975 PINPUT_RECORD lpBuffer
,
977 LPDWORD lpNumberOfEventsRead
,
980 return IntGetConsoleInput(hConsoleInput
,
983 lpNumberOfEventsRead
,
989 /*--------------------------------------------------------------
990 * ReadConsoleInputExA
996 ReadConsoleInputExA(HANDLE hConsoleInput
,
997 PINPUT_RECORD lpBuffer
,
999 LPDWORD lpNumberOfEventsRead
,
1002 return IntGetConsoleInput(hConsoleInput
,
1005 lpNumberOfEventsRead
,
1011 /*--------------------------------------------------------------
1012 * ReadConsoleOutputW
1018 ReadConsoleOutputW(HANDLE hConsoleOutput
,
1019 PCHAR_INFO lpBuffer
,
1021 COORD dwBufferCoord
,
1022 PSMALL_RECT lpReadRegion
)
1024 return IntReadConsoleOutput(hConsoleOutput
,
1033 /*--------------------------------------------------------------
1034 * ReadConsoleOutputA
1040 ReadConsoleOutputA(HANDLE hConsoleOutput
,
1041 PCHAR_INFO lpBuffer
,
1043 COORD dwBufferCoord
,
1044 PSMALL_RECT lpReadRegion
)
1046 return IntReadConsoleOutput(hConsoleOutput
,
1055 /*--------------------------------------------------------------
1056 * ReadConsoleOutputCharacterW
1062 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1066 LPDWORD lpNumberOfCharsRead
)
1068 return IntReadConsoleOutputCode(hConsoleOutput
,
1073 lpNumberOfCharsRead
);
1077 /*--------------------------------------------------------------
1078 * ReadConsoleOutputCharacterA
1084 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1088 LPDWORD lpNumberOfCharsRead
)
1090 return IntReadConsoleOutputCode(hConsoleOutput
,
1095 lpNumberOfCharsRead
);
1099 /*--------------------------------------------------------------
1100 * ReadConsoleOutputAttribute
1106 ReadConsoleOutputAttribute(HANDLE hConsoleOutput
,
1110 LPDWORD lpNumberOfAttrsRead
)
1112 return IntReadConsoleOutputCode(hConsoleOutput
,
1117 lpNumberOfAttrsRead
);
1121 /*******************
1123 *******************/
1125 /*--------------------------------------------------------------
1132 WriteConsoleW(HANDLE hConsoleOutput
,
1133 CONST VOID
*lpBuffer
,
1134 DWORD nNumberOfCharsToWrite
,
1135 LPDWORD lpNumberOfCharsWritten
,
1138 return IntWriteConsole(hConsoleOutput
,
1140 nNumberOfCharsToWrite
,
1141 lpNumberOfCharsWritten
,
1147 /*--------------------------------------------------------------
1154 WriteConsoleA(HANDLE hConsoleOutput
,
1155 CONST VOID
*lpBuffer
,
1156 DWORD nNumberOfCharsToWrite
,
1157 LPDWORD lpNumberOfCharsWritten
,
1160 return IntWriteConsole(hConsoleOutput
,
1162 nNumberOfCharsToWrite
,
1163 lpNumberOfCharsWritten
,
1169 /*--------------------------------------------------------------
1170 * WriteConsoleInputW
1176 WriteConsoleInputW(HANDLE hConsoleInput
,
1177 CONST INPUT_RECORD
*lpBuffer
,
1179 LPDWORD lpNumberOfEventsWritten
)
1181 return IntWriteConsoleInput(hConsoleInput
,
1182 (PINPUT_RECORD
)lpBuffer
,
1184 lpNumberOfEventsWritten
,
1190 /*--------------------------------------------------------------
1191 * WriteConsoleInputA
1197 WriteConsoleInputA(HANDLE hConsoleInput
,
1198 CONST INPUT_RECORD
*lpBuffer
,
1200 LPDWORD lpNumberOfEventsWritten
)
1202 return IntWriteConsoleInput(hConsoleInput
,
1203 (PINPUT_RECORD
)lpBuffer
,
1205 lpNumberOfEventsWritten
,
1211 /*--------------------------------------------------------------
1212 * WriteConsoleInputVDMW
1218 WriteConsoleInputVDMW(HANDLE hConsoleInput
,
1219 CONST INPUT_RECORD
*lpBuffer
,
1221 LPDWORD lpNumberOfEventsWritten
)
1223 return IntWriteConsoleInput(hConsoleInput
,
1224 (PINPUT_RECORD
)lpBuffer
,
1226 lpNumberOfEventsWritten
,
1232 /*--------------------------------------------------------------
1233 * WriteConsoleInputVDMA
1239 WriteConsoleInputVDMA(HANDLE hConsoleInput
,
1240 CONST INPUT_RECORD
*lpBuffer
,
1242 LPDWORD lpNumberOfEventsWritten
)
1244 return IntWriteConsoleInput(hConsoleInput
,
1245 (PINPUT_RECORD
)lpBuffer
,
1247 lpNumberOfEventsWritten
,
1253 /*--------------------------------------------------------------
1254 * WriteConsoleOutputW
1260 WriteConsoleOutputW(HANDLE hConsoleOutput
,
1261 CONST CHAR_INFO
*lpBuffer
,
1263 COORD dwBufferCoord
,
1264 PSMALL_RECT lpWriteRegion
)
1266 return IntWriteConsoleOutput(hConsoleOutput
,
1275 /*--------------------------------------------------------------
1276 * WriteConsoleOutputA
1282 WriteConsoleOutputA(HANDLE hConsoleOutput
,
1283 CONST CHAR_INFO
*lpBuffer
,
1285 COORD dwBufferCoord
,
1286 PSMALL_RECT lpWriteRegion
)
1288 return IntWriteConsoleOutput(hConsoleOutput
,
1297 /*--------------------------------------------------------------
1298 * WriteConsoleOutputCharacterW
1304 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1305 LPCWSTR lpCharacter
,
1308 LPDWORD lpNumberOfCharsWritten
)
1310 return IntWriteConsoleOutputCode(hConsoleOutput
,
1315 lpNumberOfCharsWritten
);
1319 /*--------------------------------------------------------------
1320 * WriteConsoleOutputCharacterA
1326 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1330 LPDWORD lpNumberOfCharsWritten
)
1332 return IntWriteConsoleOutputCode(hConsoleOutput
,
1337 lpNumberOfCharsWritten
);
1341 /*--------------------------------------------------------------
1342 * WriteConsoleOutputAttribute
1348 WriteConsoleOutputAttribute(HANDLE hConsoleOutput
,
1349 CONST WORD
*lpAttribute
,
1352 LPDWORD lpNumberOfAttrsWritten
)
1354 return IntWriteConsoleOutputCode(hConsoleOutput
,
1359 lpNumberOfAttrsWritten
);
1363 /*--------------------------------------------------------------
1364 * FillConsoleOutputCharacterW
1370 FillConsoleOutputCharacterW(HANDLE hConsoleOutput
,
1374 LPDWORD lpNumberOfCharsWritten
)
1377 Code
.UnicodeChar
= cCharacter
;
1378 return IntFillConsoleOutputCode(hConsoleOutput
,
1383 lpNumberOfCharsWritten
);
1387 /*--------------------------------------------------------------
1388 * FillConsoleOutputCharacterA
1394 FillConsoleOutputCharacterA(HANDLE hConsoleOutput
,
1398 LPDWORD lpNumberOfCharsWritten
)
1401 Code
.AsciiChar
= cCharacter
;
1402 return IntFillConsoleOutputCode(hConsoleOutput
,
1407 lpNumberOfCharsWritten
);
1411 /*--------------------------------------------------------------
1412 * FillConsoleOutputAttribute
1418 FillConsoleOutputAttribute(HANDLE hConsoleOutput
,
1422 LPDWORD lpNumberOfAttrsWritten
)
1425 Code
.Attribute
= wAttribute
;
1426 return IntFillConsoleOutputCode(hConsoleOutput
,
1431 lpNumberOfAttrsWritten
);