[KERNEL32]
[reactos.git] / dll / win32 / kernel32 / client / console / readwrite.c
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 /* PRIVATE FUNCTIONS **********************************************************/
22
23 /******************
24 * Read functions *
25 ******************/
26
27 static
28 BOOL
29 IntReadConsole(HANDLE hConsoleInput,
30 PVOID lpBuffer,
31 DWORD nNumberOfCharsToRead,
32 LPDWORD lpNumberOfCharsRead,
33 PCONSOLE_READCONSOLE_CONTROL pInputControl,
34 BOOL bUnicode)
35 {
36 CONSOLE_API_MESSAGE ApiMessage;
37 PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
38 PCSR_CAPTURE_BUFFER CaptureBuffer;
39 ULONG CharSize;
40
41 /* Determine the needed size */
42 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
43 ReadConsoleRequest->BufferSize = nNumberOfCharsToRead * CharSize;
44
45 /* Allocate a Capture Buffer */
46 CaptureBuffer = CsrAllocateCaptureBuffer(1, ReadConsoleRequest->BufferSize);
47 if (CaptureBuffer == NULL)
48 {
49 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
50 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
51 return FALSE;
52 }
53
54 /* Allocate space in the Buffer */
55 CsrAllocateMessagePointer(CaptureBuffer,
56 ReadConsoleRequest->BufferSize,
57 (PVOID*)&ReadConsoleRequest->Buffer);
58
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))
66 {
67 /*
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."
72 */
73 ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
74 RtlCopyMemory(ReadConsoleRequest->Buffer,
75 lpBuffer,
76 pInputControl->nInitialChars * sizeof(WCHAR));
77 ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
78 }
79
80 /* Call the server */
81 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
82 CaptureBuffer,
83 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
84 sizeof(*ReadConsoleRequest));
85
86 /* Check for success */
87 if (NT_SUCCESS(ApiMessage.Status))
88 {
89 RtlCopyMemory(lpBuffer,
90 ReadConsoleRequest->Buffer,
91 ReadConsoleRequest->NrCharactersRead * CharSize);
92
93 if (lpNumberOfCharsRead != NULL)
94 *lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
95
96 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
97 pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
98 }
99 else
100 {
101 DPRINT1("CSR returned error in ReadConsole\n");
102
103 if (lpNumberOfCharsRead != NULL)
104 *lpNumberOfCharsRead = 0;
105
106 /* Error out */
107 BaseSetLastNTError(ApiMessage.Status);
108 }
109
110 CsrFreeCaptureBuffer(CaptureBuffer);
111
112 /* Return TRUE or FALSE */
113 // return TRUE;
114 return (ReadConsoleRequest->NrCharactersRead > 0);
115 // return NT_SUCCESS(ApiMessage.Status);
116 }
117
118
119 static
120 BOOL
121 IntGetConsoleInput(IN HANDLE hConsoleInput,
122 OUT PINPUT_RECORD lpBuffer,
123 IN DWORD nLength,
124 OUT LPDWORD lpNumberOfEventsRead,
125 IN WORD wFlags,
126 IN BOOLEAN bUnicode)
127 {
128 BOOL Success;
129 CONSOLE_API_MESSAGE ApiMessage;
130 PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
131 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
132
133 if (!IsConsoleHandle(hConsoleInput))
134 {
135 _SEH2_TRY
136 {
137 *lpNumberOfEventsRead = 0;
138 SetLastError(ERROR_INVALID_HANDLE);
139 }
140 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
141 {
142 SetLastError(ERROR_INVALID_ACCESS);
143 }
144 _SEH2_END;
145
146 return FALSE;
147 }
148
149 DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
150
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;
157
158 /*
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.
163 */
164 if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
165 {
166 GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
167 // CaptureBuffer = NULL;
168 }
169 else
170 {
171 ULONG Size = nLength * sizeof(INPUT_RECORD);
172
173 /* Allocate a Capture Buffer */
174 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
175 if (CaptureBuffer == NULL)
176 {
177 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
178 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
179 return FALSE;
180 }
181
182 /* Allocate space in the Buffer */
183 CsrAllocateMessagePointer(CaptureBuffer,
184 Size,
185 (PVOID*)&GetInputRequest->RecordBufPtr);
186 }
187
188 /* Call the server */
189 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
190 CaptureBuffer,
191 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
192 sizeof(*GetInputRequest));
193
194 /* Check for success */
195 Success = NT_SUCCESS(ApiMessage.Status);
196
197 /* Retrieve the results */
198 _SEH2_TRY
199 {
200 DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
201 *lpNumberOfEventsRead = GetInputRequest->NumRecords;
202
203 if (Success)
204 {
205 RtlCopyMemory(lpBuffer,
206 GetInputRequest->RecordBufPtr,
207 GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
208 }
209 else
210 {
211 BaseSetLastNTError(ApiMessage.Status);
212 }
213 }
214 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
215 {
216 SetLastError(ERROR_INVALID_ACCESS);
217 Success = FALSE;
218 }
219 _SEH2_END;
220
221 /* Release the capture buffer if needed */
222 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
223
224 /* Return success status */
225 return Success;
226 }
227
228
229 static
230 BOOL
231 IntReadConsoleOutput(HANDLE hConsoleOutput,
232 PCHAR_INFO lpBuffer,
233 COORD dwBufferSize,
234 COORD dwBufferCoord,
235 PSMALL_RECT lpReadRegion,
236 BOOL bUnicode)
237 {
238 CONSOLE_API_MESSAGE ApiMessage;
239 PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
240 PCSR_CAPTURE_BUFFER CaptureBuffer;
241 DWORD Size, SizeX, SizeY;
242
243 if (lpBuffer == NULL)
244 {
245 SetLastError(ERROR_INVALID_ACCESS);
246 return FALSE;
247 }
248
249 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
250
251 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
252
253 /* Allocate a Capture Buffer */
254 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
255 if (CaptureBuffer == NULL)
256 {
257 DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
258 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
259 return FALSE;
260 }
261
262 /* Allocate space in the Buffer */
263 CsrAllocateMessagePointer(CaptureBuffer,
264 Size,
265 (PVOID*)&ReadOutputRequest->CharInfo);
266
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;
273
274 /* Call the server */
275 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
276 CaptureBuffer,
277 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
278 sizeof(*ReadOutputRequest));
279
280 /* Check for success */
281 if (NT_SUCCESS(ApiMessage.Status))
282 {
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);
292 }
293 else
294 {
295 /* Error out */
296 BaseSetLastNTError(ApiMessage.Status);
297 }
298
299 /* Return the read region */
300 DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
301 *lpReadRegion = ReadOutputRequest->ReadRegion;
302
303 /* Release the capture buffer */
304 CsrFreeCaptureBuffer(CaptureBuffer);
305
306 /* Return TRUE or FALSE */
307 return NT_SUCCESS(ApiMessage.Status);
308 }
309
310
311 static
312 BOOL
313 IntReadConsoleOutputCode(IN HANDLE hConsoleOutput,
314 IN CODE_TYPE CodeType,
315 OUT PVOID pCode,
316 IN DWORD nLength,
317 IN COORD dwReadCoord,
318 OUT LPDWORD lpNumberOfCodesRead)
319 {
320 BOOL Success;
321 CONSOLE_API_MESSAGE ApiMessage;
322 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
323 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
324 ULONG SizeBytes, CodeSize;
325
326 DPRINT("IntReadConsoleOutputCode\n");
327
328 if ( (CodeType != CODE_ASCII ) &&
329 (CodeType != CODE_UNICODE ) &&
330 (CodeType != CODE_ATTRIBUTE) )
331 {
332 SetLastError(ERROR_INVALID_PARAMETER);
333 return FALSE;
334 }
335
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;
341
342 /* Determine the needed size */
343 ReadOutputCodeRequest->CodeType = CodeType;
344 switch (CodeType)
345 {
346 case CODE_ASCII:
347 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
348 break;
349
350 case CODE_UNICODE:
351 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
352 break;
353
354 case CODE_ATTRIBUTE:
355 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
356 break;
357 }
358 SizeBytes = nLength * CodeSize;
359
360 /*
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.
365 */
366 if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
367 {
368 ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
369 // CaptureBuffer = NULL;
370 }
371 else
372 {
373 /* Allocate a Capture Buffer */
374 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
375 if (CaptureBuffer == NULL)
376 {
377 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
378 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
379 return FALSE;
380 }
381
382 /* Allocate space in the Buffer */
383 CsrAllocateMessagePointer(CaptureBuffer,
384 SizeBytes,
385 (PVOID*)&ReadOutputCodeRequest->pCode);
386 }
387
388 /* Call the server */
389 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
390 CaptureBuffer,
391 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
392 sizeof(*ReadOutputCodeRequest));
393
394 /* Check for success */
395 Success = NT_SUCCESS(ApiMessage.Status);
396
397 /* Retrieve the results */
398 _SEH2_TRY
399 {
400 *lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
401
402 if (Success)
403 {
404 RtlCopyMemory(pCode,
405 ReadOutputCodeRequest->pCode,
406 ReadOutputCodeRequest->NumCodes * CodeSize);
407 }
408 else
409 {
410 BaseSetLastNTError(ApiMessage.Status);
411 }
412 }
413 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
414 {
415 SetLastError(ERROR_INVALID_ACCESS);
416 Success = FALSE;
417 }
418 _SEH2_END;
419
420 /* Release the capture buffer if needed */
421 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
422
423 /* Return success status */
424 return Success;
425 }
426
427
428 /*******************
429 * Write functions *
430 *******************/
431
432 static
433 BOOL
434 IntWriteConsole(HANDLE hConsoleOutput,
435 PVOID lpBuffer,
436 DWORD nNumberOfCharsToWrite,
437 LPDWORD lpNumberOfCharsWritten,
438 LPVOID lpReserved,
439 BOOL bUnicode)
440 {
441 BOOL bRet = TRUE;
442 CONSOLE_API_MESSAGE ApiMessage;
443 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
444 PCSR_CAPTURE_BUFFER CaptureBuffer;
445 ULONG CharSize;
446
447 /* Determine the needed size */
448 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
449 WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize;
450
451 /* Allocate a Capture Buffer */
452 CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleRequest->BufferSize);
453 if (CaptureBuffer == NULL)
454 {
455 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
456 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
457 return FALSE;
458 }
459
460 /* Capture the buffer to write */
461 CsrCaptureMessageBuffer(CaptureBuffer,
462 (PVOID)lpBuffer,
463 WriteConsoleRequest->BufferSize,
464 (PVOID*)&WriteConsoleRequest->Buffer);
465
466 /* Start writing */
467 WriteConsoleRequest->NrCharactersToWrite = nNumberOfCharsToWrite;
468 WriteConsoleRequest->OutputHandle = hConsoleOutput;
469 WriteConsoleRequest->Unicode = bUnicode;
470
471 /* Call the server */
472 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
473 CaptureBuffer,
474 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
475 sizeof(*WriteConsoleRequest));
476
477 /* Check for success */
478 if (NT_SUCCESS(ApiMessage.Status))
479 {
480 if (lpNumberOfCharsWritten != NULL)
481 *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
482
483 bRet = TRUE;
484 }
485 else
486 {
487 if (lpNumberOfCharsWritten != NULL)
488 *lpNumberOfCharsWritten = 0;
489
490 /* Error out */
491 BaseSetLastNTError(ApiMessage.Status);
492 bRet = FALSE;
493 }
494
495 CsrFreeCaptureBuffer(CaptureBuffer);
496
497 return bRet;
498 }
499
500
501 static
502 BOOL
503 IntWriteConsoleInput(IN HANDLE hConsoleInput,
504 IN PINPUT_RECORD lpBuffer,
505 IN DWORD nLength,
506 OUT LPDWORD lpNumberOfEventsWritten,
507 IN BOOLEAN bUnicode,
508 IN BOOLEAN bAppendToEnd)
509 {
510 BOOL Success;
511 CONSOLE_API_MESSAGE ApiMessage;
512 PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
513 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
514
515 DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
516
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;
523
524 /*
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.
529 */
530 if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
531 {
532 WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
533 // CaptureBuffer = NULL;
534
535 _SEH2_TRY
536 {
537 RtlCopyMemory(WriteInputRequest->RecordBufPtr,
538 lpBuffer,
539 nLength * sizeof(INPUT_RECORD));
540 }
541 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
542 {
543 SetLastError(ERROR_INVALID_ACCESS);
544 return FALSE;
545 }
546 _SEH2_END;
547 }
548 else
549 {
550 ULONG Size = nLength * sizeof(INPUT_RECORD);
551
552 /* Allocate a Capture Buffer */
553 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
554 if (CaptureBuffer == NULL)
555 {
556 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
557 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
558 return FALSE;
559 }
560
561 /* Capture the user buffer */
562 CsrCaptureMessageBuffer(CaptureBuffer,
563 lpBuffer,
564 Size,
565 (PVOID*)&WriteInputRequest->RecordBufPtr);
566 }
567
568 /* Call the server */
569 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
570 CaptureBuffer,
571 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
572 sizeof(*WriteInputRequest));
573
574 /* Check for success */
575 Success = NT_SUCCESS(ApiMessage.Status);
576
577 /* Release the capture buffer if needed */
578 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
579
580 /* Retrieve the results */
581 _SEH2_TRY
582 {
583 DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
584 *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
585
586 if (!Success)
587 BaseSetLastNTError(ApiMessage.Status);
588 }
589 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
590 {
591 SetLastError(ERROR_INVALID_ACCESS);
592 Success = FALSE;
593 }
594 _SEH2_END;
595
596 /* Return success status */
597 return Success;
598 }
599
600
601 static
602 BOOL
603 IntWriteConsoleOutput(HANDLE hConsoleOutput,
604 CONST CHAR_INFO *lpBuffer,
605 COORD dwBufferSize,
606 COORD dwBufferCoord,
607 PSMALL_RECT lpWriteRegion,
608 BOOL bUnicode)
609 {
610 CONSOLE_API_MESSAGE ApiMessage;
611 PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
612 PCSR_CAPTURE_BUFFER CaptureBuffer;
613 ULONG Size;
614
615 if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
616 {
617 SetLastError(ERROR_INVALID_ACCESS);
618 return FALSE;
619 }
620 /*
621 if (lpWriteRegion == NULL)
622 {
623 SetLastError(ERROR_INVALID_PARAMETER);
624 return FALSE;
625 }
626 */
627
628 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
629
630 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
631
632 /* Allocate a Capture Buffer */
633 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
634 if (CaptureBuffer == NULL)
635 {
636 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
637 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
638 return FALSE;
639 }
640
641 /* Capture the user buffer */
642 CsrCaptureMessageBuffer(CaptureBuffer,
643 (PVOID)lpBuffer,
644 Size,
645 (PVOID*)&WriteOutputRequest->CharInfo);
646
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;
653
654 /* Call the server */
655 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
656 CaptureBuffer,
657 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
658 sizeof(*WriteOutputRequest));
659
660 /* Check for success */
661 if (!NT_SUCCESS(ApiMessage.Status))
662 {
663 /* Error out */
664 BaseSetLastNTError(ApiMessage.Status);
665 }
666
667 /* Return the read region */
668 DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
669 *lpWriteRegion = WriteOutputRequest->WriteRegion;
670
671 /* Release the capture buffer */
672 CsrFreeCaptureBuffer(CaptureBuffer);
673
674 /* Return TRUE or FALSE */
675 return NT_SUCCESS(ApiMessage.Status);
676 }
677
678
679 static
680 BOOL
681 IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput,
682 IN CODE_TYPE CodeType,
683 IN CONST VOID *pCode,
684 IN DWORD nLength,
685 IN COORD dwWriteCoord,
686 OUT LPDWORD lpNumberOfCodesWritten)
687 {
688 BOOL Success;
689 CONSOLE_API_MESSAGE ApiMessage;
690 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
691 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
692 ULONG SizeBytes, CodeSize;
693
694 if ( (CodeType != CODE_ASCII ) &&
695 (CodeType != CODE_UNICODE ) &&
696 (CodeType != CODE_ATTRIBUTE) )
697 {
698 SetLastError(ERROR_INVALID_PARAMETER);
699 return FALSE;
700 }
701
702 DPRINT("IntWriteConsoleOutputCode\n");
703
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;
709
710 /* Determine the needed size */
711 WriteOutputCodeRequest->CodeType = CodeType;
712 switch (CodeType)
713 {
714 case CODE_ASCII:
715 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
716 break;
717
718 case CODE_UNICODE:
719 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
720 break;
721
722 case CODE_ATTRIBUTE:
723 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
724 break;
725 }
726 SizeBytes = nLength * CodeSize;
727
728 /*
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.
733 */
734 if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
735 {
736 WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
737 // CaptureBuffer = NULL;
738
739 _SEH2_TRY
740 {
741 RtlCopyMemory(WriteOutputCodeRequest->pCode,
742 pCode,
743 SizeBytes);
744 }
745 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
746 {
747 SetLastError(ERROR_INVALID_ACCESS);
748 return FALSE;
749 }
750 _SEH2_END;
751 }
752 else
753 {
754 /* Allocate a Capture Buffer */
755 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
756 if (CaptureBuffer == NULL)
757 {
758 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
759 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
760 return FALSE;
761 }
762
763 /* Capture the buffer to write */
764 CsrCaptureMessageBuffer(CaptureBuffer,
765 (PVOID)pCode,
766 SizeBytes,
767 (PVOID*)&WriteOutputCodeRequest->pCode);
768 }
769
770 /* Call the server */
771 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
772 CaptureBuffer,
773 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
774 sizeof(*WriteOutputCodeRequest));
775
776 /* Check for success */
777 Success = NT_SUCCESS(ApiMessage.Status);
778
779 /* Release the capture buffer if needed */
780 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
781
782 /* Retrieve the results */
783 _SEH2_TRY
784 {
785 *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
786
787 if (!Success)
788 BaseSetLastNTError(ApiMessage.Status);
789 }
790 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
791 {
792 SetLastError(ERROR_INVALID_ACCESS);
793 Success = FALSE;
794 }
795 _SEH2_END;
796
797 /* Return success status */
798 return Success;
799 }
800
801
802 static
803 BOOL
804 IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
805 IN CODE_TYPE CodeType,
806 IN CODE_ELEMENT Code,
807 IN DWORD nLength,
808 IN COORD dwWriteCoord,
809 OUT LPDWORD lpNumberOfCodesWritten)
810 {
811 BOOL Success;
812 CONSOLE_API_MESSAGE ApiMessage;
813 PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
814
815 DPRINT("IntFillConsoleOutputCode\n");
816
817 if ( (CodeType != CODE_ASCII ) &&
818 (CodeType != CODE_UNICODE ) &&
819 (CodeType != CODE_ATTRIBUTE) )
820 {
821 SetLastError(ERROR_INVALID_PARAMETER);
822 return FALSE;
823 }
824
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;
832
833 /* Call the server */
834 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
835 NULL,
836 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
837 sizeof(*FillOutputRequest));
838
839 /* Check for success */
840 Success = NT_SUCCESS(ApiMessage.Status);
841
842 /* Retrieve the results */
843 _SEH2_TRY
844 {
845 *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
846
847 if (!Success)
848 BaseSetLastNTError(ApiMessage.Status);
849 }
850 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
851 {
852 SetLastError(ERROR_INVALID_ACCESS);
853 Success = FALSE;
854 }
855 _SEH2_END;
856
857 /* Return success status */
858 return Success;
859 }
860
861
862 /* FUNCTIONS ******************************************************************/
863
864 /******************
865 * Read functions *
866 ******************/
867
868 /*--------------------------------------------------------------
869 * ReadConsoleW
870 *
871 * @implemented
872 */
873 BOOL
874 WINAPI
875 ReadConsoleW(HANDLE hConsoleInput,
876 LPVOID lpBuffer,
877 DWORD nNumberOfCharsToRead,
878 LPDWORD lpNumberOfCharsRead,
879 PCONSOLE_READCONSOLE_CONTROL pInputControl)
880 {
881 return IntReadConsole(hConsoleInput,
882 lpBuffer,
883 nNumberOfCharsToRead,
884 lpNumberOfCharsRead,
885 pInputControl,
886 TRUE);
887 }
888
889
890 /*--------------------------------------------------------------
891 * ReadConsoleA
892 *
893 * @implemented
894 */
895 BOOL
896 WINAPI
897 ReadConsoleA(HANDLE hConsoleInput,
898 LPVOID lpBuffer,
899 DWORD nNumberOfCharsToRead,
900 LPDWORD lpNumberOfCharsRead,
901 PCONSOLE_READCONSOLE_CONTROL pInputControl)
902 {
903 return IntReadConsole(hConsoleInput,
904 lpBuffer,
905 nNumberOfCharsToRead,
906 lpNumberOfCharsRead,
907 NULL,
908 FALSE);
909 }
910
911
912 /*--------------------------------------------------------------
913 * PeekConsoleInputW
914 *
915 * @implemented
916 */
917 BOOL
918 WINAPI
919 PeekConsoleInputW(IN HANDLE hConsoleInput,
920 OUT PINPUT_RECORD lpBuffer,
921 IN DWORD nLength,
922 OUT LPDWORD lpNumberOfEventsRead)
923 {
924 return IntGetConsoleInput(hConsoleInput,
925 lpBuffer,
926 nLength,
927 lpNumberOfEventsRead,
928 CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
929 TRUE);
930 }
931
932
933 /*--------------------------------------------------------------
934 * PeekConsoleInputA
935 *
936 * @implemented
937 */
938 BOOL
939 WINAPI
940 PeekConsoleInputA(IN HANDLE hConsoleInput,
941 OUT PINPUT_RECORD lpBuffer,
942 IN DWORD nLength,
943 OUT LPDWORD lpNumberOfEventsRead)
944 {
945 return IntGetConsoleInput(hConsoleInput,
946 lpBuffer,
947 nLength,
948 lpNumberOfEventsRead,
949 CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
950 FALSE);
951 }
952
953
954 /*--------------------------------------------------------------
955 * ReadConsoleInputW
956 *
957 * @implemented
958 */
959 BOOL
960 WINAPI
961 ReadConsoleInputW(IN HANDLE hConsoleInput,
962 OUT PINPUT_RECORD lpBuffer,
963 IN DWORD nLength,
964 OUT LPDWORD lpNumberOfEventsRead)
965 {
966 return IntGetConsoleInput(hConsoleInput,
967 lpBuffer,
968 nLength,
969 lpNumberOfEventsRead,
970 0,
971 TRUE);
972 }
973
974
975 /*--------------------------------------------------------------
976 * ReadConsoleInputA
977 *
978 * @implemented
979 */
980 BOOL
981 WINAPI
982 ReadConsoleInputA(IN HANDLE hConsoleInput,
983 OUT PINPUT_RECORD lpBuffer,
984 IN DWORD nLength,
985 OUT LPDWORD lpNumberOfEventsRead)
986 {
987 return IntGetConsoleInput(hConsoleInput,
988 lpBuffer,
989 nLength,
990 lpNumberOfEventsRead,
991 0,
992 FALSE);
993 }
994
995
996 /*--------------------------------------------------------------
997 * ReadConsoleInputExW
998 *
999 * @implemented
1000 */
1001 BOOL
1002 WINAPI
1003 ReadConsoleInputExW(IN HANDLE hConsoleInput,
1004 OUT PINPUT_RECORD lpBuffer,
1005 IN DWORD nLength,
1006 OUT LPDWORD lpNumberOfEventsRead,
1007 IN WORD wFlags)
1008 {
1009 return IntGetConsoleInput(hConsoleInput,
1010 lpBuffer,
1011 nLength,
1012 lpNumberOfEventsRead,
1013 wFlags,
1014 TRUE);
1015 }
1016
1017
1018 /*--------------------------------------------------------------
1019 * ReadConsoleInputExA
1020 *
1021 * @implemented
1022 */
1023 BOOL
1024 WINAPI
1025 ReadConsoleInputExA(IN HANDLE hConsoleInput,
1026 OUT PINPUT_RECORD lpBuffer,
1027 IN DWORD nLength,
1028 OUT LPDWORD lpNumberOfEventsRead,
1029 IN WORD wFlags)
1030 {
1031 return IntGetConsoleInput(hConsoleInput,
1032 lpBuffer,
1033 nLength,
1034 lpNumberOfEventsRead,
1035 wFlags,
1036 FALSE);
1037 }
1038
1039
1040 /*--------------------------------------------------------------
1041 * ReadConsoleOutputW
1042 *
1043 * @implemented
1044 */
1045 BOOL
1046 WINAPI
1047 ReadConsoleOutputW(HANDLE hConsoleOutput,
1048 PCHAR_INFO lpBuffer,
1049 COORD dwBufferSize,
1050 COORD dwBufferCoord,
1051 PSMALL_RECT lpReadRegion)
1052 {
1053 return IntReadConsoleOutput(hConsoleOutput,
1054 lpBuffer,
1055 dwBufferSize,
1056 dwBufferCoord,
1057 lpReadRegion,
1058 TRUE);
1059 }
1060
1061
1062 /*--------------------------------------------------------------
1063 * ReadConsoleOutputA
1064 *
1065 * @implemented
1066 */
1067 BOOL
1068 WINAPI
1069 ReadConsoleOutputA(HANDLE hConsoleOutput,
1070 PCHAR_INFO lpBuffer,
1071 COORD dwBufferSize,
1072 COORD dwBufferCoord,
1073 PSMALL_RECT lpReadRegion)
1074 {
1075 return IntReadConsoleOutput(hConsoleOutput,
1076 lpBuffer,
1077 dwBufferSize,
1078 dwBufferCoord,
1079 lpReadRegion,
1080 FALSE);
1081 }
1082
1083
1084 /*--------------------------------------------------------------
1085 * ReadConsoleOutputCharacterW
1086 *
1087 * @implemented
1088 */
1089 BOOL
1090 WINAPI
1091 ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1092 OUT LPWSTR lpCharacter,
1093 IN DWORD nLength,
1094 IN COORD dwReadCoord,
1095 OUT LPDWORD lpNumberOfCharsRead)
1096 {
1097 return IntReadConsoleOutputCode(hConsoleOutput,
1098 CODE_UNICODE,
1099 lpCharacter,
1100 nLength,
1101 dwReadCoord,
1102 lpNumberOfCharsRead);
1103 }
1104
1105
1106 /*--------------------------------------------------------------
1107 * ReadConsoleOutputCharacterA
1108 *
1109 * @implemented
1110 */
1111 BOOL
1112 WINAPI
1113 ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1114 OUT LPSTR lpCharacter,
1115 IN DWORD nLength,
1116 IN COORD dwReadCoord,
1117 OUT LPDWORD lpNumberOfCharsRead)
1118 {
1119 return IntReadConsoleOutputCode(hConsoleOutput,
1120 CODE_ASCII,
1121 lpCharacter,
1122 nLength,
1123 dwReadCoord,
1124 lpNumberOfCharsRead);
1125 }
1126
1127
1128 /*--------------------------------------------------------------
1129 * ReadConsoleOutputAttribute
1130 *
1131 * @implemented
1132 */
1133 BOOL
1134 WINAPI
1135 ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1136 OUT LPWORD lpAttribute,
1137 IN DWORD nLength,
1138 IN COORD dwReadCoord,
1139 OUT LPDWORD lpNumberOfAttrsRead)
1140 {
1141 return IntReadConsoleOutputCode(hConsoleOutput,
1142 CODE_ATTRIBUTE,
1143 lpAttribute,
1144 nLength,
1145 dwReadCoord,
1146 lpNumberOfAttrsRead);
1147 }
1148
1149
1150 /*******************
1151 * Write functions *
1152 *******************/
1153
1154 /*--------------------------------------------------------------
1155 * WriteConsoleW
1156 *
1157 * @implemented
1158 */
1159 BOOL
1160 WINAPI
1161 WriteConsoleW(HANDLE hConsoleOutput,
1162 CONST VOID *lpBuffer,
1163 DWORD nNumberOfCharsToWrite,
1164 LPDWORD lpNumberOfCharsWritten,
1165 LPVOID lpReserved)
1166 {
1167 return IntWriteConsole(hConsoleOutput,
1168 (PVOID)lpBuffer,
1169 nNumberOfCharsToWrite,
1170 lpNumberOfCharsWritten,
1171 lpReserved,
1172 TRUE);
1173 }
1174
1175
1176 /*--------------------------------------------------------------
1177 * WriteConsoleA
1178 *
1179 * @implemented
1180 */
1181 BOOL
1182 WINAPI
1183 WriteConsoleA(HANDLE hConsoleOutput,
1184 CONST VOID *lpBuffer,
1185 DWORD nNumberOfCharsToWrite,
1186 LPDWORD lpNumberOfCharsWritten,
1187 LPVOID lpReserved)
1188 {
1189 return IntWriteConsole(hConsoleOutput,
1190 (PVOID)lpBuffer,
1191 nNumberOfCharsToWrite,
1192 lpNumberOfCharsWritten,
1193 lpReserved,
1194 FALSE);
1195 }
1196
1197
1198 /*--------------------------------------------------------------
1199 * WriteConsoleInputW
1200 *
1201 * @implemented
1202 */
1203 BOOL
1204 WINAPI
1205 WriteConsoleInputW(IN HANDLE hConsoleInput,
1206 IN CONST INPUT_RECORD *lpBuffer,
1207 IN DWORD nLength,
1208 OUT LPDWORD lpNumberOfEventsWritten)
1209 {
1210 return IntWriteConsoleInput(hConsoleInput,
1211 (PINPUT_RECORD)lpBuffer,
1212 nLength,
1213 lpNumberOfEventsWritten,
1214 TRUE,
1215 TRUE);
1216 }
1217
1218
1219 /*--------------------------------------------------------------
1220 * WriteConsoleInputA
1221 *
1222 * @implemented
1223 */
1224 BOOL
1225 WINAPI
1226 WriteConsoleInputA(IN HANDLE hConsoleInput,
1227 IN CONST INPUT_RECORD *lpBuffer,
1228 IN DWORD nLength,
1229 OUT LPDWORD lpNumberOfEventsWritten)
1230 {
1231 return IntWriteConsoleInput(hConsoleInput,
1232 (PINPUT_RECORD)lpBuffer,
1233 nLength,
1234 lpNumberOfEventsWritten,
1235 FALSE,
1236 TRUE);
1237 }
1238
1239
1240 /*--------------------------------------------------------------
1241 * WriteConsoleInputVDMW
1242 *
1243 * @implemented
1244 */
1245 BOOL
1246 WINAPI
1247 WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
1248 IN CONST INPUT_RECORD *lpBuffer,
1249 IN DWORD nLength,
1250 OUT LPDWORD lpNumberOfEventsWritten)
1251 {
1252 return IntWriteConsoleInput(hConsoleInput,
1253 (PINPUT_RECORD)lpBuffer,
1254 nLength,
1255 lpNumberOfEventsWritten,
1256 TRUE,
1257 FALSE);
1258 }
1259
1260
1261 /*--------------------------------------------------------------
1262 * WriteConsoleInputVDMA
1263 *
1264 * @implemented
1265 */
1266 BOOL
1267 WINAPI
1268 WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
1269 IN CONST INPUT_RECORD *lpBuffer,
1270 IN DWORD nLength,
1271 OUT LPDWORD lpNumberOfEventsWritten)
1272 {
1273 return IntWriteConsoleInput(hConsoleInput,
1274 (PINPUT_RECORD)lpBuffer,
1275 nLength,
1276 lpNumberOfEventsWritten,
1277 FALSE,
1278 FALSE);
1279 }
1280
1281
1282 /*--------------------------------------------------------------
1283 * WriteConsoleOutputW
1284 *
1285 * @implemented
1286 */
1287 BOOL
1288 WINAPI
1289 WriteConsoleOutputW(HANDLE hConsoleOutput,
1290 CONST CHAR_INFO *lpBuffer,
1291 COORD dwBufferSize,
1292 COORD dwBufferCoord,
1293 PSMALL_RECT lpWriteRegion)
1294 {
1295 return IntWriteConsoleOutput(hConsoleOutput,
1296 lpBuffer,
1297 dwBufferSize,
1298 dwBufferCoord,
1299 lpWriteRegion,
1300 TRUE);
1301 }
1302
1303
1304 /*--------------------------------------------------------------
1305 * WriteConsoleOutputA
1306 *
1307 * @implemented
1308 */
1309 BOOL
1310 WINAPI
1311 WriteConsoleOutputA(HANDLE hConsoleOutput,
1312 CONST CHAR_INFO *lpBuffer,
1313 COORD dwBufferSize,
1314 COORD dwBufferCoord,
1315 PSMALL_RECT lpWriteRegion)
1316 {
1317 return IntWriteConsoleOutput(hConsoleOutput,
1318 lpBuffer,
1319 dwBufferSize,
1320 dwBufferCoord,
1321 lpWriteRegion,
1322 FALSE);
1323 }
1324
1325
1326 /*--------------------------------------------------------------
1327 * WriteConsoleOutputCharacterW
1328 *
1329 * @implemented
1330 */
1331 BOOL
1332 WINAPI
1333 WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1334 IN LPCWSTR lpCharacter,
1335 IN DWORD nLength,
1336 IN COORD dwWriteCoord,
1337 OUT LPDWORD lpNumberOfCharsWritten)
1338 {
1339 return IntWriteConsoleOutputCode(hConsoleOutput,
1340 CODE_UNICODE,
1341 lpCharacter,
1342 nLength,
1343 dwWriteCoord,
1344 lpNumberOfCharsWritten);
1345 }
1346
1347
1348 /*--------------------------------------------------------------
1349 * WriteConsoleOutputCharacterA
1350 *
1351 * @implemented
1352 */
1353 BOOL
1354 WINAPI
1355 WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1356 IN LPCSTR lpCharacter,
1357 IN DWORD nLength,
1358 IN COORD dwWriteCoord,
1359 OUT LPDWORD lpNumberOfCharsWritten)
1360 {
1361 return IntWriteConsoleOutputCode(hConsoleOutput,
1362 CODE_ASCII,
1363 lpCharacter,
1364 nLength,
1365 dwWriteCoord,
1366 lpNumberOfCharsWritten);
1367 }
1368
1369
1370 /*--------------------------------------------------------------
1371 * WriteConsoleOutputAttribute
1372 *
1373 * @implemented
1374 */
1375 BOOL
1376 WINAPI
1377 WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1378 IN CONST WORD *lpAttribute,
1379 IN DWORD nLength,
1380 IN COORD dwWriteCoord,
1381 OUT LPDWORD lpNumberOfAttrsWritten)
1382 {
1383 return IntWriteConsoleOutputCode(hConsoleOutput,
1384 CODE_ATTRIBUTE,
1385 lpAttribute,
1386 nLength,
1387 dwWriteCoord,
1388 lpNumberOfAttrsWritten);
1389 }
1390
1391
1392 /*--------------------------------------------------------------
1393 * FillConsoleOutputCharacterW
1394 *
1395 * @implemented
1396 */
1397 BOOL
1398 WINAPI
1399 FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1400 IN WCHAR cCharacter,
1401 IN DWORD nLength,
1402 IN COORD dwWriteCoord,
1403 OUT LPDWORD lpNumberOfCharsWritten)
1404 {
1405 CODE_ELEMENT Code;
1406 Code.UnicodeChar = cCharacter;
1407 return IntFillConsoleOutputCode(hConsoleOutput,
1408 CODE_UNICODE,
1409 Code,
1410 nLength,
1411 dwWriteCoord,
1412 lpNumberOfCharsWritten);
1413 }
1414
1415
1416 /*--------------------------------------------------------------
1417 * FillConsoleOutputCharacterA
1418 *
1419 * @implemented
1420 */
1421 BOOL
1422 WINAPI
1423 FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1424 IN CHAR cCharacter,
1425 IN DWORD nLength,
1426 IN COORD dwWriteCoord,
1427 LPDWORD lpNumberOfCharsWritten)
1428 {
1429 CODE_ELEMENT Code;
1430 Code.AsciiChar = cCharacter;
1431 return IntFillConsoleOutputCode(hConsoleOutput,
1432 CODE_ASCII,
1433 Code,
1434 nLength,
1435 dwWriteCoord,
1436 lpNumberOfCharsWritten);
1437 }
1438
1439
1440 /*--------------------------------------------------------------
1441 * FillConsoleOutputAttribute
1442 *
1443 * @implemented
1444 */
1445 BOOL
1446 WINAPI
1447 FillConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1448 IN WORD wAttribute,
1449 IN DWORD nLength,
1450 IN COORD dwWriteCoord,
1451 OUT LPDWORD lpNumberOfAttrsWritten)
1452 {
1453 CODE_ELEMENT Code;
1454 Code.Attribute = wAttribute;
1455 return IntFillConsoleOutputCode(hConsoleOutput,
1456 CODE_ATTRIBUTE,
1457 Code,
1458 nLength,
1459 dwWriteCoord,
1460 lpNumberOfAttrsWritten);
1461 }
1462
1463 /* EOF */