Sync with trunk r58033.
[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 NTSTATUS Status;
37 CONSOLE_API_MESSAGE ApiMessage;
38 PCSRSS_READ_CONSOLE ReadConsoleRequest = &ApiMessage.Data.ReadConsoleRequest;
39 PCSR_CAPTURE_BUFFER CaptureBuffer;
40 ULONG CharSize;
41
42 /* Determine the needed size */
43 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
44 ReadConsoleRequest->BufferSize = nNumberOfCharsToRead * CharSize;
45
46 /* Allocate a Capture Buffer */
47 CaptureBuffer = CsrAllocateCaptureBuffer(1, ReadConsoleRequest->BufferSize);
48 if (CaptureBuffer == NULL)
49 {
50 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
51 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
52 return FALSE;
53 }
54
55 /* Allocate space in the Buffer */
56 CsrAllocateMessagePointer(CaptureBuffer,
57 ReadConsoleRequest->BufferSize,
58 (PVOID*)&ReadConsoleRequest->Buffer);
59
60 /* Set up the data to send to the Console Server */
61 ReadConsoleRequest->ConsoleHandle = hConsoleInput;
62 ReadConsoleRequest->Unicode = bUnicode;
63 ReadConsoleRequest->NrCharactersToRead = (WORD)nNumberOfCharsToRead;
64 ReadConsoleRequest->NrCharactersRead = 0;
65 ReadConsoleRequest->CtrlWakeupMask = 0;
66 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
67 {
68 ReadConsoleRequest->NrCharactersRead = pInputControl->nInitialChars;
69 memcpy(ReadConsoleRequest->Buffer,
70 lpBuffer,
71 pInputControl->nInitialChars * sizeof(WCHAR));
72 ReadConsoleRequest->CtrlWakeupMask = pInputControl->dwCtrlWakeupMask;
73 }
74
75 /* Call the server */
76 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
77 CaptureBuffer,
78 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsole),
79 sizeof(CSRSS_READ_CONSOLE));
80
81 /* Check for success */
82 if (NT_SUCCESS(Status) || NT_SUCCESS(Status = ApiMessage.Status))
83 {
84 memcpy(lpBuffer,
85 ReadConsoleRequest->Buffer,
86 ReadConsoleRequest->NrCharactersRead * CharSize);
87
88 if (lpNumberOfCharsRead != NULL)
89 *lpNumberOfCharsRead = ReadConsoleRequest->NrCharactersRead;
90
91 if (pInputControl && pInputControl->nLength == sizeof(CONSOLE_READCONSOLE_CONTROL))
92 pInputControl->dwControlKeyState = ReadConsoleRequest->ControlKeyState;
93 }
94 else
95 {
96 DPRINT1("CSR returned error in ReadConsole\n");
97
98 if (lpNumberOfCharsRead != NULL)
99 *lpNumberOfCharsRead = 0;
100
101 /* Error out */
102 BaseSetLastNTError(Status /* ApiMessage.Status */);
103 }
104
105 CsrFreeCaptureBuffer(CaptureBuffer);
106
107 /* Return TRUE or FALSE */
108 // return TRUE;
109 return (ReadConsoleRequest->NrCharactersRead > 0);
110 // return NT_SUCCESS(ApiMessage.Status);
111 }
112
113
114 static
115 BOOL
116 IntGetConsoleInput(HANDLE hConsoleInput,
117 BOOL bRead,
118 PINPUT_RECORD lpBuffer,
119 DWORD nLength,
120 LPDWORD lpNumberOfEventsRead,
121 BOOL bUnicode)
122 {
123 NTSTATUS Status;
124 CONSOLE_API_MESSAGE ApiMessage;
125 PCSRSS_GET_CONSOLE_INPUT GetConsoleInputRequest = &ApiMessage.Data.GetConsoleInputRequest;
126 PCSR_CAPTURE_BUFFER CaptureBuffer;
127 ULONG Size;
128
129 if (lpBuffer == NULL)
130 {
131 SetLastError(ERROR_INVALID_PARAMETER);
132 return FALSE;
133 }
134
135 Size = nLength * sizeof(INPUT_RECORD);
136
137 DPRINT("IntGetConsoleInput: %lx %p\n", Size, lpNumberOfEventsRead);
138
139 /* Allocate a Capture Buffer */
140 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
141 if (CaptureBuffer == NULL)
142 {
143 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
144 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
145 return FALSE;
146 }
147
148 /* Allocate space in the Buffer */
149 CsrAllocateMessagePointer(CaptureBuffer,
150 Size,
151 (PVOID*)&GetConsoleInputRequest->InputRecord);
152
153 /* Set up the data to send to the Console Server */
154 GetConsoleInputRequest->ConsoleHandle = hConsoleInput;
155 GetConsoleInputRequest->Unicode = bUnicode;
156 GetConsoleInputRequest->bRead = bRead;
157 GetConsoleInputRequest->InputsRead = 0;
158 GetConsoleInputRequest->Length = nLength;
159
160 /* Call the server */
161 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
162 CaptureBuffer,
163 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleInput),
164 sizeof(CSRSS_GET_CONSOLE_INPUT));
165 DPRINT("Server returned: %x\n", ApiMessage.Status);
166
167 /* Check for success */
168 if (NT_SUCCESS(Status) || NT_SUCCESS(Status = ApiMessage.Status))
169 {
170 /* Return the number of events read */
171 DPRINT("Events read: %lx\n", GetConsoleInputRequest->InputsRead);
172
173 if (lpNumberOfEventsRead != NULL)
174 *lpNumberOfEventsRead = GetConsoleInputRequest->InputsRead;
175
176 /* Copy into the buffer */
177 DPRINT("Copying to buffer\n");
178 RtlCopyMemory(lpBuffer,
179 GetConsoleInputRequest->InputRecord,
180 sizeof(INPUT_RECORD) * GetConsoleInputRequest->InputsRead);
181 }
182 else
183 {
184 if (lpNumberOfEventsRead != NULL)
185 *lpNumberOfEventsRead = 0;
186
187 /* Error out */
188 BaseSetLastNTError(ApiMessage.Status);
189
190 /*********
191 // BaseSetLastNTError(Status); ????
192 if (GetConsoleInputRequest->InputsRead == 0)
193 {
194 /\* we couldn't read a single record, fail *\/
195 BaseSetLastNTError(Status);
196 return FALSE;
197 }
198 else
199 {
200 /\* FIXME - fail gracefully in case we already read at least one record? *\/
201 // break;
202 }
203 *********/
204 }
205
206 /* Release the capture buffer */
207 CsrFreeCaptureBuffer(CaptureBuffer);
208
209 /* Return TRUE or FALSE */
210 return (GetConsoleInputRequest->InputsRead > 0);
211 // return NT_SUCCESS(ApiMessage.Status);
212 }
213
214
215 static
216 BOOL
217 IntReadConsoleOutput(HANDLE hConsoleOutput,
218 PCHAR_INFO lpBuffer,
219 COORD dwBufferSize,
220 COORD dwBufferCoord,
221 PSMALL_RECT lpReadRegion,
222 BOOL bUnicode)
223 {
224 CONSOLE_API_MESSAGE ApiMessage;
225 PCSRSS_READ_CONSOLE_OUTPUT ReadConsoleOutputRequest = &ApiMessage.Data.ReadConsoleOutputRequest;
226 PCSR_CAPTURE_BUFFER CaptureBuffer;
227 DWORD Size, SizeX, SizeY;
228
229 if (lpBuffer == NULL)
230 {
231 SetLastError(ERROR_INVALID_PARAMETER);
232 return FALSE;
233 }
234
235 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
236
237 DPRINT("IntReadConsoleOutput: %lx %p\n", Size, lpReadRegion);
238
239 /* Allocate a Capture Buffer */
240 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
241 if (CaptureBuffer == NULL)
242 {
243 DPRINT1("CsrAllocateCaptureBuffer failed with size 0x%x!\n", Size);
244 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
245 return FALSE;
246 }
247
248 /* Allocate space in the Buffer */
249 CsrAllocateMessagePointer(CaptureBuffer,
250 Size,
251 (PVOID*)&ReadConsoleOutputRequest->CharInfo);
252
253 /* Set up the data to send to the Console Server */
254 ReadConsoleOutputRequest->ConsoleHandle = hConsoleOutput;
255 ReadConsoleOutputRequest->Unicode = bUnicode;
256 ReadConsoleOutputRequest->BufferSize = dwBufferSize;
257 ReadConsoleOutputRequest->BufferCoord = dwBufferCoord;
258 ReadConsoleOutputRequest->ReadRegion = *lpReadRegion;
259
260 /* Call the server */
261 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
262 CaptureBuffer,
263 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutput),
264 sizeof(CSRSS_READ_CONSOLE_OUTPUT));
265 DPRINT("Server returned: %x\n", ApiMessage.Status);
266
267 /* Check for success*/
268 if (NT_SUCCESS(ApiMessage.Status))
269 {
270 /* Copy into the buffer */
271 DPRINT("Copying to buffer\n");
272 SizeX = ReadConsoleOutputRequest->ReadRegion.Right -
273 ReadConsoleOutputRequest->ReadRegion.Left + 1;
274 SizeY = ReadConsoleOutputRequest->ReadRegion.Bottom -
275 ReadConsoleOutputRequest->ReadRegion.Top + 1;
276 RtlCopyMemory(lpBuffer,
277 ReadConsoleOutputRequest->CharInfo,
278 sizeof(CHAR_INFO) * SizeX * SizeY);
279 }
280 else
281 {
282 /* Error out */
283 BaseSetLastNTError(ApiMessage.Status);
284 }
285
286 /* Return the read region */
287 DPRINT("read region: %lx\n", ReadConsoleOutputRequest->ReadRegion);
288 *lpReadRegion = ReadConsoleOutputRequest->ReadRegion;
289
290 /* Release the capture buffer */
291 CsrFreeCaptureBuffer(CaptureBuffer);
292
293 /* Return TRUE or FALSE */
294 return NT_SUCCESS(ApiMessage.Status);
295 }
296
297
298 static
299 BOOL
300 IntReadConsoleOutputCode(HANDLE hConsoleOutput,
301 CODE_TYPE CodeType,
302 PVOID pCode,
303 DWORD nLength,
304 COORD dwReadCoord,
305 LPDWORD lpNumberOfCodesRead)
306 {
307 NTSTATUS Status;
308 CONSOLE_API_MESSAGE ApiMessage;
309 PCSRSS_READ_CONSOLE_OUTPUT_CODE ReadConsoleOutputCodeRequest = &ApiMessage.Data.ReadConsoleOutputCodeRequest;
310 PCSR_CAPTURE_BUFFER CaptureBuffer;
311 ULONG SizeBytes, CodeSize;
312 DWORD /*CodesRead = 0,*/ BytesRead;
313
314 /* Determine the needed size */
315 switch (CodeType)
316 {
317 case CODE_ASCII:
318 CodeSize = sizeof(CHAR);
319 break;
320
321 case CODE_UNICODE:
322 CodeSize = sizeof(WCHAR);
323 break;
324
325 case CODE_ATTRIBUTE:
326 CodeSize = sizeof(WORD);
327 break;
328
329 default:
330 SetLastError(ERROR_INVALID_PARAMETER);
331 return FALSE;
332 }
333 SizeBytes = nLength * CodeSize;
334
335 /* Allocate a Capture Buffer */
336 CaptureBuffer = CsrAllocateCaptureBuffer(1, SizeBytes);
337 if (CaptureBuffer == NULL)
338 {
339 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
340 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
341 return FALSE;
342 }
343
344 /* Allocate space in the Buffer */
345 CsrAllocateMessagePointer(CaptureBuffer,
346 SizeBytes,
347 (PVOID*)&ReadConsoleOutputCodeRequest->pCode.pCode);
348
349 /* Start reading */
350 ReadConsoleOutputCodeRequest->ConsoleHandle = hConsoleOutput;
351 ReadConsoleOutputCodeRequest->CodeType = CodeType;
352 ReadConsoleOutputCodeRequest->ReadCoord = dwReadCoord;
353
354 // while (nLength > 0)
355 {
356 ReadConsoleOutputCodeRequest->NumCodesToRead = nLength;
357 // SizeBytes = ReadConsoleOutputCodeRequest->NumCodesToRead * CodeSize;
358
359 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
360 CaptureBuffer,
361 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepReadConsoleOutputString),
362 sizeof(CSRSS_READ_CONSOLE_OUTPUT_CODE));
363 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
364 {
365 BaseSetLastNTError(Status);
366 CsrFreeCaptureBuffer(CaptureBuffer);
367 return FALSE;
368 }
369
370 BytesRead = ReadConsoleOutputCodeRequest->CodesRead * CodeSize;
371 memcpy(pCode, ReadConsoleOutputCodeRequest->pCode.pCode, BytesRead);
372 // pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)*/BytesRead);
373 // nLength -= ReadConsoleOutputCodeRequest->CodesRead;
374 // CodesRead += ReadConsoleOutputCodeRequest->CodesRead;
375
376 ReadConsoleOutputCodeRequest->ReadCoord = ReadConsoleOutputCodeRequest->EndCoord;
377 }
378
379 if (lpNumberOfCodesRead != NULL)
380 *lpNumberOfCodesRead = /*CodesRead;*/ ReadConsoleOutputCodeRequest->CodesRead;
381
382 CsrFreeCaptureBuffer(CaptureBuffer);
383
384 return TRUE;
385 }
386
387
388 /*******************
389 * Write functions *
390 *******************/
391
392 static
393 BOOL
394 IntWriteConsole(HANDLE hConsoleOutput,
395 PVOID lpBuffer,
396 DWORD nNumberOfCharsToWrite,
397 LPDWORD lpNumberOfCharsWritten,
398 LPVOID lpReserved,
399 BOOL bUnicode)
400 {
401 NTSTATUS Status;
402 CONSOLE_API_MESSAGE ApiMessage;
403 PCSRSS_WRITE_CONSOLE WriteConsoleRequest = &ApiMessage.Data.WriteConsoleRequest;
404 PCSR_CAPTURE_BUFFER CaptureBuffer;
405 // USHORT nChars;
406 ULONG /* SizeBytes, */ CharSize;
407 // DWORD Written = 0;
408
409 /* Determine the needed size */
410 CharSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
411 WriteConsoleRequest->BufferSize = nNumberOfCharsToWrite * CharSize;
412
413 /* Allocate a Capture Buffer */
414 CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleRequest->BufferSize);
415 if (CaptureBuffer == NULL)
416 {
417 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
418 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
419 return FALSE;
420 }
421
422 /* Capture the buffer to write */
423 CsrCaptureMessageBuffer(CaptureBuffer,
424 (PVOID)lpBuffer,
425 WriteConsoleRequest->BufferSize,
426 (PVOID*)&WriteConsoleRequest->Buffer);
427
428 /* Start writing */
429 WriteConsoleRequest->NrCharactersToWrite = nNumberOfCharsToWrite;
430 WriteConsoleRequest->ConsoleHandle = hConsoleOutput;
431 WriteConsoleRequest->Unicode = bUnicode;
432
433 // while (nNumberOfCharsToWrite > 0)
434 {
435 //// nChars = (USHORT)min(nNumberOfCharsToWrite, CSRSS_MAX_WRITE_CONSOLE / CharSize);
436 // nChars = nNumberOfCharsToWrite;
437 // WriteConsoleRequest->NrCharactersToWrite = nChars;
438
439 // SizeBytes = nChars * CharSize;
440
441 // memcpy(WriteConsoleRequest->Buffer, lpBuffer, SizeBytes);
442
443 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
444 CaptureBuffer,
445 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsole),
446 sizeof(CSRSS_WRITE_CONSOLE));
447 /** FIXME: Added in 47359 for pausing
448
449 if (Status == STATUS_PENDING)
450 {
451 WaitForSingleObject(WriteConsoleRequest->UnpauseEvent, INFINITE);
452 CloseHandle(WriteConsoleRequest->UnpauseEvent);
453 continue;
454 }
455 **/
456 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
457 {
458 CsrFreeCaptureBuffer(CaptureBuffer);
459 BaseSetLastNTError(Status);
460 return FALSE;
461 }
462
463 // nNumberOfCharsToWrite -= nChars;
464 // lpBuffer = (PVOID)((ULONG_PTR)lpBuffer + (ULONG_PTR)SizeBytes);
465 // Written += WriteConsoleRequest->NrCharactersWritten;
466 }
467
468 if (lpNumberOfCharsWritten != NULL)
469 // *lpNumberOfCharsWritten = Written;
470 *lpNumberOfCharsWritten = WriteConsoleRequest->NrCharactersWritten;
471
472 CsrFreeCaptureBuffer(CaptureBuffer);
473
474 return TRUE;
475 }
476
477
478 static
479 BOOL
480 IntWriteConsoleInput(HANDLE hConsoleInput,
481 PINPUT_RECORD lpBuffer,
482 DWORD nLength,
483 LPDWORD lpNumberOfEventsWritten,
484 BOOL bUnicode)
485 {
486 CONSOLE_API_MESSAGE ApiMessage;
487 PCSRSS_WRITE_CONSOLE_INPUT WriteConsoleInputRequest = &ApiMessage.Data.WriteConsoleInputRequest;
488 PCSR_CAPTURE_BUFFER CaptureBuffer;
489 DWORD Size;
490
491 if (lpBuffer == NULL)
492 {
493 SetLastError(ERROR_INVALID_PARAMETER);
494 return FALSE;
495 }
496
497 Size = nLength * sizeof(INPUT_RECORD);
498
499 DPRINT("IntWriteConsoleInput: %lx %p\n", Size, lpNumberOfEventsWritten);
500
501 /* Allocate a Capture Buffer */
502 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
503 if (CaptureBuffer == NULL)
504 {
505 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
506 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
507 return FALSE;
508 }
509
510 /* Capture the user buffer */
511 CsrCaptureMessageBuffer(CaptureBuffer,
512 lpBuffer,
513 Size,
514 (PVOID*)&WriteConsoleInputRequest->InputRecord);
515
516 /* Set up the data to send to the Console Server */
517 WriteConsoleInputRequest->ConsoleHandle = hConsoleInput;
518 WriteConsoleInputRequest->Unicode = bUnicode;
519 WriteConsoleInputRequest->Length = nLength;
520
521 /* Call the server */
522 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
523 CaptureBuffer,
524 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleInput),
525 sizeof(CSRSS_WRITE_CONSOLE_INPUT));
526 DPRINT("Server returned: %x\n", ApiMessage.Status);
527
528 /* Check for success*/
529 if (NT_SUCCESS(ApiMessage.Status))
530 {
531 /* Return the number of events read */
532 DPRINT("Events read: %lx\n", WriteConsoleInputRequest->Length);
533
534 if (lpNumberOfEventsWritten != NULL)
535 *lpNumberOfEventsWritten = WriteConsoleInputRequest->Length;
536 }
537 else
538 {
539 if (lpNumberOfEventsWritten != NULL)
540 *lpNumberOfEventsWritten = 0;
541
542 /* Error out */
543 BaseSetLastNTError(ApiMessage.Status);
544 }
545
546 /* Release the capture buffer */
547 CsrFreeCaptureBuffer(CaptureBuffer);
548
549 /* Return TRUE or FALSE */
550 return NT_SUCCESS(ApiMessage.Status);
551 }
552
553
554 static
555 BOOL
556 IntWriteConsoleOutput(HANDLE hConsoleOutput,
557 CONST CHAR_INFO *lpBuffer,
558 COORD dwBufferSize,
559 COORD dwBufferCoord,
560 PSMALL_RECT lpWriteRegion,
561 BOOL bUnicode)
562 {
563 CONSOLE_API_MESSAGE ApiMessage;
564 PCSRSS_WRITE_CONSOLE_OUTPUT WriteConsoleOutputRequest = &ApiMessage.Data.WriteConsoleOutputRequest;
565 PCSR_CAPTURE_BUFFER CaptureBuffer;
566 ULONG Size;
567
568 if ((lpBuffer == NULL) || (lpWriteRegion == NULL))
569 {
570 SetLastError(ERROR_INVALID_PARAMETER);
571 return FALSE;
572 }
573
574 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
575
576 DPRINT("IntWriteConsoleOutput: %lx %p\n", Size, lpWriteRegion);
577
578 /* Allocate a Capture Buffer */
579 CaptureBuffer = CsrAllocateCaptureBuffer(1, Size);
580 if (CaptureBuffer == NULL)
581 {
582 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
583 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
584 return FALSE;
585 }
586
587 /* Capture the user buffer */
588 CsrCaptureMessageBuffer(CaptureBuffer,
589 (PVOID)lpBuffer,
590 Size,
591 (PVOID*)&WriteConsoleOutputRequest->CharInfo);
592
593 /* Set up the data to send to the Console Server */
594 WriteConsoleOutputRequest->ConsoleHandle = hConsoleOutput;
595 WriteConsoleOutputRequest->Unicode = bUnicode;
596 WriteConsoleOutputRequest->BufferSize = dwBufferSize;
597 WriteConsoleOutputRequest->BufferCoord = dwBufferCoord;
598 WriteConsoleOutputRequest->WriteRegion = *lpWriteRegion;
599
600 /* Call the server */
601 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
602 CaptureBuffer,
603 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutput),
604 sizeof(CSRSS_WRITE_CONSOLE_OUTPUT));
605 DPRINT("Server returned: %x\n", ApiMessage.Status);
606
607 /* Check for success*/
608 if (!NT_SUCCESS(ApiMessage.Status))
609 {
610 /* Error out */
611 BaseSetLastNTError(ApiMessage.Status);
612 }
613
614 /* Return the read region */
615 DPRINT("read region: %lx\n", WriteConsoleOutputRequest->WriteRegion);
616 *lpWriteRegion = WriteConsoleOutputRequest->WriteRegion;
617
618 /* Release the capture buffer */
619 CsrFreeCaptureBuffer(CaptureBuffer);
620
621 /* Return TRUE or FALSE */
622 return NT_SUCCESS(ApiMessage.Status);
623 }
624
625
626 static
627 BOOL
628 IntWriteConsoleOutputCode(HANDLE hConsoleOutput,
629 CODE_TYPE CodeType,
630 CONST VOID *pCode,
631 DWORD nLength,
632 COORD dwWriteCoord,
633 LPDWORD lpNumberOfCodesWritten)
634 {
635 NTSTATUS Status;
636 CONSOLE_API_MESSAGE ApiMessage;
637 PCSRSS_WRITE_CONSOLE_OUTPUT_CODE WriteConsoleOutputCodeRequest = &ApiMessage.Data.WriteConsoleOutputCodeRequest;
638 PCSR_CAPTURE_BUFFER CaptureBuffer;
639 ULONG CodeSize; //, nChars;
640 // ULONG SizeBytes;
641 // DWORD Written = 0;
642
643 /* Determine the needed size */
644 /*
645 CodeSize = (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
646 nChars = min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR / CodeSize);
647 SizeBytes = nChars * CodeSize;
648 */
649 switch (CodeType)
650 {
651 case CODE_ASCII:
652 CodeSize = sizeof(CHAR);
653 break;
654
655 case CODE_UNICODE:
656 CodeSize = sizeof(WCHAR);
657 break;
658
659 case CODE_ATTRIBUTE:
660 CodeSize = sizeof(WORD);
661 break;
662
663 default:
664 SetLastError(ERROR_INVALID_PARAMETER);
665 return FALSE;
666 }
667 WriteConsoleOutputCodeRequest->BufferSize = nLength * CodeSize;
668
669 /* Allocate a Capture Buffer */
670 CaptureBuffer = CsrAllocateCaptureBuffer(1, WriteConsoleOutputCodeRequest->BufferSize);
671 if (CaptureBuffer == NULL)
672 {
673 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
674 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
675 return FALSE;
676 }
677
678 /*
679 /\* Allocate space in the Buffer *\/
680 CsrAllocateMessagePointer(CaptureBuffer,
681 SizeBytes,
682 (PVOID*)&WriteConsoleOutputCodeRequest->pCode.pCode);
683 */
684 /* Capture the buffer to write */
685 CsrCaptureMessageBuffer(CaptureBuffer,
686 (PVOID)pCode,
687 WriteConsoleOutputCodeRequest->BufferSize,
688 (PVOID*)&WriteConsoleOutputCodeRequest->pCode.pCode);
689
690 /* Start writing */
691 WriteConsoleOutputCodeRequest->ConsoleHandle = hConsoleOutput;
692 WriteConsoleOutputCodeRequest->CodeType = CodeType;
693 WriteConsoleOutputCodeRequest->Coord = dwWriteCoord;
694
695 /**
696 ** TODO: HACK: Surely it has to go into CONSRV !!
697 **/
698 // while (nLength > 0)
699 {
700 // DWORD BytesWrite;
701
702 WriteConsoleOutputCodeRequest->Length = nLength; // (WORD)min(nLength, nChars);
703 // BytesWrite = WriteConsoleOutputCodeRequest->Length * CodeSize;
704
705 // memcpy(WriteConsoleOutputCodeRequest->pCode.pCode, pCode, BytesWrite);
706
707 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
708 CaptureBuffer,
709 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepWriteConsoleOutputString),
710 sizeof(CSRSS_WRITE_CONSOLE_OUTPUT_CODE));
711 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
712 {
713 CsrFreeCaptureBuffer(CaptureBuffer);
714 BaseSetLastNTError(Status);
715 return FALSE;
716 }
717
718 // nLength -= WriteConsoleOutputCodeRequest->NrCharactersWritten;
719 // pCode = (PVOID)((ULONG_PTR)pCode + /*(ULONG_PTR)(*/WriteConsoleOutputCodeRequest->NrCharactersWritten * CodeSize/*)*/);
720 // Written += WriteConsoleOutputCodeRequest->NrCharactersWritten;
721
722 WriteConsoleOutputCodeRequest->Coord = WriteConsoleOutputCodeRequest->EndCoord;
723 }
724
725 if (lpNumberOfCodesWritten != NULL)
726 // *lpNumberOfCodesWritten = Written;
727 // *lpNumberOfCodesWritten = WriteConsoleOutputCodeRequest->NrCharactersWritten;
728 *lpNumberOfCodesWritten = WriteConsoleOutputCodeRequest->Length;
729
730 CsrFreeCaptureBuffer(CaptureBuffer);
731
732 return TRUE;
733 }
734
735
736 static
737 BOOL
738 IntFillConsoleOutputCode(HANDLE hConsoleOutput,
739 CODE_TYPE CodeType,
740 PVOID pCode,
741 DWORD nLength,
742 COORD dwWriteCoord,
743 LPDWORD lpNumberOfCodesWritten)
744 {
745 NTSTATUS Status;
746 CONSOLE_API_MESSAGE ApiMessage;
747 PCSRSS_FILL_OUTPUT FillOutputRequest = &ApiMessage.Data.FillOutputRequest;
748
749 FillOutputRequest->ConsoleHandle = hConsoleOutput;
750 FillOutputRequest->CodeType = CodeType;
751
752 switch (CodeType)
753 {
754 case CODE_ASCII:
755 FillOutputRequest->Code.AsciiChar = *(PCHAR)pCode;
756 break;
757
758 case CODE_UNICODE:
759 FillOutputRequest->Code.UnicodeChar = *(PWCHAR)pCode;
760 break;
761
762 case CODE_ATTRIBUTE:
763 FillOutputRequest->Code.Attribute = *(PWORD)pCode;
764 break;
765
766 default:
767 SetLastError(ERROR_INVALID_PARAMETER);
768 return FALSE;
769 }
770
771 FillOutputRequest->Coord = dwWriteCoord;
772 FillOutputRequest->Length = nLength;
773
774 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
775 NULL,
776 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFillConsoleOutput),
777 sizeof(CSRSS_FILL_OUTPUT));
778 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
779 {
780 BaseSetLastNTError(Status);
781 return FALSE;
782 }
783
784 if (lpNumberOfCodesWritten)
785 *lpNumberOfCodesWritten = FillOutputRequest->Length;
786 // *lpNumberOfCodesWritten = Request.Data.FillOutputRequest.NrCharactersWritten;
787
788 return TRUE;
789 }
790
791
792 /* FUNCTIONS ******************************************************************/
793
794 /******************
795 * Read functions *
796 ******************/
797
798 /*--------------------------------------------------------------
799 * ReadConsoleW
800 *
801 * @implemented
802 */
803 BOOL
804 WINAPI
805 ReadConsoleW(HANDLE hConsoleInput,
806 LPVOID lpBuffer,
807 DWORD nNumberOfCharsToRead,
808 LPDWORD lpNumberOfCharsRead,
809 PCONSOLE_READCONSOLE_CONTROL pInputControl)
810 {
811 return IntReadConsole(hConsoleInput,
812 lpBuffer,
813 nNumberOfCharsToRead,
814 lpNumberOfCharsRead,
815 pInputControl,
816 TRUE);
817 }
818
819
820 /*--------------------------------------------------------------
821 * ReadConsoleA
822 *
823 * @implemented
824 */
825 BOOL
826 WINAPI
827 ReadConsoleA(HANDLE hConsoleInput,
828 LPVOID lpBuffer,
829 DWORD nNumberOfCharsToRead,
830 LPDWORD lpNumberOfCharsRead,
831 PCONSOLE_READCONSOLE_CONTROL pInputControl)
832 {
833 return IntReadConsole(hConsoleInput,
834 lpBuffer,
835 nNumberOfCharsToRead,
836 lpNumberOfCharsRead,
837 NULL,
838 FALSE);
839 }
840
841
842 /*--------------------------------------------------------------
843 * PeekConsoleInputW
844 *
845 * @implemented
846 */
847 BOOL
848 WINAPI
849 PeekConsoleInputW(HANDLE hConsoleInput,
850 PINPUT_RECORD lpBuffer,
851 DWORD nLength,
852 LPDWORD lpNumberOfEventsRead)
853 {
854 return IntGetConsoleInput(hConsoleInput,
855 FALSE,
856 lpBuffer,
857 nLength,
858 lpNumberOfEventsRead,
859 TRUE);
860 }
861
862
863 /*--------------------------------------------------------------
864 * PeekConsoleInputA
865 *
866 * @implemented
867 */
868 BOOL
869 WINAPI
870 PeekConsoleInputA(HANDLE hConsoleInput,
871 PINPUT_RECORD lpBuffer,
872 DWORD nLength,
873 LPDWORD lpNumberOfEventsRead)
874 {
875 return IntGetConsoleInput(hConsoleInput,
876 FALSE,
877 lpBuffer,
878 nLength,
879 lpNumberOfEventsRead,
880 FALSE);
881 }
882
883
884 /*--------------------------------------------------------------
885 * ReadConsoleInputW
886 *
887 * @implemented
888 */
889 BOOL
890 WINAPI
891 ReadConsoleInputW(HANDLE hConsoleInput,
892 PINPUT_RECORD lpBuffer,
893 DWORD nLength,
894 LPDWORD lpNumberOfEventsRead)
895 {
896 return IntGetConsoleInput(hConsoleInput,
897 TRUE,
898 lpBuffer,
899 nLength,
900 lpNumberOfEventsRead,
901 TRUE);
902 }
903
904
905 /*--------------------------------------------------------------
906 * ReadConsoleInputA
907 *
908 * @implemented
909 */
910 BOOL
911 WINAPI
912 ReadConsoleInputA(HANDLE hConsoleInput,
913 PINPUT_RECORD lpBuffer,
914 DWORD nLength,
915 LPDWORD lpNumberOfEventsRead)
916 {
917 return IntGetConsoleInput(hConsoleInput,
918 TRUE,
919 lpBuffer,
920 nLength,
921 lpNumberOfEventsRead,
922 FALSE);
923 }
924
925
926 BOOL
927 WINAPI
928 ReadConsoleInputExW(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
929 {
930 STUB;
931 return FALSE;
932 }
933
934
935 BOOL
936 WINAPI
937 ReadConsoleInputExA(HANDLE hConsole, LPVOID lpBuffer, DWORD dwLen, LPDWORD Unknown1, DWORD Unknown2)
938 {
939 STUB;
940 return FALSE;
941 }
942
943
944 /*--------------------------------------------------------------
945 * ReadConsoleOutputW
946 *
947 * @implemented
948 */
949 BOOL
950 WINAPI
951 ReadConsoleOutputW(HANDLE hConsoleOutput,
952 PCHAR_INFO lpBuffer,
953 COORD dwBufferSize,
954 COORD dwBufferCoord,
955 PSMALL_RECT lpReadRegion)
956 {
957 return IntReadConsoleOutput(hConsoleOutput,
958 lpBuffer,
959 dwBufferSize,
960 dwBufferCoord,
961 lpReadRegion,
962 TRUE);
963 }
964
965
966 /*--------------------------------------------------------------
967 * ReadConsoleOutputA
968 *
969 * @implemented
970 */
971 BOOL
972 WINAPI
973 ReadConsoleOutputA(HANDLE hConsoleOutput,
974 PCHAR_INFO lpBuffer,
975 COORD dwBufferSize,
976 COORD dwBufferCoord,
977 PSMALL_RECT lpReadRegion)
978 {
979 return IntReadConsoleOutput(hConsoleOutput,
980 lpBuffer,
981 dwBufferSize,
982 dwBufferCoord,
983 lpReadRegion,
984 FALSE);
985 }
986
987
988 /*--------------------------------------------------------------
989 * ReadConsoleOutputCharacterW
990 *
991 * @implemented
992 */
993 BOOL
994 WINAPI
995 ReadConsoleOutputCharacterW(HANDLE hConsoleOutput,
996 LPWSTR lpCharacter,
997 DWORD nLength,
998 COORD dwReadCoord,
999 LPDWORD lpNumberOfCharsRead)
1000 {
1001 return IntReadConsoleOutputCode(hConsoleOutput,
1002 CODE_UNICODE,
1003 lpCharacter,
1004 nLength,
1005 dwReadCoord,
1006 lpNumberOfCharsRead);
1007 }
1008
1009
1010 /*--------------------------------------------------------------
1011 * ReadConsoleOutputCharacterA
1012 *
1013 * @implemented
1014 */
1015 BOOL
1016 WINAPI
1017 ReadConsoleOutputCharacterA(HANDLE hConsoleOutput,
1018 LPSTR lpCharacter,
1019 DWORD nLength,
1020 COORD dwReadCoord,
1021 LPDWORD lpNumberOfCharsRead)
1022 {
1023 return IntReadConsoleOutputCode(hConsoleOutput,
1024 CODE_ASCII,
1025 lpCharacter,
1026 nLength,
1027 dwReadCoord,
1028 lpNumberOfCharsRead);
1029 }
1030
1031
1032 /*--------------------------------------------------------------
1033 * ReadConsoleOutputAttribute
1034 *
1035 * @implemented
1036 */
1037 BOOL
1038 WINAPI
1039 ReadConsoleOutputAttribute(HANDLE hConsoleOutput,
1040 LPWORD lpAttribute,
1041 DWORD nLength,
1042 COORD dwReadCoord,
1043 LPDWORD lpNumberOfAttrsRead)
1044 {
1045 return IntReadConsoleOutputCode(hConsoleOutput,
1046 CODE_ATTRIBUTE,
1047 lpAttribute,
1048 nLength,
1049 dwReadCoord,
1050 lpNumberOfAttrsRead);
1051 }
1052
1053
1054 /*******************
1055 * Write functions *
1056 *******************/
1057
1058 /*--------------------------------------------------------------
1059 * WriteConsoleW
1060 *
1061 * @implemented
1062 */
1063 BOOL
1064 WINAPI
1065 WriteConsoleW(HANDLE hConsoleOutput,
1066 CONST VOID *lpBuffer,
1067 DWORD nNumberOfCharsToWrite,
1068 LPDWORD lpNumberOfCharsWritten,
1069 LPVOID lpReserved)
1070 {
1071 return IntWriteConsole(hConsoleOutput,
1072 (PVOID)lpBuffer,
1073 nNumberOfCharsToWrite,
1074 lpNumberOfCharsWritten,
1075 lpReserved,
1076 TRUE);
1077 }
1078
1079
1080 /*--------------------------------------------------------------
1081 * WriteConsoleA
1082 *
1083 * @implemented
1084 */
1085 BOOL
1086 WINAPI
1087 WriteConsoleA(HANDLE hConsoleOutput,
1088 CONST VOID *lpBuffer,
1089 DWORD nNumberOfCharsToWrite,
1090 LPDWORD lpNumberOfCharsWritten,
1091 LPVOID lpReserved)
1092 {
1093 return IntWriteConsole(hConsoleOutput,
1094 (PVOID)lpBuffer,
1095 nNumberOfCharsToWrite,
1096 lpNumberOfCharsWritten,
1097 lpReserved,
1098 FALSE);
1099 }
1100
1101
1102 /*--------------------------------------------------------------
1103 * WriteConsoleInputW
1104 *
1105 * @implemented
1106 */
1107 BOOL
1108 WINAPI
1109 WriteConsoleInputW(HANDLE hConsoleInput,
1110 CONST INPUT_RECORD *lpBuffer,
1111 DWORD nLength,
1112 LPDWORD lpNumberOfEventsWritten)
1113 {
1114 return IntWriteConsoleInput(hConsoleInput,
1115 (PINPUT_RECORD)lpBuffer,
1116 nLength,
1117 lpNumberOfEventsWritten,
1118 TRUE);
1119 }
1120
1121
1122 /*--------------------------------------------------------------
1123 * WriteConsoleInputA
1124 *
1125 * @implemented
1126 */
1127 BOOL
1128 WINAPI
1129 WriteConsoleInputA(HANDLE hConsoleInput,
1130 CONST INPUT_RECORD *lpBuffer,
1131 DWORD nLength,
1132 LPDWORD lpNumberOfEventsWritten)
1133 {
1134 return IntWriteConsoleInput(hConsoleInput,
1135 (PINPUT_RECORD)lpBuffer,
1136 nLength,
1137 lpNumberOfEventsWritten,
1138 FALSE);
1139 }
1140
1141
1142 /*--------------------------------------------------------------
1143 * WriteConsoleOutputW
1144 *
1145 * @implemented
1146 */
1147 BOOL
1148 WINAPI
1149 WriteConsoleOutputW(HANDLE hConsoleOutput,
1150 CONST CHAR_INFO *lpBuffer,
1151 COORD dwBufferSize,
1152 COORD dwBufferCoord,
1153 PSMALL_RECT lpWriteRegion)
1154 {
1155 return IntWriteConsoleOutput(hConsoleOutput,
1156 lpBuffer,
1157 dwBufferSize,
1158 dwBufferCoord,
1159 lpWriteRegion,
1160 TRUE);
1161 }
1162
1163
1164 /*--------------------------------------------------------------
1165 * WriteConsoleOutputA
1166 *
1167 * @implemented
1168 */
1169 BOOL
1170 WINAPI
1171 WriteConsoleOutputA(HANDLE hConsoleOutput,
1172 CONST CHAR_INFO *lpBuffer,
1173 COORD dwBufferSize,
1174 COORD dwBufferCoord,
1175 PSMALL_RECT lpWriteRegion)
1176 {
1177 return IntWriteConsoleOutput(hConsoleOutput,
1178 lpBuffer,
1179 dwBufferSize,
1180 dwBufferCoord,
1181 lpWriteRegion,
1182 FALSE);
1183 }
1184
1185
1186 /*--------------------------------------------------------------
1187 * WriteConsoleOutputCharacterW
1188 *
1189 * @implemented
1190 */
1191 BOOL
1192 WINAPI
1193 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
1194 LPCWSTR lpCharacter,
1195 DWORD nLength,
1196 COORD dwWriteCoord,
1197 LPDWORD lpNumberOfCharsWritten)
1198 {
1199 return IntWriteConsoleOutputCode(hConsoleOutput,
1200 CODE_UNICODE,
1201 lpCharacter,
1202 nLength,
1203 dwWriteCoord,
1204 lpNumberOfCharsWritten);
1205 }
1206
1207
1208 /*--------------------------------------------------------------
1209 * WriteConsoleOutputCharacterA
1210 *
1211 * @implemented
1212 */
1213 BOOL
1214 WINAPI
1215 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
1216 LPCSTR lpCharacter,
1217 DWORD nLength,
1218 COORD dwWriteCoord,
1219 LPDWORD lpNumberOfCharsWritten)
1220 {
1221 return IntWriteConsoleOutputCode(hConsoleOutput,
1222 CODE_ASCII,
1223 lpCharacter,
1224 nLength,
1225 dwWriteCoord,
1226 lpNumberOfCharsWritten);
1227 }
1228
1229
1230 /*--------------------------------------------------------------
1231 * WriteConsoleOutputAttribute
1232 *
1233 * @implemented
1234 */
1235 BOOL
1236 WINAPI
1237 WriteConsoleOutputAttribute(HANDLE hConsoleOutput,
1238 CONST WORD *lpAttribute,
1239 DWORD nLength,
1240 COORD dwWriteCoord,
1241 LPDWORD lpNumberOfAttrsWritten)
1242 {
1243 return IntWriteConsoleOutputCode(hConsoleOutput,
1244 CODE_ATTRIBUTE,
1245 lpAttribute,
1246 nLength,
1247 dwWriteCoord,
1248 lpNumberOfAttrsWritten);
1249 }
1250
1251
1252 /*--------------------------------------------------------------
1253 * FillConsoleOutputCharacterW
1254 *
1255 * @implemented
1256 */
1257 BOOL
1258 WINAPI
1259 FillConsoleOutputCharacterW(HANDLE hConsoleOutput,
1260 WCHAR cCharacter,
1261 DWORD nLength,
1262 COORD dwWriteCoord,
1263 LPDWORD lpNumberOfCharsWritten)
1264 {
1265 return IntFillConsoleOutputCode(hConsoleOutput,
1266 CODE_UNICODE,
1267 &cCharacter,
1268 nLength,
1269 dwWriteCoord,
1270 lpNumberOfCharsWritten);
1271 }
1272
1273
1274 /*--------------------------------------------------------------
1275 * FillConsoleOutputCharacterA
1276 *
1277 * @implemented
1278 */
1279 BOOL
1280 WINAPI
1281 FillConsoleOutputCharacterA(HANDLE hConsoleOutput,
1282 CHAR cCharacter,
1283 DWORD nLength,
1284 COORD dwWriteCoord,
1285 LPDWORD lpNumberOfCharsWritten)
1286 {
1287 return IntFillConsoleOutputCode(hConsoleOutput,
1288 CODE_ASCII,
1289 &cCharacter,
1290 nLength,
1291 dwWriteCoord,
1292 lpNumberOfCharsWritten);
1293 }
1294
1295
1296 /*--------------------------------------------------------------
1297 * FillConsoleOutputAttribute
1298 *
1299 * @implemented
1300 */
1301 BOOL
1302 WINAPI
1303 FillConsoleOutputAttribute(HANDLE hConsoleOutput,
1304 WORD wAttribute,
1305 DWORD nLength,
1306 COORD dwWriteCoord,
1307 LPDWORD lpNumberOfAttrsWritten)
1308 {
1309 return IntFillConsoleOutputCode(hConsoleOutput,
1310 CODE_ATTRIBUTE,
1311 &wAttribute,
1312 nLength,
1313 dwWriteCoord,
1314 lpNumberOfAttrsWritten);
1315 }
1316
1317 /* EOF */