[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 DWORD
28 WINAPI
29 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer);
30
31 static
32 BOOL
33 IntReadConsole(IN HANDLE hConsoleInput,
34 OUT PVOID lpBuffer,
35 IN DWORD nNumberOfCharsToRead,
36 OUT LPDWORD lpNumberOfCharsRead,
37 IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL,
38 IN BOOLEAN bUnicode)
39 {
40 BOOL Success;
41 CONSOLE_API_MESSAGE ApiMessage;
42 PCONSOLE_READCONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
43 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
44 ULONG CharSize, SizeBytes;
45
46 DPRINT("IntReadConsole\n");
47
48 /* Set up the data to send to the Console Server */
49 ReadConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
50 ReadConsoleRequest->InputHandle = hConsoleInput;
51 ReadConsoleRequest->Unicode = bUnicode;
52
53 /*
54 * Retrieve the current console executable name string and length (always
55 * in UNICODE format).
56 * FIXME: Do not use GetConsoleInputExeNameW but use something else...
57 */
58 // 1- Get the exe name length in characters, including NULL character.
59 ReadConsoleRequest->ExeLength =
60 GetConsoleInputExeNameW(0, (PWCHAR)ReadConsoleRequest->StaticBuffer);
61 // 2- Get the exe name (GetConsoleInputExeNameW returns 1 in case of success).
62 if (GetConsoleInputExeNameW(ReadConsoleRequest->ExeLength,
63 (PWCHAR)ReadConsoleRequest->StaticBuffer) != 1)
64 {
65 // Nothing
66 ReadConsoleRequest->ExeLength = 0;
67 }
68 else
69 {
70 // Remove the NULL character, and convert in number of bytes.
71 ReadConsoleRequest->ExeLength--;
72 ReadConsoleRequest->ExeLength *= sizeof(WCHAR);
73 }
74
75 /*** For DEBUGGING purposes ***/
76 {
77 UNICODE_STRING ExeName;
78 ExeName.Length = ExeName.MaximumLength = ReadConsoleRequest->ExeLength;
79 ExeName.Buffer = (PWCHAR)ReadConsoleRequest->StaticBuffer;
80 DPRINT1("IntReadConsole(ExeName = %wZ)\n", &ExeName);
81 }
82 /******************************/
83
84 /* Determine the needed size */
85 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
86 SizeBytes = nNumberOfCharsToRead * CharSize;
87
88 ReadConsoleRequest->CaptureBufferSize =
89 ReadConsoleRequest->NumBytes = SizeBytes;
90
91 /*
92 * For optimization purposes, Windows (and hence ReactOS, too, for
93 * compatibility reasons) uses a static buffer if no more than eighty
94 * bytes are read. Otherwise a new buffer is allocated.
95 * This behaviour is also expected in the server-side.
96 */
97 if (SizeBytes <= sizeof(ReadConsoleRequest->StaticBuffer))
98 {
99 ReadConsoleRequest->Buffer = ReadConsoleRequest->StaticBuffer;
100 // CaptureBuffer = NULL;
101 }
102 else
103 {
104 /* Allocate a Capture Buffer */
105 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
106 if (CaptureBuffer == NULL)
107 {
108 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
109 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
110 return FALSE;
111 }
112
113 /* Allocate space in the Buffer */
114 CsrAllocateMessagePointer(CaptureBuffer,
115 SizeBytes,
116 (PVOID*)&ReadConsoleRequest->Buffer);
117 }
118
119 ReadConsoleRequest->InitialNumBytes = 0;
120 ReadConsoleRequest->CtrlWakeupMask = 0;
121 ReadConsoleRequest->ControlKeyState = 0;
122
123 /*
124 * From MSDN (ReadConsole function), the description
125 * for pInputControl says:
126 * "This parameter requires Unicode input by default.
127 * For ANSI mode, set this parameter to NULL."
128 */
129 _SEH2_TRY
130 {
131 if (bUnicode && pInputControl &&
132 pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
133 {
134 /* Sanity check */
135 if (pInputControl->nInitialChars <= nNumberOfCharsToRead)
136 {
137 ReadConsoleRequest->InitialNumBytes =
138 pInputControl->nInitialChars * sizeof(WCHAR); // CharSize
139
140 if (pInputControl->nInitialChars != 0)
141 {
142 /*
143 * It is possible here to overwrite the static buffer, in case
144 * the number of bytes to read was smaller than the static buffer.
145 * In this case, this means we are continuing a pending read,
146 * and we do not need in fact the executable name that was
147 * stored in the static buffer because it was first grabbed when
148 * we started the first read.
149 */
150 RtlCopyMemory(ReadConsoleRequest->Buffer,
151 lpBuffer,
152 ReadConsoleRequest->InitialNumBytes);
153 }
154
155 ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
156 }
157 else
158 {
159 // Status = STATUS_INVALID_PARAMETER;
160 }
161 }
162 else
163 {
164 /* We are in a situation where pInputControl has no meaning */
165 pInputControl = NULL;
166 }
167 }
168 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
169 {
170 // HACK
171 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
172 SetLastError(ERROR_INVALID_ACCESS);
173 return FALSE;
174 }
175 _SEH2_END;
176
177 /* Check for sanity */
178 /*
179 if (!NT_SUCCESS(Status) && pInputControl)
180 {
181 // Free CaptureBuffer if needed
182 // Set last error to last status
183 // Return FALSE
184 }
185 */
186
187 /* Call the server */
188 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
189 CaptureBuffer,
190 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
191 sizeof(*ReadConsoleRequest));
192
193 /* Check for success */
194 Success = NT_SUCCESS(ApiMessage.Status);
195
196 /* Retrieve the results */
197 if (Success)
198 {
199 _SEH2_TRY
200 {
201 *lpNumberOfCharsRead = ReadConsoleRequest->NumBytes / CharSize;
202
203 if (bUnicode && pInputControl)
204 pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
205
206 RtlCopyMemory(lpBuffer,
207 ReadConsoleRequest->Buffer,
208 ReadConsoleRequest->NumBytes);
209 }
210 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
211 {
212 SetLastError(ERROR_INVALID_ACCESS);
213 Success = FALSE;
214 }
215 _SEH2_END;
216 }
217 else
218 {
219 BaseSetLastNTError(ApiMessage.Status);
220 }
221
222 /* Release the capture buffer if needed */
223 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
224
225 if (Success)
226 {
227 /* Yield execution to another thread if Ctrl-C or Ctrl-Break happened */
228 if (ApiMessage.Status == STATUS_ALERTED /* || ApiMessage.Status == STATUS_CANCELLED */)
229 {
230 NtYieldExecution();
231 SetLastError(ERROR_OPERATION_ABORTED); // STATUS_CANCELLED
232 }
233 }
234
235 /* Return success status */
236 return Success;
237 }
238
239
240 static
241 BOOL
242 IntGetConsoleInput(IN HANDLE hConsoleInput,
243 OUT PINPUT_RECORD lpBuffer,
244 IN DWORD nLength,
245 OUT LPDWORD lpNumberOfEventsRead,
246 IN WORD wFlags,
247 IN BOOLEAN bUnicode)
248 {
249 BOOL Success;
250 CONSOLE_API_MESSAGE ApiMessage;
251 PCONSOLE_GETINPUT GetInputRequest = &ApiMessage.Data.GetInputRequest;
252 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
253
254 if (!IsConsoleHandle(hConsoleInput))
255 {
256 _SEH2_TRY
257 {
258 *lpNumberOfEventsRead = 0;
259 SetLastError(ERROR_INVALID_HANDLE);
260 }
261 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
262 {
263 SetLastError(ERROR_INVALID_ACCESS);
264 }
265 _SEH2_END;
266
267 return FALSE;
268 }
269
270 DPRINT("IntGetConsoleInput: %lx %p\n", nLength, lpNumberOfEventsRead);
271
272 /* Set up the data to send to the Console Server */
273 GetInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
274 GetInputRequest->InputHandle = hConsoleInput;
275 GetInputRequest->NumRecords = nLength;
276 GetInputRequest->Flags = wFlags;
277 GetInputRequest->Unicode = bUnicode;
278
279 /*
280 * For optimization purposes, Windows (and hence ReactOS, too, for
281 * compatibility reasons) uses a static buffer if no more than five
282 * input records are read. Otherwise a new buffer is allocated.
283 * This behaviour is also expected in the server-side.
284 */
285 if (nLength <= sizeof(GetInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
286 {
287 GetInputRequest->RecordBufPtr = GetInputRequest->RecordStaticBuffer;
288 // CaptureBuffer = NULL;
289 }
290 else
291 {
292 ULONG Size = nLength * sizeof(INPUT_RECORD);
293
294 /* Allocate a Capture Buffer */
295 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
296 if (CaptureBuffer == NULL)
297 {
298 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
299 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
300 return FALSE;
301 }
302
303 /* Allocate space in the Buffer */
304 CsrAllocateMessagePointer(CaptureBuffer,
305 Size,
306 (PVOID*)&GetInputRequest->RecordBufPtr);
307 }
308
309 /* Call the server */
310 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
311 CaptureBuffer,
312 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
313 sizeof(*GetInputRequest));
314
315 /* Check for success */
316 Success = NT_SUCCESS(ApiMessage.Status);
317
318 /* Retrieve the results */
319 _SEH2_TRY
320 {
321 DPRINT("Events read: %lx\n", GetInputRequest->NumRecords);
322 *lpNumberOfEventsRead = GetInputRequest->NumRecords;
323
324 if (Success)
325 {
326 RtlCopyMemory(lpBuffer,
327 GetInputRequest->RecordBufPtr,
328 GetInputRequest->NumRecords * sizeof(INPUT_RECORD));
329 }
330 else
331 {
332 BaseSetLastNTError(ApiMessage.Status);
333 }
334 }
335 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
336 {
337 SetLastError(ERROR_INVALID_ACCESS);
338 Success = FALSE;
339 }
340 _SEH2_END;
341
342 /* Release the capture buffer if needed */
343 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
344
345 /* Return success status */
346 return Success;
347 }
348
349
350 static
351 BOOL
352 IntReadConsoleOutput(IN HANDLE hConsoleOutput,
353 OUT PCHAR_INFO lpBuffer,
354 IN COORD dwBufferSize,
355 IN COORD dwBufferCoord,
356 IN OUT PSMALL_RECT lpReadRegion,
357 IN BOOLEAN bUnicode)
358 {
359 CONSOLE_API_MESSAGE ApiMessage;
360 PCONSOLE_READOUTPUT ReadOutputRequest = &ApiMessage.Data.ReadOutputRequest;
361 PCSR_CAPTURE_BUFFER CaptureBuffer;
362 DWORD Size, SizeX, SizeY;
363
364 if (lpBuffer == NULL)
365 {
366 SetLastError(ERROR_INVALID_ACCESS);
367 return FALSE;
368 }
369
370 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
371
372 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
373
374 /* Allocate a Capture Buffer */
375 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
376 if (CaptureBuffer == NULL)
377 {
378 DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
379 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
380 return FALSE;
381 }
382
383 /* Allocate space in the Buffer */
384 CsrAllocateMessagePointer(CaptureBuffer,
385 Size,
386 (PVOID*)&ReadOutputRequest->CharInfo);
387
388 /* Set up the data to send to the Console Server */
389 ReadOutputRequest->OutputHandle = hConsoleOutput;
390 ReadOutputRequest->Unicode = bUnicode;
391 ReadOutputRequest->BufferSize = dwBufferSize;
392 ReadOutputRequest->BufferCoord = dwBufferCoord;
393 ReadOutputRequest->ReadRegion = *lpReadRegion;
394
395 /* Call the server */
396 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
397 CaptureBuffer,
398 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
399 sizeof(*ReadOutputRequest));
400
401 /* Check for success */
402 if (NT_SUCCESS(ApiMessage.Status))
403 {
404 /* Copy into the buffer */
405 DPRINT("Copying to buffer\n");
406 SizeX = ReadOutputRequest->ReadRegion.Right -
407 ReadOutputRequest->ReadRegion.Left + 1;
408 SizeY = ReadOutputRequest->ReadRegion.Bottom -
409 ReadOutputRequest->ReadRegion.Top + 1;
410 RtlCopyMemory(lpBuffer,
411 ReadOutputRequest->CharInfo,
412 sizeof(CHAR_INFO) * SizeX * SizeY);
413 }
414 else
415 {
416 BaseSetLastNTError(ApiMessage.Status);
417 }
418
419 /* Return the read region */
420 DPRINT("read region: %p\n", ReadOutputRequest->ReadRegion);
421 *lpReadRegion = ReadOutputRequest->ReadRegion;
422
423 /* Release the capture buffer */
424 CsrFreeCaptureBuffer(CaptureBuffer);
425
426 /* Return TRUE or FALSE */
427 return NT_SUCCESS(ApiMessage.Status);
428 }
429
430
431 static
432 BOOL
433 IntReadConsoleOutputCode(IN HANDLE hConsoleOutput,
434 IN CODE_TYPE CodeType,
435 OUT PVOID pCode,
436 IN DWORD nLength,
437 IN COORD dwReadCoord,
438 OUT LPDWORD lpNumberOfCodesRead)
439 {
440 BOOL Success;
441 CONSOLE_API_MESSAGE ApiMessage;
442 PCONSOLE_READOUTPUTCODE ReadOutputCodeRequest = &ApiMessage.Data.ReadOutputCodeRequest;
443 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
444 ULONG CodeSize, SizeBytes;
445
446 DPRINT("IntReadConsoleOutputCode\n");
447
448 if ( (CodeType != CODE_ASCII ) &&
449 (CodeType != CODE_UNICODE ) &&
450 (CodeType != CODE_ATTRIBUTE) )
451 {
452 SetLastError(ERROR_INVALID_PARAMETER);
453 return FALSE;
454 }
455
456 /* Set up the data to send to the Console Server */
457 ReadOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
458 ReadOutputCodeRequest->OutputHandle = hConsoleOutput;
459 ReadOutputCodeRequest->Coord = dwReadCoord;
460 ReadOutputCodeRequest->NumCodes = nLength;
461
462 /* Determine the needed size */
463 ReadOutputCodeRequest->CodeType = CodeType;
464 switch (CodeType)
465 {
466 case CODE_ASCII:
467 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
468 break;
469
470 case CODE_UNICODE:
471 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
472 break;
473
474 case CODE_ATTRIBUTE:
475 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
476 break;
477 }
478 SizeBytes = nLength * CodeSize;
479
480 /*
481 * For optimization purposes, Windows (and hence ReactOS, too, for
482 * compatibility reasons) uses a static buffer if no more than eighty
483 * bytes are read. Otherwise a new buffer is allocated.
484 * This behaviour is also expected in the server-side.
485 */
486 if (SizeBytes <= sizeof(ReadOutputCodeRequest->CodeStaticBuffer))
487 {
488 ReadOutputCodeRequest->pCode = ReadOutputCodeRequest->CodeStaticBuffer;
489 // CaptureBuffer = NULL;
490 }
491 else
492 {
493 /* Allocate a Capture Buffer */
494 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
495 if (CaptureBuffer == NULL)
496 {
497 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
498 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
499 return FALSE;
500 }
501
502 /* Allocate space in the Buffer */
503 CsrAllocateMessagePointer(CaptureBuffer,
504 SizeBytes,
505 (PVOID*)&ReadOutputCodeRequest->pCode);
506 }
507
508 /* Call the server */
509 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
510 CaptureBuffer,
511 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
512 sizeof(*ReadOutputCodeRequest));
513
514 /* Check for success */
515 Success = NT_SUCCESS(ApiMessage.Status);
516
517 /* Retrieve the results */
518 _SEH2_TRY
519 {
520 *lpNumberOfCodesRead = ReadOutputCodeRequest->NumCodes;
521
522 if (Success)
523 {
524 RtlCopyMemory(pCode,
525 ReadOutputCodeRequest->pCode,
526 ReadOutputCodeRequest->NumCodes * CodeSize);
527 }
528 else
529 {
530 BaseSetLastNTError(ApiMessage.Status);
531 }
532 }
533 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
534 {
535 SetLastError(ERROR_INVALID_ACCESS);
536 Success = FALSE;
537 }
538 _SEH2_END;
539
540 /* Release the capture buffer if needed */
541 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
542
543 /* Return success status */
544 return Success;
545 }
546
547
548 /*******************
549 * Write functions *
550 *******************/
551
552 static
553 BOOL
554 IntWriteConsole(IN HANDLE hConsoleOutput,
555 IN PVOID lpBuffer,
556 IN DWORD nNumberOfCharsToWrite,
557 OUT LPDWORD lpNumberOfCharsWritten,
558 LPVOID lpReserved,
559 IN BOOLEAN bUnicode)
560 {
561 BOOL Success;
562 CONSOLE_API_MESSAGE ApiMessage;
563 PCONSOLE_WRITECONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
564 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
565 ULONG CharSize, SizeBytes;
566
567 DPRINT("IntWriteConsole\n");
568
569 /* Set up the data to send to the Console Server */
570 WriteConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
571 WriteConsoleRequest->OutputHandle = hConsoleOutput;
572 WriteConsoleRequest->Unicode = bUnicode;
573
574 /* Those members are unused by the client, on Windows */
575 WriteConsoleRequest->Reserved1 = 0;
576 // WriteConsoleRequest->Reserved2 = {0};
577
578 /* Determine the needed size */
579 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
580 SizeBytes = nNumberOfCharsToWrite * CharSize;
581
582 WriteConsoleRequest->NumBytes = SizeBytes;
583
584 /*
585 * For optimization purposes, Windows (and hence ReactOS, too, for
586 * compatibility reasons) uses a static buffer if no more than eighty
587 * bytes are written. Otherwise a new buffer is allocated.
588 * This behaviour is also expected in the server-side.
589 */
590 if (SizeBytes <= sizeof(WriteConsoleRequest->StaticBuffer))
591 {
592 WriteConsoleRequest->Buffer = WriteConsoleRequest->StaticBuffer;
593 // CaptureBuffer = NULL;
594 WriteConsoleRequest->UsingStaticBuffer = TRUE;
595
596 _SEH2_TRY
597 {
598 RtlCopyMemory(WriteConsoleRequest->Buffer,
599 lpBuffer,
600 SizeBytes);
601 }
602 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
603 {
604 SetLastError(ERROR_INVALID_ACCESS);
605 return FALSE;
606 }
607 _SEH2_END;
608 }
609 else
610 {
611 /* Allocate a Capture Buffer */
612 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
613 if (CaptureBuffer == NULL)
614 {
615 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
616 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
617 return FALSE;
618 }
619
620 /* Capture the buffer to write */
621 CsrCaptureMessageBuffer(CaptureBuffer,
622 (PVOID)lpBuffer,
623 SizeBytes,
624 (PVOID*)&WriteConsoleRequest->Buffer);
625 WriteConsoleRequest->UsingStaticBuffer = FALSE;
626 }
627
628 /* Call the server */
629 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
630 CaptureBuffer,
631 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
632 sizeof(*WriteConsoleRequest));
633
634 /* Check for success */
635 Success = NT_SUCCESS(ApiMessage.Status);
636
637 /* Release the capture buffer if needed */
638 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
639
640 /* Retrieve the results */
641 if (Success)
642 {
643 _SEH2_TRY
644 {
645 *lpNumberOfCharsWritten = WriteConsoleRequest->NumBytes / CharSize;
646 }
647 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
648 {
649 SetLastError(ERROR_INVALID_ACCESS);
650 Success = FALSE;
651 }
652 _SEH2_END;
653 }
654 else
655 {
656 BaseSetLastNTError(ApiMessage.Status);
657 }
658
659 /* Return success status */
660 return Success;
661 }
662
663
664 static
665 BOOL
666 IntWriteConsoleInput(IN HANDLE hConsoleInput,
667 IN PINPUT_RECORD lpBuffer,
668 IN DWORD nLength,
669 OUT LPDWORD lpNumberOfEventsWritten,
670 IN BOOLEAN bUnicode,
671 IN BOOLEAN bAppendToEnd)
672 {
673 BOOL Success;
674 CONSOLE_API_MESSAGE ApiMessage;
675 PCONSOLE_WRITEINPUT WriteInputRequest = &ApiMessage.Data.WriteInputRequest;
676 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
677
678 DPRINT("IntWriteConsoleInput: %lx %p\n", nLength, lpNumberOfEventsWritten);
679
680 /* Set up the data to send to the Console Server */
681 WriteInputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
682 WriteInputRequest->InputHandle = hConsoleInput;
683 WriteInputRequest->NumRecords = nLength;
684 WriteInputRequest->Unicode = bUnicode;
685 WriteInputRequest->AppendToEnd = bAppendToEnd;
686
687 /*
688 * For optimization purposes, Windows (and hence ReactOS, too, for
689 * compatibility reasons) uses a static buffer if no more than five
690 * input records are written. Otherwise a new buffer is allocated.
691 * This behaviour is also expected in the server-side.
692 */
693 if (nLength <= sizeof(WriteInputRequest->RecordStaticBuffer)/sizeof(INPUT_RECORD))
694 {
695 WriteInputRequest->RecordBufPtr = WriteInputRequest->RecordStaticBuffer;
696 // CaptureBuffer = NULL;
697
698 _SEH2_TRY
699 {
700 RtlCopyMemory(WriteInputRequest->RecordBufPtr,
701 lpBuffer,
702 nLength * sizeof(INPUT_RECORD));
703 }
704 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
705 {
706 SetLastError(ERROR_INVALID_ACCESS);
707 return FALSE;
708 }
709 _SEH2_END;
710 }
711 else
712 {
713 ULONG Size = nLength * sizeof(INPUT_RECORD);
714
715 /* Allocate a Capture Buffer */
716 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
717 if (CaptureBuffer == NULL)
718 {
719 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
720 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
721 return FALSE;
722 }
723
724 /* Capture the user buffer */
725 CsrCaptureMessageBuffer(CaptureBuffer,
726 lpBuffer,
727 Size,
728 (PVOID*)&WriteInputRequest->RecordBufPtr);
729 }
730
731 /* Call the server */
732 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
733 CaptureBuffer,
734 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
735 sizeof(*WriteInputRequest));
736
737 /* Check for success */
738 Success = NT_SUCCESS(ApiMessage.Status);
739
740 /* Release the capture buffer if needed */
741 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
742
743 /* Retrieve the results */
744 _SEH2_TRY
745 {
746 DPRINT("Events written: %lx\n", WriteInputRequest->NumRecords);
747 *lpNumberOfEventsWritten = WriteInputRequest->NumRecords;
748
749 if (!Success)
750 BaseSetLastNTError(ApiMessage.Status);
751 }
752 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
753 {
754 SetLastError(ERROR_INVALID_ACCESS);
755 Success = FALSE;
756 }
757 _SEH2_END;
758
759 /* Return success status */
760 return Success;
761 }
762
763
764 static
765 BOOL
766 IntWriteConsoleOutput(IN HANDLE hConsoleOutput,
767 IN CONST CHAR_INFO *lpBuffer,
768 IN COORD dwBufferSize,
769 IN COORD dwBufferCoord,
770 IN OUT PSMALL_RECT lpWriteRegion,
771 IN BOOLEAN bUnicode)
772 {
773 CONSOLE_API_MESSAGE ApiMessage;
774 PCONSOLE_WRITEOUTPUT WriteOutputRequest = &ApiMessage.Data.WriteOutputRequest;
775 PCSR_CAPTURE_BUFFER CaptureBuffer;
776 ULONG Size;
777
778 if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
779 {
780 SetLastError(ERROR_INVALID_ACCESS);
781 return FALSE;
782 }
783 /*
784 if (lpWriteRegion == NULL)
785 {
786 SetLastError(ERROR_INVALID_PARAMETER);
787 return FALSE;
788 }
789 */
790
791 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
792
793 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
794
795 /* Allocate a Capture Buffer */
796 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
797 if (CaptureBuffer == NULL)
798 {
799 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
800 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
801 return FALSE;
802 }
803
804 /* Capture the user buffer */
805 CsrCaptureMessageBuffer(CaptureBuffer,
806 (PVOID)lpBuffer,
807 Size,
808 (PVOID*)&WriteOutputRequest->CharInfo);
809
810 /* Set up the data to send to the Console Server */
811 WriteOutputRequest->OutputHandle = hConsoleOutput;
812 WriteOutputRequest->Unicode = bUnicode;
813 WriteOutputRequest->BufferSize = dwBufferSize;
814 WriteOutputRequest->BufferCoord = dwBufferCoord;
815 WriteOutputRequest->WriteRegion = *lpWriteRegion;
816
817 /* Call the server */
818 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
819 CaptureBuffer,
820 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
821 sizeof(*WriteOutputRequest));
822
823 /* Check for success */
824 if (!NT_SUCCESS(ApiMessage.Status))
825 {
826 BaseSetLastNTError(ApiMessage.Status);
827 }
828
829 /* Return the read region */
830 DPRINT("read region: %p\n", WriteOutputRequest->WriteRegion);
831 *lpWriteRegion = WriteOutputRequest->WriteRegion;
832
833 /* Release the capture buffer */
834 CsrFreeCaptureBuffer(CaptureBuffer);
835
836 /* Return TRUE or FALSE */
837 return NT_SUCCESS(ApiMessage.Status);
838 }
839
840
841 static
842 BOOL
843 IntWriteConsoleOutputCode(IN HANDLE hConsoleOutput,
844 IN CODE_TYPE CodeType,
845 IN CONST VOID *pCode,
846 IN DWORD nLength,
847 IN COORD dwWriteCoord,
848 OUT LPDWORD lpNumberOfCodesWritten)
849 {
850 BOOL Success;
851 CONSOLE_API_MESSAGE ApiMessage;
852 PCONSOLE_WRITEOUTPUTCODE WriteOutputCodeRequest = &ApiMessage.Data.WriteOutputCodeRequest;
853 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
854 ULONG CodeSize, SizeBytes;
855
856 if ( (CodeType != CODE_ASCII ) &&
857 (CodeType != CODE_UNICODE ) &&
858 (CodeType != CODE_ATTRIBUTE) )
859 {
860 SetLastError(ERROR_INVALID_PARAMETER);
861 return FALSE;
862 }
863
864 DPRINT("IntWriteConsoleOutputCode\n");
865
866 /* Set up the data to send to the Console Server */
867 WriteOutputCodeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
868 WriteOutputCodeRequest->OutputHandle = hConsoleOutput;
869 WriteOutputCodeRequest->Coord = dwWriteCoord;
870 WriteOutputCodeRequest->NumCodes = nLength;
871
872 /* Determine the needed size */
873 WriteOutputCodeRequest->CodeType = CodeType;
874 switch (CodeType)
875 {
876 case CODE_ASCII:
877 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
878 break;
879
880 case CODE_UNICODE:
881 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
882 break;
883
884 case CODE_ATTRIBUTE:
885 CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
886 break;
887 }
888 SizeBytes = nLength * CodeSize;
889
890 /*
891 * For optimization purposes, Windows (and hence ReactOS, too, for
892 * compatibility reasons) uses a static buffer if no more than eighty
893 * bytes are written. Otherwise a new buffer is allocated.
894 * This behaviour is also expected in the server-side.
895 */
896 if (SizeBytes <= sizeof(WriteOutputCodeRequest->CodeStaticBuffer))
897 {
898 WriteOutputCodeRequest->pCode = WriteOutputCodeRequest->CodeStaticBuffer;
899 // CaptureBuffer = NULL;
900
901 _SEH2_TRY
902 {
903 RtlCopyMemory(WriteOutputCodeRequest->pCode,
904 pCode,
905 SizeBytes);
906 }
907 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
908 {
909 SetLastError(ERROR_INVALID_ACCESS);
910 return FALSE;
911 }
912 _SEH2_END;
913 }
914 else
915 {
916 /* Allocate a Capture Buffer */
917 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
918 if (CaptureBuffer == NULL)
919 {
920 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
921 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
922 return FALSE;
923 }
924
925 /* Capture the buffer to write */
926 CsrCaptureMessageBuffer(CaptureBuffer,
927 (PVOID)pCode,
928 SizeBytes,
929 (PVOID*)&WriteOutputCodeRequest->pCode);
930 }
931
932 /* Call the server */
933 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
934 CaptureBuffer,
935 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
936 sizeof(*WriteOutputCodeRequest));
937
938 /* Check for success */
939 Success = NT_SUCCESS(ApiMessage.Status);
940
941 /* Release the capture buffer if needed */
942 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
943
944 /* Retrieve the results */
945 _SEH2_TRY
946 {
947 *lpNumberOfCodesWritten = WriteOutputCodeRequest->NumCodes;
948
949 if (!Success)
950 BaseSetLastNTError(ApiMessage.Status);
951 }
952 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
953 {
954 SetLastError(ERROR_INVALID_ACCESS);
955 Success = FALSE;
956 }
957 _SEH2_END;
958
959 /* Return success status */
960 return Success;
961 }
962
963
964 static
965 BOOL
966 IntFillConsoleOutputCode(IN HANDLE hConsoleOutput,
967 IN CODE_TYPE CodeType,
968 IN CODE_ELEMENT Code,
969 IN DWORD nLength,
970 IN COORD dwWriteCoord,
971 OUT LPDWORD lpNumberOfCodesWritten)
972 {
973 BOOL Success;
974 CONSOLE_API_MESSAGE ApiMessage;
975 PCONSOLE_FILLOUTPUTCODE FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
976
977 DPRINT("IntFillConsoleOutputCode\n");
978
979 if ( (CodeType != CODE_ASCII ) &&
980 (CodeType != CODE_UNICODE ) &&
981 (CodeType != CODE_ATTRIBUTE) )
982 {
983 SetLastError(ERROR_INVALID_PARAMETER);
984 return FALSE;
985 }
986
987 /* Set up the data to send to the Console Server */
988 FillOutputRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
989 FillOutputRequest->OutputHandle = hConsoleOutput;
990 FillOutputRequest->WriteCoord = dwWriteCoord;
991 FillOutputRequest->CodeType = CodeType;
992 FillOutputRequest->Code = Code;
993 FillOutputRequest->NumCodes = nLength;
994
995 /* Call the server */
996 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
997 NULL,
998 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
999 sizeof(*FillOutputRequest));
1000
1001 /* Check for success */
1002 Success = NT_SUCCESS(ApiMessage.Status);
1003
1004 /* Retrieve the results */
1005 _SEH2_TRY
1006 {
1007 *lpNumberOfCodesWritten = FillOutputRequest->NumCodes;
1008
1009 if (!Success)
1010 BaseSetLastNTError(ApiMessage.Status);
1011 }
1012 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
1013 {
1014 SetLastError(ERROR_INVALID_ACCESS);
1015 Success = FALSE;
1016 }
1017 _SEH2_END;
1018
1019 /* Return success status */
1020 return Success;
1021 }
1022
1023
1024 /* FUNCTIONS ******************************************************************/
1025
1026 /******************
1027 * Read functions *
1028 ******************/
1029
1030 /*--------------------------------------------------------------
1031 * ReadConsoleW
1032 *
1033 * @implemented
1034 */
1035 BOOL
1036 WINAPI
1037 ReadConsoleW(IN HANDLE hConsoleInput,
1038 OUT LPVOID lpBuffer,
1039 IN DWORD nNumberOfCharsToRead,
1040 OUT LPDWORD lpNumberOfCharsRead,
1041 IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
1042 {
1043 return IntReadConsole(hConsoleInput,
1044 lpBuffer,
1045 nNumberOfCharsToRead,
1046 lpNumberOfCharsRead,
1047 pInputControl,
1048 TRUE);
1049 }
1050
1051
1052 /*--------------------------------------------------------------
1053 * ReadConsoleA
1054 *
1055 * @implemented
1056 */
1057 BOOL
1058 WINAPI
1059 ReadConsoleA(IN HANDLE hConsoleInput,
1060 OUT LPVOID lpBuffer,
1061 IN DWORD nNumberOfCharsToRead,
1062 OUT LPDWORD lpNumberOfCharsRead,
1063 IN PCONSOLE_READCONSOLE_CONTROL pInputControl OPTIONAL)
1064 {
1065 return IntReadConsole(hConsoleInput,
1066 lpBuffer,
1067 nNumberOfCharsToRead,
1068 lpNumberOfCharsRead,
1069 NULL,
1070 FALSE);
1071 }
1072
1073
1074 /*--------------------------------------------------------------
1075 * PeekConsoleInputW
1076 *
1077 * @implemented
1078 */
1079 BOOL
1080 WINAPI
1081 PeekConsoleInputW(IN HANDLE hConsoleInput,
1082 OUT PINPUT_RECORD lpBuffer,
1083 IN DWORD nLength,
1084 OUT LPDWORD lpNumberOfEventsRead)
1085 {
1086 return IntGetConsoleInput(hConsoleInput,
1087 lpBuffer,
1088 nLength,
1089 lpNumberOfEventsRead,
1090 CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
1091 TRUE);
1092 }
1093
1094
1095 /*--------------------------------------------------------------
1096 * PeekConsoleInputA
1097 *
1098 * @implemented
1099 */
1100 BOOL
1101 WINAPI
1102 PeekConsoleInputA(IN HANDLE hConsoleInput,
1103 OUT PINPUT_RECORD lpBuffer,
1104 IN DWORD nLength,
1105 OUT LPDWORD lpNumberOfEventsRead)
1106 {
1107 return IntGetConsoleInput(hConsoleInput,
1108 lpBuffer,
1109 nLength,
1110 lpNumberOfEventsRead,
1111 CONSOLE_READ_KEEPEVENT | CONSOLE_READ_CONTINUE,
1112 FALSE);
1113 }
1114
1115
1116 /*--------------------------------------------------------------
1117 * ReadConsoleInputW
1118 *
1119 * @implemented
1120 */
1121 BOOL
1122 WINAPI
1123 ReadConsoleInputW(IN HANDLE hConsoleInput,
1124 OUT PINPUT_RECORD lpBuffer,
1125 IN DWORD nLength,
1126 OUT LPDWORD lpNumberOfEventsRead)
1127 {
1128 return IntGetConsoleInput(hConsoleInput,
1129 lpBuffer,
1130 nLength,
1131 lpNumberOfEventsRead,
1132 0,
1133 TRUE);
1134 }
1135
1136
1137 /*--------------------------------------------------------------
1138 * ReadConsoleInputA
1139 *
1140 * @implemented
1141 */
1142 BOOL
1143 WINAPI
1144 ReadConsoleInputA(IN HANDLE hConsoleInput,
1145 OUT PINPUT_RECORD lpBuffer,
1146 IN DWORD nLength,
1147 OUT LPDWORD lpNumberOfEventsRead)
1148 {
1149 return IntGetConsoleInput(hConsoleInput,
1150 lpBuffer,
1151 nLength,
1152 lpNumberOfEventsRead,
1153 0,
1154 FALSE);
1155 }
1156
1157
1158 /*--------------------------------------------------------------
1159 * ReadConsoleInputExW
1160 *
1161 * @implemented
1162 */
1163 BOOL
1164 WINAPI
1165 ReadConsoleInputExW(IN HANDLE hConsoleInput,
1166 OUT PINPUT_RECORD lpBuffer,
1167 IN DWORD nLength,
1168 OUT LPDWORD lpNumberOfEventsRead,
1169 IN WORD wFlags)
1170 {
1171 return IntGetConsoleInput(hConsoleInput,
1172 lpBuffer,
1173 nLength,
1174 lpNumberOfEventsRead,
1175 wFlags,
1176 TRUE);
1177 }
1178
1179
1180 /*--------------------------------------------------------------
1181 * ReadConsoleInputExA
1182 *
1183 * @implemented
1184 */
1185 BOOL
1186 WINAPI
1187 ReadConsoleInputExA(IN HANDLE hConsoleInput,
1188 OUT PINPUT_RECORD lpBuffer,
1189 IN DWORD nLength,
1190 OUT LPDWORD lpNumberOfEventsRead,
1191 IN WORD wFlags)
1192 {
1193 return IntGetConsoleInput(hConsoleInput,
1194 lpBuffer,
1195 nLength,
1196 lpNumberOfEventsRead,
1197 wFlags,
1198 FALSE);
1199 }
1200
1201
1202 /*--------------------------------------------------------------
1203 * ReadConsoleOutputW
1204 *
1205 * @implemented
1206 */
1207 BOOL
1208 WINAPI
1209 ReadConsoleOutputW(IN HANDLE hConsoleOutput,
1210 OUT PCHAR_INFO lpBuffer,
1211 IN COORD dwBufferSize,
1212 IN COORD dwBufferCoord,
1213 IN OUT PSMALL_RECT lpReadRegion)
1214 {
1215 return IntReadConsoleOutput(hConsoleOutput,
1216 lpBuffer,
1217 dwBufferSize,
1218 dwBufferCoord,
1219 lpReadRegion,
1220 TRUE);
1221 }
1222
1223
1224 /*--------------------------------------------------------------
1225 * ReadConsoleOutputA
1226 *
1227 * @implemented
1228 */
1229 BOOL
1230 WINAPI
1231 ReadConsoleOutputA(IN HANDLE hConsoleOutput,
1232 OUT PCHAR_INFO lpBuffer,
1233 IN COORD dwBufferSize,
1234 IN COORD dwBufferCoord,
1235 IN OUT PSMALL_RECT lpReadRegion)
1236 {
1237 return IntReadConsoleOutput(hConsoleOutput,
1238 lpBuffer,
1239 dwBufferSize,
1240 dwBufferCoord,
1241 lpReadRegion,
1242 FALSE);
1243 }
1244
1245
1246 /*--------------------------------------------------------------
1247 * ReadConsoleOutputCharacterW
1248 *
1249 * @implemented
1250 */
1251 BOOL
1252 WINAPI
1253 ReadConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1254 OUT LPWSTR lpCharacter,
1255 IN DWORD nLength,
1256 IN COORD dwReadCoord,
1257 OUT LPDWORD lpNumberOfCharsRead)
1258 {
1259 return IntReadConsoleOutputCode(hConsoleOutput,
1260 CODE_UNICODE,
1261 lpCharacter,
1262 nLength,
1263 dwReadCoord,
1264 lpNumberOfCharsRead);
1265 }
1266
1267
1268 /*--------------------------------------------------------------
1269 * ReadConsoleOutputCharacterA
1270 *
1271 * @implemented
1272 */
1273 BOOL
1274 WINAPI
1275 ReadConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1276 OUT LPSTR lpCharacter,
1277 IN DWORD nLength,
1278 IN COORD dwReadCoord,
1279 OUT LPDWORD lpNumberOfCharsRead)
1280 {
1281 return IntReadConsoleOutputCode(hConsoleOutput,
1282 CODE_ASCII,
1283 lpCharacter,
1284 nLength,
1285 dwReadCoord,
1286 lpNumberOfCharsRead);
1287 }
1288
1289
1290 /*--------------------------------------------------------------
1291 * ReadConsoleOutputAttribute
1292 *
1293 * @implemented
1294 */
1295 BOOL
1296 WINAPI
1297 ReadConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1298 OUT LPWORD lpAttribute,
1299 IN DWORD nLength,
1300 IN COORD dwReadCoord,
1301 OUT LPDWORD lpNumberOfAttrsRead)
1302 {
1303 return IntReadConsoleOutputCode(hConsoleOutput,
1304 CODE_ATTRIBUTE,
1305 lpAttribute,
1306 nLength,
1307 dwReadCoord,
1308 lpNumberOfAttrsRead);
1309 }
1310
1311
1312 /*******************
1313 * Write functions *
1314 *******************/
1315
1316 /*--------------------------------------------------------------
1317 * WriteConsoleW
1318 *
1319 * @implemented
1320 */
1321 BOOL
1322 WINAPI
1323 WriteConsoleW(IN HANDLE hConsoleOutput,
1324 IN CONST VOID *lpBuffer,
1325 IN DWORD nNumberOfCharsToWrite,
1326 OUT LPDWORD lpNumberOfCharsWritten,
1327 LPVOID lpReserved)
1328 {
1329 return IntWriteConsole(hConsoleOutput,
1330 (PVOID)lpBuffer,
1331 nNumberOfCharsToWrite,
1332 lpNumberOfCharsWritten,
1333 lpReserved,
1334 TRUE);
1335 }
1336
1337
1338 /*--------------------------------------------------------------
1339 * WriteConsoleA
1340 *
1341 * @implemented
1342 */
1343 BOOL
1344 WINAPI
1345 WriteConsoleA(IN HANDLE hConsoleOutput,
1346 IN CONST VOID *lpBuffer,
1347 IN DWORD nNumberOfCharsToWrite,
1348 OUT LPDWORD lpNumberOfCharsWritten,
1349 LPVOID lpReserved)
1350 {
1351 return IntWriteConsole(hConsoleOutput,
1352 (PVOID)lpBuffer,
1353 nNumberOfCharsToWrite,
1354 lpNumberOfCharsWritten,
1355 lpReserved,
1356 FALSE);
1357 }
1358
1359
1360 /*--------------------------------------------------------------
1361 * WriteConsoleInputW
1362 *
1363 * @implemented
1364 */
1365 BOOL
1366 WINAPI
1367 WriteConsoleInputW(IN HANDLE hConsoleInput,
1368 IN CONST INPUT_RECORD *lpBuffer,
1369 IN DWORD nLength,
1370 OUT LPDWORD lpNumberOfEventsWritten)
1371 {
1372 return IntWriteConsoleInput(hConsoleInput,
1373 (PINPUT_RECORD)lpBuffer,
1374 nLength,
1375 lpNumberOfEventsWritten,
1376 TRUE,
1377 TRUE);
1378 }
1379
1380
1381 /*--------------------------------------------------------------
1382 * WriteConsoleInputA
1383 *
1384 * @implemented
1385 */
1386 BOOL
1387 WINAPI
1388 WriteConsoleInputA(IN HANDLE hConsoleInput,
1389 IN CONST INPUT_RECORD *lpBuffer,
1390 IN DWORD nLength,
1391 OUT LPDWORD lpNumberOfEventsWritten)
1392 {
1393 return IntWriteConsoleInput(hConsoleInput,
1394 (PINPUT_RECORD)lpBuffer,
1395 nLength,
1396 lpNumberOfEventsWritten,
1397 FALSE,
1398 TRUE);
1399 }
1400
1401
1402 /*--------------------------------------------------------------
1403 * WriteConsoleInputVDMW
1404 *
1405 * @implemented
1406 */
1407 BOOL
1408 WINAPI
1409 WriteConsoleInputVDMW(IN HANDLE hConsoleInput,
1410 IN CONST INPUT_RECORD *lpBuffer,
1411 IN DWORD nLength,
1412 OUT LPDWORD lpNumberOfEventsWritten)
1413 {
1414 return IntWriteConsoleInput(hConsoleInput,
1415 (PINPUT_RECORD)lpBuffer,
1416 nLength,
1417 lpNumberOfEventsWritten,
1418 TRUE,
1419 FALSE);
1420 }
1421
1422
1423 /*--------------------------------------------------------------
1424 * WriteConsoleInputVDMA
1425 *
1426 * @implemented
1427 */
1428 BOOL
1429 WINAPI
1430 WriteConsoleInputVDMA(IN HANDLE hConsoleInput,
1431 IN CONST INPUT_RECORD *lpBuffer,
1432 IN DWORD nLength,
1433 OUT LPDWORD lpNumberOfEventsWritten)
1434 {
1435 return IntWriteConsoleInput(hConsoleInput,
1436 (PINPUT_RECORD)lpBuffer,
1437 nLength,
1438 lpNumberOfEventsWritten,
1439 FALSE,
1440 FALSE);
1441 }
1442
1443
1444 /*--------------------------------------------------------------
1445 * WriteConsoleOutputW
1446 *
1447 * @implemented
1448 */
1449 BOOL
1450 WINAPI
1451 WriteConsoleOutputW(IN HANDLE hConsoleOutput,
1452 IN CONST CHAR_INFO *lpBuffer,
1453 IN COORD dwBufferSize,
1454 IN COORD dwBufferCoord,
1455 IN OUT PSMALL_RECT lpWriteRegion)
1456 {
1457 return IntWriteConsoleOutput(hConsoleOutput,
1458 lpBuffer,
1459 dwBufferSize,
1460 dwBufferCoord,
1461 lpWriteRegion,
1462 TRUE);
1463 }
1464
1465
1466 /*--------------------------------------------------------------
1467 * WriteConsoleOutputA
1468 *
1469 * @implemented
1470 */
1471 BOOL
1472 WINAPI
1473 WriteConsoleOutputA(IN HANDLE hConsoleOutput,
1474 IN CONST CHAR_INFO *lpBuffer,
1475 IN COORD dwBufferSize,
1476 IN COORD dwBufferCoord,
1477 IN OUT PSMALL_RECT lpWriteRegion)
1478 {
1479 return IntWriteConsoleOutput(hConsoleOutput,
1480 lpBuffer,
1481 dwBufferSize,
1482 dwBufferCoord,
1483 lpWriteRegion,
1484 FALSE);
1485 }
1486
1487
1488 /*--------------------------------------------------------------
1489 * WriteConsoleOutputCharacterW
1490 *
1491 * @implemented
1492 */
1493 BOOL
1494 WINAPI
1495 WriteConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1496 IN LPCWSTR lpCharacter,
1497 IN DWORD nLength,
1498 IN COORD dwWriteCoord,
1499 OUT LPDWORD lpNumberOfCharsWritten)
1500 {
1501 return IntWriteConsoleOutputCode(hConsoleOutput,
1502 CODE_UNICODE,
1503 lpCharacter,
1504 nLength,
1505 dwWriteCoord,
1506 lpNumberOfCharsWritten);
1507 }
1508
1509
1510 /*--------------------------------------------------------------
1511 * WriteConsoleOutputCharacterA
1512 *
1513 * @implemented
1514 */
1515 BOOL
1516 WINAPI
1517 WriteConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1518 IN LPCSTR lpCharacter,
1519 IN DWORD nLength,
1520 IN COORD dwWriteCoord,
1521 OUT LPDWORD lpNumberOfCharsWritten)
1522 {
1523 return IntWriteConsoleOutputCode(hConsoleOutput,
1524 CODE_ASCII,
1525 lpCharacter,
1526 nLength,
1527 dwWriteCoord,
1528 lpNumberOfCharsWritten);
1529 }
1530
1531
1532 /*--------------------------------------------------------------
1533 * WriteConsoleOutputAttribute
1534 *
1535 * @implemented
1536 */
1537 BOOL
1538 WINAPI
1539 WriteConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1540 IN CONST WORD *lpAttribute,
1541 IN DWORD nLength,
1542 IN COORD dwWriteCoord,
1543 OUT LPDWORD lpNumberOfAttrsWritten)
1544 {
1545 return IntWriteConsoleOutputCode(hConsoleOutput,
1546 CODE_ATTRIBUTE,
1547 lpAttribute,
1548 nLength,
1549 dwWriteCoord,
1550 lpNumberOfAttrsWritten);
1551 }
1552
1553
1554 /*--------------------------------------------------------------
1555 * FillConsoleOutputCharacterW
1556 *
1557 * @implemented
1558 */
1559 BOOL
1560 WINAPI
1561 FillConsoleOutputCharacterW(IN HANDLE hConsoleOutput,
1562 IN WCHAR cCharacter,
1563 IN DWORD nLength,
1564 IN COORD dwWriteCoord,
1565 OUT LPDWORD lpNumberOfCharsWritten)
1566 {
1567 CODE_ELEMENT Code;
1568 Code.UnicodeChar = cCharacter;
1569 return IntFillConsoleOutputCode(hConsoleOutput,
1570 CODE_UNICODE,
1571 Code,
1572 nLength,
1573 dwWriteCoord,
1574 lpNumberOfCharsWritten);
1575 }
1576
1577
1578 /*--------------------------------------------------------------
1579 * FillConsoleOutputCharacterA
1580 *
1581 * @implemented
1582 */
1583 BOOL
1584 WINAPI
1585 FillConsoleOutputCharacterA(IN HANDLE hConsoleOutput,
1586 IN CHAR cCharacter,
1587 IN DWORD nLength,
1588 IN COORD dwWriteCoord,
1589 LPDWORD lpNumberOfCharsWritten)
1590 {
1591 CODE_ELEMENT Code;
1592 Code.AsciiChar = cCharacter;
1593 return IntFillConsoleOutputCode(hConsoleOutput,
1594 CODE_ASCII,
1595 Code,
1596 nLength,
1597 dwWriteCoord,
1598 lpNumberOfCharsWritten);
1599 }
1600
1601
1602 /*--------------------------------------------------------------
1603 * FillConsoleOutputAttribute
1604 *
1605 * @implemented
1606 */
1607 BOOL
1608 WINAPI
1609 FillConsoleOutputAttribute(IN HANDLE hConsoleOutput,
1610 IN WORD wAttribute,
1611 IN DWORD nLength,
1612 IN COORD dwWriteCoord,
1613 OUT LPDWORD lpNumberOfAttrsWritten)
1614 {
1615 CODE_ELEMENT Code;
1616 Code.Attribute = wAttribute;
1617 return IntFillConsoleOutputCode(hConsoleOutput,
1618 CODE_ATTRIBUTE,
1619 Code,
1620 nLength,
1621 dwWriteCoord,
1622 lpNumberOfAttrsWritten);
1623 }
1624
1625 /* EOF */