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