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