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(IN HANDLE hConsoleInput
,
122 OUT PINPUT_RECORD lpBuffer
,
124 OUT LPDWORD lpNumberOfEventsRead
,
129 CONSOLE_API_MESSAGE ApiMessage
;
130 PCONSOLE_GETINPUT GetInputRequest
= &ApiMessage
.Data
.GetInputRequest
;
131 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
133 if (!IsConsoleHandle(hConsoleInput
))
137 *lpNumberOfEventsRead
= 0;
138 SetLastError(ERROR_INVALID_HANDLE
);
140 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
142 SetLastError(ERROR_INVALID_ACCESS
);
149 DPRINT("IntGetConsoleInput: %lx %p\n", nLength
, lpNumberOfEventsRead
);
151 /* Set up the data to send to the Console Server */
152 GetInputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
153 GetInputRequest
->InputHandle
= hConsoleInput
;
154 GetInputRequest
->NumRecords
= nLength
;
155 GetInputRequest
->Flags
= wFlags
;
156 GetInputRequest
->Unicode
= bUnicode
;
159 * For optimization purposes, Windows (and hence ReactOS, too, for
160 * compatibility reasons) uses a static buffer if no more than five
161 * input records are read. Otherwise a new buffer is allocated.
162 * This behaviour is also expected in the server-side.
164 if (nLength
<= sizeof(GetInputRequest
->RecordStaticBuffer
)/sizeof(INPUT_RECORD
))
166 GetInputRequest
->RecordBufPtr
= GetInputRequest
->RecordStaticBuffer
;
167 // CaptureBuffer = NULL;
171 ULONG Size
= nLength
* sizeof(INPUT_RECORD
);
173 /* Allocate a Capture Buffer */
174 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
175 if (CaptureBuffer
== NULL
)
177 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
178 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
182 /* Allocate space in the Buffer */
183 CsrAllocateMessagePointer(CaptureBuffer
,
185 (PVOID
*)&GetInputRequest
->RecordBufPtr
);
188 /* Call the server */
189 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
191 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepGetConsoleInput
),
192 sizeof(*GetInputRequest
));
194 /* Check for success */
195 Success
= NT_SUCCESS(ApiMessage
.Status
);
197 /* Retrieve the results */
200 DPRINT("Events read: %lx\n", GetInputRequest
->NumRecords
);
201 *lpNumberOfEventsRead
= GetInputRequest
->NumRecords
;
205 RtlCopyMemory(lpBuffer
,
206 GetInputRequest
->RecordBufPtr
,
207 GetInputRequest
->NumRecords
* sizeof(INPUT_RECORD
));
211 BaseSetLastNTError(ApiMessage
.Status
);
214 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
216 SetLastError(ERROR_INVALID_ACCESS
);
221 /* Release the capture buffer if needed */
222 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
224 /* Return success status */
231 IntReadConsoleOutput(HANDLE hConsoleOutput
,
235 PSMALL_RECT lpReadRegion
,
238 CONSOLE_API_MESSAGE ApiMessage
;
239 PCONSOLE_READOUTPUT ReadOutputRequest
= &ApiMessage
.Data
.ReadOutputRequest
;
240 PCSR_CAPTURE_BUFFER CaptureBuffer
;
241 DWORD Size
, SizeX
, SizeY
;
243 if (lpBuffer
== NULL
)
245 SetLastError(ERROR_INVALID_ACCESS
);
249 Size
= dwBufferSize
.X
* dwBufferSize
.Y
* sizeof(CHAR_INFO
);
251 DPRINT("IntReadConsoleOutput: %lx %p\n", Size
, lpReadRegion
);
253 /* Allocate a Capture Buffer */
254 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
255 if (CaptureBuffer
== NULL
)
257 DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size
);
258 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
262 /* Allocate space in the Buffer */
263 CsrAllocateMessagePointer(CaptureBuffer
,
265 (PVOID
*)&ReadOutputRequest
->CharInfo
);
267 /* Set up the data to send to the Console Server */
268 ReadOutputRequest
->OutputHandle
= hConsoleOutput
;
269 ReadOutputRequest
->Unicode
= bUnicode
;
270 ReadOutputRequest
->BufferSize
= dwBufferSize
;
271 ReadOutputRequest
->BufferCoord
= dwBufferCoord
;
272 ReadOutputRequest
->ReadRegion
= *lpReadRegion
;
274 /* Call the server */
275 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
277 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsoleOutput
),
278 sizeof(*ReadOutputRequest
));
280 /* Check for success */
281 if (NT_SUCCESS(ApiMessage
.Status
))
283 /* Copy into the buffer */
284 DPRINT("Copying to buffer\n");
285 SizeX
= ReadOutputRequest
->ReadRegion
.Right
-
286 ReadOutputRequest
->ReadRegion
.Left
+ 1;
287 SizeY
= ReadOutputRequest
->ReadRegion
.Bottom
-
288 ReadOutputRequest
->ReadRegion
.Top
+ 1;
289 RtlCopyMemory(lpBuffer
,
290 ReadOutputRequest
->CharInfo
,
291 sizeof(CHAR_INFO
) * SizeX
* SizeY
);
296 BaseSetLastNTError(ApiMessage
.Status
);
299 /* Return the read region */
300 DPRINT("read region: %p\n", ReadOutputRequest
->ReadRegion
);
301 *lpReadRegion
= ReadOutputRequest
->ReadRegion
;
303 /* Release the capture buffer */
304 CsrFreeCaptureBuffer(CaptureBuffer
);
306 /* Return TRUE or FALSE */
307 return NT_SUCCESS(ApiMessage
.Status
);
313 IntReadConsoleOutputCode(IN HANDLE hConsoleOutput
,
314 IN CODE_TYPE CodeType
,
317 IN COORD dwReadCoord
,
318 OUT LPDWORD lpNumberOfCodesRead
)
321 CONSOLE_API_MESSAGE ApiMessage
;
322 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest
= &ApiMessage
.Data
.ReadOutputCodeRequest
;
323 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
324 ULONG SizeBytes
, CodeSize
;
326 DPRINT("IntReadConsoleOutputCode\n");
328 if ( (CodeType
!= CODE_ASCII
) &&
329 (CodeType
!= CODE_UNICODE
) &&
330 (CodeType
!= CODE_ATTRIBUTE
) )
332 SetLastError(ERROR_INVALID_PARAMETER
);
336 /* Set up the data to send to the Console Server */
337 ReadOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
338 ReadOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
339 ReadOutputCodeRequest
->Coord
= dwReadCoord
;
340 ReadOutputCodeRequest
->NumCodes
= nLength
;
342 /* Determine the needed size */
343 ReadOutputCodeRequest
->CodeType
= CodeType
;
347 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, AsciiChar
);
351 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, UnicodeChar
);
355 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, Attribute
);
358 SizeBytes
= nLength
* CodeSize
;
361 * For optimization purposes, Windows (and hence ReactOS, too, for
362 * compatibility reasons) uses a static buffer if no more than eighty
363 * bytes are read. Otherwise a new buffer is allocated.
364 * This behaviour is also expected in the server-side.
366 if (SizeBytes
<= sizeof(ReadOutputCodeRequest
->CodeStaticBuffer
))
368 ReadOutputCodeRequest
->pCode
= ReadOutputCodeRequest
->CodeStaticBuffer
;
369 // CaptureBuffer = NULL;
373 /* Allocate a Capture Buffer */
374 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
375 if (CaptureBuffer
== NULL
)
377 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
378 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
382 /* Allocate space in the Buffer */
383 CsrAllocateMessagePointer(CaptureBuffer
,
385 (PVOID
*)&ReadOutputCodeRequest
->pCode
);
388 /* Call the server */
389 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
391 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepReadConsoleOutputString
),
392 sizeof(*ReadOutputCodeRequest
));
394 /* Check for success */
395 Success
= NT_SUCCESS(ApiMessage
.Status
);
397 /* Retrieve the results */
400 *lpNumberOfCodesRead
= ReadOutputCodeRequest
->NumCodes
;
405 ReadOutputCodeRequest
->pCode
,
406 ReadOutputCodeRequest
->NumCodes
* CodeSize
);
410 BaseSetLastNTError(ApiMessage
.Status
);
413 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
415 SetLastError(ERROR_INVALID_ACCESS
);
420 /* Release the capture buffer if needed */
421 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
423 /* Return success status */
434 IntWriteConsole(HANDLE hConsoleOutput
,
436 DWORD nNumberOfCharsToWrite
,
437 LPDWORD lpNumberOfCharsWritten
,
442 CONSOLE_API_MESSAGE ApiMessage
;
443 PCONSOLE_WRITECONSOLE WriteConsoleRequest
= &ApiMessage
.Data
.WriteConsoleRequest
;
444 PCSR_CAPTURE_BUFFER CaptureBuffer
;
447 /* Determine the needed size */
448 CharSize
= (bUnicode
? sizeof(WCHAR
) : sizeof(CHAR
));
449 WriteConsoleRequest
->BufferSize
= nNumberOfCharsToWrite
* CharSize
;
451 /* Allocate a Capture Buffer */
452 CaptureBuffer
= CsrAllocateCaptureBuffer(1, WriteConsoleRequest
->BufferSize
);
453 if (CaptureBuffer
== NULL
)
455 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
456 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
460 /* Capture the buffer to write */
461 CsrCaptureMessageBuffer(CaptureBuffer
,
463 WriteConsoleRequest
->BufferSize
,
464 (PVOID
*)&WriteConsoleRequest
->Buffer
);
467 WriteConsoleRequest
->NrCharactersToWrite
= nNumberOfCharsToWrite
;
468 WriteConsoleRequest
->OutputHandle
= hConsoleOutput
;
469 WriteConsoleRequest
->Unicode
= bUnicode
;
471 /* Call the server */
472 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
474 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsole
),
475 sizeof(*WriteConsoleRequest
));
477 /* Check for success */
478 if (NT_SUCCESS(ApiMessage
.Status
))
480 if (lpNumberOfCharsWritten
!= NULL
)
481 *lpNumberOfCharsWritten
= WriteConsoleRequest
->NrCharactersWritten
;
487 if (lpNumberOfCharsWritten
!= NULL
)
488 *lpNumberOfCharsWritten
= 0;
491 BaseSetLastNTError(ApiMessage
.Status
);
495 CsrFreeCaptureBuffer(CaptureBuffer
);
503 IntWriteConsoleInput(IN HANDLE hConsoleInput
,
504 IN PINPUT_RECORD lpBuffer
,
506 OUT LPDWORD lpNumberOfEventsWritten
,
508 IN BOOLEAN bAppendToEnd
)
511 CONSOLE_API_MESSAGE ApiMessage
;
512 PCONSOLE_WRITEINPUT WriteInputRequest
= &ApiMessage
.Data
.WriteInputRequest
;
513 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
515 DPRINT("IntWriteConsoleInput: %lx %p\n", nLength
, lpNumberOfEventsWritten
);
517 /* Set up the data to send to the Console Server */
518 WriteInputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
519 WriteInputRequest
->InputHandle
= hConsoleInput
;
520 WriteInputRequest
->NumRecords
= nLength
;
521 WriteInputRequest
->Unicode
= bUnicode
;
522 WriteInputRequest
->AppendToEnd
= bAppendToEnd
;
525 * For optimization purposes, Windows (and hence ReactOS, too, for
526 * compatibility reasons) uses a static buffer if no more than five
527 * input records are written. Otherwise a new buffer is allocated.
528 * This behaviour is also expected in the server-side.
530 if (nLength
<= sizeof(WriteInputRequest
->RecordStaticBuffer
)/sizeof(INPUT_RECORD
))
532 WriteInputRequest
->RecordBufPtr
= WriteInputRequest
->RecordStaticBuffer
;
533 // CaptureBuffer = NULL;
537 RtlCopyMemory(WriteInputRequest
->RecordBufPtr
,
539 nLength
* sizeof(INPUT_RECORD
));
541 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
543 SetLastError(ERROR_INVALID_ACCESS
);
550 ULONG Size
= nLength
* sizeof(INPUT_RECORD
);
552 /* Allocate a Capture Buffer */
553 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
554 if (CaptureBuffer
== NULL
)
556 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
557 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
561 /* Capture the user buffer */
562 CsrCaptureMessageBuffer(CaptureBuffer
,
565 (PVOID
*)&WriteInputRequest
->RecordBufPtr
);
568 /* Call the server */
569 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
571 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleInput
),
572 sizeof(*WriteInputRequest
));
574 /* Check for success */
575 Success
= NT_SUCCESS(ApiMessage
.Status
);
577 /* Release the capture buffer if needed */
578 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
580 /* Retrieve the results */
583 DPRINT("Events written: %lx\n", WriteInputRequest
->NumRecords
);
584 *lpNumberOfEventsWritten
= WriteInputRequest
->NumRecords
;
587 BaseSetLastNTError(ApiMessage
.Status
);
589 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
591 SetLastError(ERROR_INVALID_ACCESS
);
596 /* Return success status */
603 IntWriteConsoleOutput(HANDLE hConsoleOutput
,
604 CONST CHAR_INFO
*lpBuffer
,
607 PSMALL_RECT lpWriteRegion
,
610 CONSOLE_API_MESSAGE ApiMessage
;
611 PCONSOLE_WRITEOUTPUT WriteOutputRequest
= &ApiMessage
.Data
.WriteOutputRequest
;
612 PCSR_CAPTURE_BUFFER CaptureBuffer
;
615 if ((lpBuffer
== NULL
) || (lpWriteRegion
== NULL
))
617 SetLastError(ERROR_INVALID_ACCESS
);
621 if (lpWriteRegion == NULL)
623 SetLastError(ERROR_INVALID_PARAMETER);
628 Size
= dwBufferSize
.Y
* dwBufferSize
.X
* sizeof(CHAR_INFO
);
630 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size
, lpWriteRegion
);
632 /* Allocate a Capture Buffer */
633 CaptureBuffer
= CsrAllocateCaptureBuffer(1, Size
);
634 if (CaptureBuffer
== NULL
)
636 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
637 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
641 /* Capture the user buffer */
642 CsrCaptureMessageBuffer(CaptureBuffer
,
645 (PVOID
*)&WriteOutputRequest
->CharInfo
);
647 /* Set up the data to send to the Console Server */
648 WriteOutputRequest
->OutputHandle
= hConsoleOutput
;
649 WriteOutputRequest
->Unicode
= bUnicode
;
650 WriteOutputRequest
->BufferSize
= dwBufferSize
;
651 WriteOutputRequest
->BufferCoord
= dwBufferCoord
;
652 WriteOutputRequest
->WriteRegion
= *lpWriteRegion
;
654 /* Call the server */
655 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
657 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutput
),
658 sizeof(*WriteOutputRequest
));
660 /* Check for success */
661 if (!NT_SUCCESS(ApiMessage
.Status
))
664 BaseSetLastNTError(ApiMessage
.Status
);
667 /* Return the read region */
668 DPRINT("read region: %p\n", WriteOutputRequest
->WriteRegion
);
669 *lpWriteRegion
= WriteOutputRequest
->WriteRegion
;
671 /* Release the capture buffer */
672 CsrFreeCaptureBuffer(CaptureBuffer
);
674 /* Return TRUE or FALSE */
675 return NT_SUCCESS(ApiMessage
.Status
);
681 IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput
,
682 IN CODE_TYPE CodeType
,
683 IN CONST VOID
*pCode
,
685 IN COORD dwWriteCoord
,
686 OUT LPDWORD lpNumberOfCodesWritten
)
689 CONSOLE_API_MESSAGE ApiMessage
;
690 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest
= &ApiMessage
.Data
.WriteOutputCodeRequest
;
691 PCSR_CAPTURE_BUFFER CaptureBuffer
= NULL
;
692 ULONG SizeBytes
, CodeSize
;
694 if ( (CodeType
!= CODE_ASCII
) &&
695 (CodeType
!= CODE_UNICODE
) &&
696 (CodeType
!= CODE_ATTRIBUTE
) )
698 SetLastError(ERROR_INVALID_PARAMETER
);
702 DPRINT("IntWriteConsoleOutputCode\n");
704 /* Set up the data to send to the Console Server */
705 WriteOutputCodeRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
706 WriteOutputCodeRequest
->OutputHandle
= hConsoleOutput
;
707 WriteOutputCodeRequest
->Coord
= dwWriteCoord
;
708 WriteOutputCodeRequest
->NumCodes
= nLength
;
710 /* Determine the needed size */
711 WriteOutputCodeRequest
->CodeType
= CodeType
;
715 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, AsciiChar
);
719 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, UnicodeChar
);
723 CodeSize
= RTL_FIELD_SIZE(CODE_ELEMENT
, Attribute
);
726 SizeBytes
= nLength
* CodeSize
;
729 * For optimization purposes, Windows (and hence ReactOS, too, for
730 * compatibility reasons) uses a static buffer if no more than eighty
731 * bytes are written. Otherwise a new buffer is allocated.
732 * This behaviour is also expected in the server-side.
734 if (SizeBytes
<= sizeof(WriteOutputCodeRequest
->CodeStaticBuffer
))
736 WriteOutputCodeRequest
->pCode
= WriteOutputCodeRequest
->CodeStaticBuffer
;
737 // CaptureBuffer = NULL;
741 RtlCopyMemory(WriteOutputCodeRequest
->pCode
,
745 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
747 SetLastError(ERROR_INVALID_ACCESS
);
754 /* Allocate a Capture Buffer */
755 CaptureBuffer
= CsrAllocateCaptureBuffer(1, SizeBytes
);
756 if (CaptureBuffer
== NULL
)
758 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
759 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
763 /* Capture the buffer to write */
764 CsrCaptureMessageBuffer(CaptureBuffer
,
767 (PVOID
*)&WriteOutputCodeRequest
->pCode
);
770 /* Call the server */
771 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
773 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepWriteConsoleOutputString
),
774 sizeof(*WriteOutputCodeRequest
));
776 /* Check for success */
777 Success
= NT_SUCCESS(ApiMessage
.Status
);
779 /* Release the capture buffer if needed */
780 if (CaptureBuffer
) CsrFreeCaptureBuffer(CaptureBuffer
);
782 /* Retrieve the results */
785 *lpNumberOfCodesWritten
= WriteOutputCodeRequest
->NumCodes
;
788 BaseSetLastNTError(ApiMessage
.Status
);
790 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
792 SetLastError(ERROR_INVALID_ACCESS
);
797 /* Return success status */
804 IntFillConsoleOutputCode(IN HANDLE hConsoleOutput
,
805 IN CODE_TYPE CodeType
,
806 IN CODE_ELEMENT Code
,
808 IN COORD dwWriteCoord
,
809 OUT LPDWORD lpNumberOfCodesWritten
)
812 CONSOLE_API_MESSAGE ApiMessage
;
813 PCONSOLE_FILLOUTPUTCODE FillOutputRequest
= &ApiMessage
.Data
.FillOutputRequest
;
815 DPRINT("IntFillConsoleOutputCode\n");
817 if ( (CodeType
!= CODE_ASCII
) &&
818 (CodeType
!= CODE_UNICODE
) &&
819 (CodeType
!= CODE_ATTRIBUTE
) )
821 SetLastError(ERROR_INVALID_PARAMETER
);
825 /* Set up the data to send to the Console Server */
826 FillOutputRequest
->ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->ConsoleHandle
;
827 FillOutputRequest
->OutputHandle
= hConsoleOutput
;
828 FillOutputRequest
->WriteCoord
= dwWriteCoord
;
829 FillOutputRequest
->CodeType
= CodeType
;
830 FillOutputRequest
->Code
= Code
;
831 FillOutputRequest
->NumCodes
= nLength
;
833 /* Call the server */
834 CsrClientCallServer((PCSR_API_MESSAGE
)&ApiMessage
,
836 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX
, ConsolepFillConsoleOutput
),
837 sizeof(*FillOutputRequest
));
839 /* Check for success */
840 Success
= NT_SUCCESS(ApiMessage
.Status
);
842 /* Retrieve the results */
845 *lpNumberOfCodesWritten
= FillOutputRequest
->NumCodes
;
848 BaseSetLastNTError(ApiMessage
.Status
);
850 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
852 SetLastError(ERROR_INVALID_ACCESS
);
857 /* Return success status */
862 /* FUNCTIONS ******************************************************************/
868 /*--------------------------------------------------------------
875 ReadConsoleW(HANDLE hConsoleInput
,
877 DWORD nNumberOfCharsToRead
,
878 LPDWORD lpNumberOfCharsRead
,
879 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
881 return IntReadConsole(hConsoleInput
,
883 nNumberOfCharsToRead
,
890 /*--------------------------------------------------------------
897 ReadConsoleA(HANDLE hConsoleInput
,
899 DWORD nNumberOfCharsToRead
,
900 LPDWORD lpNumberOfCharsRead
,
901 PCONSOLE_READCONSOLE_CONTROL pInputControl
)
903 return IntReadConsole(hConsoleInput
,
905 nNumberOfCharsToRead
,
912 /*--------------------------------------------------------------
919 PeekConsoleInputW(IN HANDLE hConsoleInput
,
920 OUT PINPUT_RECORD lpBuffer
,
922 OUT LPDWORD lpNumberOfEventsRead
)
924 return IntGetConsoleInput(hConsoleInput
,
927 lpNumberOfEventsRead
,
928 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
933 /*--------------------------------------------------------------
940 PeekConsoleInputA(IN HANDLE hConsoleInput
,
941 OUT PINPUT_RECORD lpBuffer
,
943 OUT LPDWORD lpNumberOfEventsRead
)
945 return IntGetConsoleInput(hConsoleInput
,
948 lpNumberOfEventsRead
,
949 CONSOLE_READ_KEEPEVENT
| CONSOLE_READ_CONTINUE
,
954 /*--------------------------------------------------------------
961 ReadConsoleInputW(IN HANDLE hConsoleInput
,
962 OUT PINPUT_RECORD lpBuffer
,
964 OUT LPDWORD lpNumberOfEventsRead
)
966 return IntGetConsoleInput(hConsoleInput
,
969 lpNumberOfEventsRead
,
975 /*--------------------------------------------------------------
982 ReadConsoleInputA(IN HANDLE hConsoleInput
,
983 OUT PINPUT_RECORD lpBuffer
,
985 OUT LPDWORD lpNumberOfEventsRead
)
987 return IntGetConsoleInput(hConsoleInput
,
990 lpNumberOfEventsRead
,
996 /*--------------------------------------------------------------
997 * ReadConsoleInputExW
1003 ReadConsoleInputExW(IN HANDLE hConsoleInput
,
1004 OUT PINPUT_RECORD lpBuffer
,
1006 OUT LPDWORD lpNumberOfEventsRead
,
1009 return IntGetConsoleInput(hConsoleInput
,
1012 lpNumberOfEventsRead
,
1018 /*--------------------------------------------------------------
1019 * ReadConsoleInputExA
1025 ReadConsoleInputExA(IN HANDLE hConsoleInput
,
1026 OUT PINPUT_RECORD lpBuffer
,
1028 OUT LPDWORD lpNumberOfEventsRead
,
1031 return IntGetConsoleInput(hConsoleInput
,
1034 lpNumberOfEventsRead
,
1040 /*--------------------------------------------------------------
1041 * ReadConsoleOutputW
1047 ReadConsoleOutputW(HANDLE hConsoleOutput
,
1048 PCHAR_INFO lpBuffer
,
1050 COORD dwBufferCoord
,
1051 PSMALL_RECT lpReadRegion
)
1053 return IntReadConsoleOutput(hConsoleOutput
,
1062 /*--------------------------------------------------------------
1063 * ReadConsoleOutputA
1069 ReadConsoleOutputA(HANDLE hConsoleOutput
,
1070 PCHAR_INFO lpBuffer
,
1072 COORD dwBufferCoord
,
1073 PSMALL_RECT lpReadRegion
)
1075 return IntReadConsoleOutput(hConsoleOutput
,
1084 /*--------------------------------------------------------------
1085 * ReadConsoleOutputCharacterW
1091 ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput
,
1092 OUT LPWSTR lpCharacter
,
1094 IN COORD dwReadCoord
,
1095 OUT LPDWORD lpNumberOfCharsRead
)
1097 return IntReadConsoleOutputCode(hConsoleOutput
,
1102 lpNumberOfCharsRead
);
1106 /*--------------------------------------------------------------
1107 * ReadConsoleOutputCharacterA
1113 ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput
,
1114 OUT LPSTR lpCharacter
,
1116 IN COORD dwReadCoord
,
1117 OUT LPDWORD lpNumberOfCharsRead
)
1119 return IntReadConsoleOutputCode(hConsoleOutput
,
1124 lpNumberOfCharsRead
);
1128 /*--------------------------------------------------------------
1129 * ReadConsoleOutputAttribute
1135 ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput
,
1136 OUT LPWORD lpAttribute
,
1138 IN COORD dwReadCoord
,
1139 OUT LPDWORD lpNumberOfAttrsRead
)
1141 return IntReadConsoleOutputCode(hConsoleOutput
,
1146 lpNumberOfAttrsRead
);
1150 /*******************
1152 *******************/
1154 /*--------------------------------------------------------------
1161 WriteConsoleW(HANDLE hConsoleOutput
,
1162 CONST VOID
*lpBuffer
,
1163 DWORD nNumberOfCharsToWrite
,
1164 LPDWORD lpNumberOfCharsWritten
,
1167 return IntWriteConsole(hConsoleOutput
,
1169 nNumberOfCharsToWrite
,
1170 lpNumberOfCharsWritten
,
1176 /*--------------------------------------------------------------
1183 WriteConsoleA(HANDLE hConsoleOutput
,
1184 CONST VOID
*lpBuffer
,
1185 DWORD nNumberOfCharsToWrite
,
1186 LPDWORD lpNumberOfCharsWritten
,
1189 return IntWriteConsole(hConsoleOutput
,
1191 nNumberOfCharsToWrite
,
1192 lpNumberOfCharsWritten
,
1198 /*--------------------------------------------------------------
1199 * WriteConsoleInputW
1205 WriteConsoleInputW(IN HANDLE hConsoleInput
,
1206 IN CONST INPUT_RECORD
*lpBuffer
,
1208 OUT LPDWORD lpNumberOfEventsWritten
)
1210 return IntWriteConsoleInput(hConsoleInput
,
1211 (PINPUT_RECORD
)lpBuffer
,
1213 lpNumberOfEventsWritten
,
1219 /*--------------------------------------------------------------
1220 * WriteConsoleInputA
1226 WriteConsoleInputA(IN HANDLE hConsoleInput
,
1227 IN CONST INPUT_RECORD
*lpBuffer
,
1229 OUT LPDWORD lpNumberOfEventsWritten
)
1231 return IntWriteConsoleInput(hConsoleInput
,
1232 (PINPUT_RECORD
)lpBuffer
,
1234 lpNumberOfEventsWritten
,
1240 /*--------------------------------------------------------------
1241 * WriteConsoleInputVDMW
1247 WriteConsoleInputVDMW(IN HANDLE hConsoleInput
,
1248 IN CONST INPUT_RECORD
*lpBuffer
,
1250 OUT LPDWORD lpNumberOfEventsWritten
)
1252 return IntWriteConsoleInput(hConsoleInput
,
1253 (PINPUT_RECORD
)lpBuffer
,
1255 lpNumberOfEventsWritten
,
1261 /*--------------------------------------------------------------
1262 * WriteConsoleInputVDMA
1268 WriteConsoleInputVDMA(IN HANDLE hConsoleInput
,
1269 IN CONST INPUT_RECORD
*lpBuffer
,
1271 OUT LPDWORD lpNumberOfEventsWritten
)
1273 return IntWriteConsoleInput(hConsoleInput
,
1274 (PINPUT_RECORD
)lpBuffer
,
1276 lpNumberOfEventsWritten
,
1282 /*--------------------------------------------------------------
1283 * WriteConsoleOutputW
1289 WriteConsoleOutputW(HANDLE hConsoleOutput
,
1290 CONST CHAR_INFO
*lpBuffer
,
1292 COORD dwBufferCoord
,
1293 PSMALL_RECT lpWriteRegion
)
1295 return IntWriteConsoleOutput(hConsoleOutput
,
1304 /*--------------------------------------------------------------
1305 * WriteConsoleOutputA
1311 WriteConsoleOutputA(HANDLE hConsoleOutput
,
1312 CONST CHAR_INFO
*lpBuffer
,
1314 COORD dwBufferCoord
,
1315 PSMALL_RECT lpWriteRegion
)
1317 return IntWriteConsoleOutput(hConsoleOutput
,
1326 /*--------------------------------------------------------------
1327 * WriteConsoleOutputCharacterW
1333 WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput
,
1334 IN LPCWSTR lpCharacter
,
1336 IN COORD dwWriteCoord
,
1337 OUT LPDWORD lpNumberOfCharsWritten
)
1339 return IntWriteConsoleOutputCode(hConsoleOutput
,
1344 lpNumberOfCharsWritten
);
1348 /*--------------------------------------------------------------
1349 * WriteConsoleOutputCharacterA
1355 WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput
,
1356 IN LPCSTR lpCharacter
,
1358 IN COORD dwWriteCoord
,
1359 OUT LPDWORD lpNumberOfCharsWritten
)
1361 return IntWriteConsoleOutputCode(hConsoleOutput
,
1366 lpNumberOfCharsWritten
);
1370 /*--------------------------------------------------------------
1371 * WriteConsoleOutputAttribute
1377 WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput
,
1378 IN CONST WORD
*lpAttribute
,
1380 IN COORD dwWriteCoord
,
1381 OUT LPDWORD lpNumberOfAttrsWritten
)
1383 return IntWriteConsoleOutputCode(hConsoleOutput
,
1388 lpNumberOfAttrsWritten
);
1392 /*--------------------------------------------------------------
1393 * FillConsoleOutputCharacterW
1399 FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput
,
1400 IN WCHAR cCharacter
,
1402 IN COORD dwWriteCoord
,
1403 OUT LPDWORD lpNumberOfCharsWritten
)
1406 Code
.UnicodeChar
= cCharacter
;
1407 return IntFillConsoleOutputCode(hConsoleOutput
,
1412 lpNumberOfCharsWritten
);
1416 /*--------------------------------------------------------------
1417 * FillConsoleOutputCharacterA
1423 FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput
,
1426 IN COORD dwWriteCoord
,
1427 LPDWORD lpNumberOfCharsWritten
)
1430 Code
.AsciiChar
= cCharacter
;
1431 return IntFillConsoleOutputCode(hConsoleOutput
,
1436 lpNumberOfCharsWritten
);
1440 /*--------------------------------------------------------------
1441 * FillConsoleOutputAttribute
1447 FillConsoleOutputAttribute(IN HANDLE hConsoleOutput
,
1450 IN COORD dwWriteCoord
,
1451 OUT LPDWORD lpNumberOfAttrsWritten
)
1454 Code
.Attribute
= wAttribute
;
1455 return IntFillConsoleOutputCode(hConsoleOutput
,
1460 lpNumberOfAttrsWritten
);