Implemented ReadConsoleOutputA() and WriteConsoleInputA().
[reactos.git] / reactos / lib / kernel32 / misc / console.c
1 /* $Id: console.c,v 1.48 2002/11/12 00:48:25 mdill Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/misc/console.c
6 * PURPOSE: Win32 server console functions
7 * PROGRAMMER: ???
8 * UPDATE HISTORY:
9 * 199901?? ?? Created
10 * 19990204 EA SetConsoleTitleA
11 * 19990306 EA Stubs
12 */
13
14 /* INCLUDES ******************************************************************/
15
16 #include <ddk/ntddk.h>
17 #include <ddk/ntddblue.h>
18 #include <windows.h>
19 #include <assert.h>
20 #include <wchar.h>
21
22 #include <csrss/csrss.h>
23 #include <ntdll/csr.h>
24
25 #define NDEBUG
26 #include <kernel32/kernel32.h>
27 #include <kernel32/error.h>
28
29 /* GLOBALS *******************************************************************/
30
31 static BOOL IgnoreCtrlEvents = FALSE;
32 static ULONG NrCtrlHandlers = 0;
33 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
34
35 /* FUNCTIONS *****************************************************************/
36
37 BOOL STDCALL
38 AddConsoleAliasA (LPSTR Source,
39 LPSTR Target,
40 LPSTR ExeName)
41 {
42 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
43 return FALSE;
44 }
45
46 BOOL STDCALL
47 AddConsoleAliasW (LPWSTR Source,
48 LPWSTR Target,
49 LPWSTR ExeName)
50 {
51 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
52 return FALSE;
53 }
54
55 BOOL STDCALL
56 ConsoleMenuControl (HANDLE hConsole,
57 DWORD Unknown1,
58 DWORD Unknown2)
59 /*
60 * Undocumented
61 */
62 {
63 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
64 return FALSE;
65 }
66
67 BOOL STDCALL
68 DuplicateConsoleHandle (HANDLE hConsole,
69 DWORD Unknown1,
70 DWORD Unknown2,
71 DWORD Unknown3)
72 /*
73 * Undocumented
74 */
75 {
76 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
77 return FALSE;
78 }
79
80 DWORD STDCALL
81 ExpungeConsoleCommandHistoryW (DWORD Unknown0)
82 /*
83 * Undocumented
84 */
85 {
86 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
87 return 0;
88 }
89
90
91 DWORD STDCALL
92 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
93 /*
94 * Undocumented
95 */
96 {
97 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
98 return 0;
99 }
100
101 DWORD STDCALL
102 GetConsoleAliasW (DWORD Unknown0,
103 DWORD Unknown1,
104 DWORD Unknown2,
105 DWORD Unknown3)
106 /*
107 * Undocumented
108 */
109 {
110 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
111 return 0;
112 }
113
114
115 DWORD STDCALL
116 GetConsoleAliasA (DWORD Unknown0,
117 DWORD Unknown1,
118 DWORD Unknown2,
119 DWORD Unknown3)
120 /*
121 * Undocumented
122 */
123 {
124 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
125 return 0;
126 }
127
128 DWORD STDCALL
129 GetConsoleAliasExesW (DWORD Unknown0,
130 DWORD Unknown1)
131 /*
132 * Undocumented
133 */
134 {
135 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
136 return 0;
137 }
138
139
140
141 DWORD STDCALL
142 GetConsoleAliasExesA (DWORD Unknown0,
143 DWORD Unknown1)
144 /*
145 * Undocumented
146 */
147 {
148 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
149 return 0;
150 }
151
152
153
154 DWORD STDCALL
155 GetConsoleAliasExesLengthA (VOID)
156 /*
157 * Undocumented
158 */
159 {
160 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
161 return 0;
162 }
163
164 DWORD STDCALL
165 GetConsoleAliasExesLengthW (VOID)
166 /*
167 * Undocumented
168 */
169 {
170 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
171 return 0;
172 }
173
174 DWORD STDCALL
175 GetConsoleAliasesW (DWORD Unknown0,
176 DWORD Unknown1,
177 DWORD Unknown2)
178 /*
179 * Undocumented
180 */
181 {
182 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
183 return 0;
184 }
185
186 DWORD STDCALL
187 GetConsoleAliasesA (DWORD Unknown0,
188 DWORD Unknown1,
189 DWORD Unknown2)
190 /*
191 * Undocumented
192 */
193 {
194 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
195 return 0;
196 }
197
198 DWORD STDCALL
199 GetConsoleAliasesLengthW (DWORD Unknown0)
200 /*
201 * Undocumented
202 */
203 {
204 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
205 return 0;
206 }
207
208 DWORD STDCALL
209 GetConsoleAliasesLengthA (DWORD Unknown0)
210 /*
211 * Undocumented
212 */
213 {
214 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
215 return 0;
216 }
217
218 DWORD STDCALL
219 GetConsoleCommandHistoryW (DWORD Unknown0,
220 DWORD Unknown1,
221 DWORD Unknown2)
222 /*
223 * Undocumented
224 */
225 {
226 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
227 return 0;
228 }
229
230 DWORD STDCALL
231 GetConsoleCommandHistoryA (DWORD Unknown0,
232 DWORD Unknown1,
233 DWORD Unknown2)
234 /*
235 * Undocumented
236 */
237 {
238 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
239 return 0;
240 }
241
242 DWORD STDCALL
243 GetConsoleCommandHistoryLengthW (DWORD Unknown0)
244 /*
245 * Undocumented
246 */
247 {
248 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
249 return 0;
250 }
251
252 DWORD STDCALL
253 GetConsoleCommandHistoryLengthA (DWORD Unknown0)
254 /*
255 * Undocumented
256 */
257 {
258 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
259 return 0;
260 }
261
262 DWORD STDCALL
263 GetConsoleDisplayMode (LPDWORD lpdwMode)
264 /*
265 * FUNCTION: Get the console display mode
266 * ARGUMENTS:
267 * lpdwMode - Address of variable that receives the current value
268 * of display mode
269 * STATUS: Undocumented
270 */
271 {
272 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
273 return 0;
274 }
275
276 DWORD STDCALL
277 GetConsoleFontInfo (DWORD Unknown0,
278 DWORD Unknown1,
279 DWORD Unknown2,
280 DWORD Unknown3)
281 /*
282 * Undocumented
283 */
284 {
285 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
286 return 0;
287 }
288
289 DWORD STDCALL
290 GetConsoleFontSize(HANDLE hConsoleOutput,
291 DWORD nFont)
292 {
293 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
294 return 0;
295 }
296
297 DWORD STDCALL
298 GetConsoleHardwareState (DWORD Unknown0,
299 DWORD Unknown1,
300 DWORD Unknown2)
301 /*
302 * Undocumented
303 */
304 {
305 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
306 return 0;
307 }
308
309 DWORD STDCALL
310 GetConsoleInputWaitHandle (VOID)
311 /*
312 * Undocumented
313 */
314 {
315 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
316 return FALSE;
317 }
318
319 DWORD STDCALL
320 GetCurrentConsoleFont(HANDLE hConsoleOutput,
321 BOOL bMaximumWindow,
322 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
323 {
324 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
325 return 0;
326 }
327
328 ULONG STDCALL
329 GetNumberOfConsoleFonts (VOID)
330 /*
331 * Undocumented
332 */
333 {
334 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
335 return 1; /* FIXME: call csrss.exe */
336 }
337
338 DWORD STDCALL
339 InvalidateConsoleDIBits (DWORD Unknown0,
340 DWORD Unknown1)
341 /*
342 * Undocumented
343 */
344 {
345 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
346 return 0;
347 }
348
349 DWORD STDCALL
350 OpenConsoleW (DWORD Unknown0,
351 DWORD Unknown1,
352 DWORD Unknown2,
353 DWORD Unknown3)
354 /*
355 * Undocumented
356 */
357 {
358 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
359 return 0;
360 }
361
362 WINBOOL STDCALL
363 SetConsoleCommandHistoryMode (DWORD dwMode)
364 /*
365 * Undocumented
366 */
367 {
368 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
369 return FALSE;
370 }
371
372 WINBOOL STDCALL
373 SetConsoleCursor (DWORD Unknown0,
374 DWORD Unknown1)
375 /*
376 * Undocumented
377 */
378 {
379 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
380 return FALSE;
381 }
382
383 WINBOOL STDCALL
384 SetConsoleDisplayMode (HANDLE hOut,
385 DWORD dwNewMode,
386 LPDWORD lpdwOldMode)
387 /*
388 * FUNCTION: Set the console display mode.
389 * ARGUMENTS:
390 * hOut - Standard output handle.
391 * dwNewMode - New mode.
392 * lpdwOldMode - Address of a variable that receives the old mode.
393 */
394 {
395 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
396 return FALSE;
397 }
398
399 WINBOOL STDCALL
400 SetConsoleFont (DWORD Unknown0,
401 DWORD Unknown1)
402 /*
403 * Undocumented
404 */
405 {
406 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
407 return FALSE;
408 }
409
410 WINBOOL STDCALL
411 SetConsoleHardwareState (DWORD Unknown0,
412 DWORD Unknown1,
413 DWORD Unknown2)
414 /*
415 * Undocumented
416 */
417 {
418 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
419 return FALSE;
420 }
421
422 WINBOOL STDCALL
423 SetConsoleKeyShortcuts (DWORD Unknown0,
424 DWORD Unknown1,
425 DWORD Unknown2,
426 DWORD Unknown3)
427 /*
428 * Undocumented
429 */
430 {
431 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
432 return FALSE;
433 }
434
435 WINBOOL STDCALL
436 SetConsoleMaximumWindowSize (DWORD Unknown0,
437 DWORD Unknown1)
438 /*
439 * Undocumented
440 */
441 {
442 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
443 return FALSE;
444 }
445
446 WINBOOL STDCALL
447 SetConsoleMenuClose (DWORD Unknown0)
448 /*
449 * Undocumented
450 */
451 {
452 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
453 return FALSE;
454 }
455
456 WINBOOL STDCALL
457 SetConsoleNumberOfCommandsA (DWORD Unknown0,
458 DWORD Unknown1)
459 /*
460 * Undocumented
461 */
462 {
463 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
464 return FALSE;
465 }
466
467 WINBOOL STDCALL
468 SetConsoleNumberOfCommandsW (DWORD Unknown0,
469 DWORD Unknown1)
470 /*
471 * Undocumented
472 */
473 {
474 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
475 return FALSE;
476 }
477
478 WINBOOL STDCALL
479 SetConsolePalette (DWORD Unknown0,
480 DWORD Unknown1,
481 DWORD Unknown2)
482 /*
483 * Undocumented
484 */
485 {
486 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
487 return FALSE;
488 }
489
490 WINBOOL STDCALL
491 SetLastConsoleEventActive (VOID)
492 /*
493 * Undocumented
494 */
495 {
496 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
497 return FALSE;
498 }
499
500 DWORD STDCALL
501 ShowConsoleCursor (DWORD Unknown0,
502 DWORD Unknown1)
503 /*
504 * Undocumented
505 */
506 {
507 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
508 return 0;
509 }
510
511 DWORD STDCALL
512 VerifyConsoleIoHandle (DWORD Unknown0)
513 /*
514 * Undocumented
515 */
516 {
517 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
518 return 0;
519 }
520
521 DWORD STDCALL
522 WriteConsoleInputVDMA (DWORD Unknown0,
523 DWORD Unknown1,
524 DWORD Unknown2,
525 DWORD Unknown3)
526 {
527 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
528 return 0;
529 }
530
531 DWORD STDCALL
532 WriteConsoleInputVDMW (DWORD Unknown0,
533 DWORD Unknown1,
534 DWORD Unknown2,
535 DWORD Unknown3)
536 {
537 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
538 return 0;
539 }
540
541 WINBOOL STDCALL
542 CloseConsoleHandle(HANDLE Handle)
543 /*
544 * Undocumented
545 */
546 {
547 if (IsConsoleHandle (Handle) == FALSE)
548 {
549 SetLastError (ERROR_INVALID_PARAMETER);
550 return FALSE;
551 }
552 /* FIXME: call CSRSS */
553 return TRUE/*FALSE*/;
554 }
555
556 BOOLEAN STDCALL
557 IsConsoleHandle(HANDLE Handle)
558 {
559 if ((((ULONG)Handle) & 0x10000003) == 0x3)
560 {
561 return(TRUE);
562 }
563 return(FALSE);
564 }
565
566 HANDLE STDCALL
567 GetStdHandle(DWORD nStdHandle)
568 /*
569 * FUNCTION: Get a handle for the standard input, standard output
570 * and a standard error device.
571 * ARGUMENTS:
572 * nStdHandle - Specifies the device for which to return the handle.
573 * RETURNS: If the function succeeds, the return value is the handle
574 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
575 */
576 {
577 PRTL_USER_PROCESS_PARAMETERS Ppb;
578
579 Ppb = NtCurrentPeb()->ProcessParameters;
580 switch (nStdHandle)
581 {
582 case STD_INPUT_HANDLE: return Ppb->hStdInput;
583 case STD_OUTPUT_HANDLE: return Ppb->hStdOutput;
584 case STD_ERROR_HANDLE: return Ppb->hStdError;
585 }
586 SetLastError (ERROR_INVALID_PARAMETER);
587 return INVALID_HANDLE_VALUE;
588 }
589
590 WINBASEAPI BOOL WINAPI
591 SetStdHandle(DWORD nStdHandle,
592 HANDLE hHandle)
593 /*
594 * FUNCTION: Set the handle for the standard input, standard output or
595 * the standard error device.
596 * ARGUMENTS:
597 * nStdHandle - Specifies the handle to be set.
598 * hHandle - The handle to set.
599 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
600 */
601 {
602 PRTL_USER_PROCESS_PARAMETERS Ppb;
603
604 Ppb = NtCurrentPeb()->ProcessParameters;
605
606 /* More checking needed? */
607 if (hHandle == INVALID_HANDLE_VALUE)
608 {
609 SetLastError (ERROR_INVALID_HANDLE);
610 return FALSE;
611 }
612
613 SetLastError(ERROR_SUCCESS); /* OK */
614 switch (nStdHandle)
615 {
616 case STD_INPUT_HANDLE:
617 Ppb->hStdInput = hHandle;
618 return TRUE;
619 case STD_OUTPUT_HANDLE:
620 Ppb->hStdOutput = hHandle;
621 return TRUE;
622 case STD_ERROR_HANDLE:
623 Ppb->hStdError = hHandle;
624 return TRUE;
625 }
626 SetLastError (ERROR_INVALID_PARAMETER);
627 return FALSE;
628 }
629
630
631 /*--------------------------------------------------------------
632 * WriteConsoleA
633 */
634 WINBOOL STDCALL
635 WriteConsoleA(HANDLE hConsoleOutput,
636 CONST VOID *lpBuffer,
637 DWORD nNumberOfCharsToWrite,
638 LPDWORD lpNumberOfCharsWritten,
639 LPVOID lpReserved)
640 {
641 PCSRSS_API_REQUEST Request;
642 CSRSS_API_REPLY Reply;
643 NTSTATUS Status;
644 USHORT Size;
645 ULONG MessageSize;
646
647 Request = RtlAllocateHeap(GetProcessHeap(),
648 HEAP_ZERO_MEMORY,
649 sizeof(CSRSS_API_REQUEST) +
650 CSRSS_MAX_WRITE_CONSOLE_REQUEST);
651 if (Request == NULL)
652 {
653 SetLastError(ERROR_OUTOFMEMORY);
654 return(FALSE);
655 }
656
657 Request->Type = CSRSS_WRITE_CONSOLE;
658 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
659 if (lpNumberOfCharsWritten != NULL)
660 *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
661 while (nNumberOfCharsToWrite)
662 {
663 if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
664 {
665 Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
666 }
667 else
668 {
669 Size = nNumberOfCharsToWrite;
670 }
671 Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
672
673 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
674
675 MessageSize = CSRSS_REQUEST_HEADER_SIZE +
676 sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
677 Status = CsrClientCallServer(Request,
678 &Reply,
679 MessageSize,
680 sizeof(CSRSS_API_REPLY));
681
682 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
683 {
684 RtlFreeHeap(GetProcessHeap(), 0, Request);
685 SetLastErrorByStatus(Status);
686 return(FALSE);
687 }
688 nNumberOfCharsToWrite -= Size;
689 lpBuffer += Size;
690 }
691 RtlFreeHeap(GetProcessHeap(), 0, Request);
692 return TRUE;
693 }
694
695
696 /*--------------------------------------------------------------
697 * ReadConsoleA
698 */
699 WINBOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
700 LPVOID lpBuffer,
701 DWORD nNumberOfCharsToRead,
702 LPDWORD lpNumberOfCharsRead,
703 LPVOID lpReserved)
704 {
705 CSRSS_API_REQUEST Request;
706 PCSRSS_API_REPLY Reply;
707 NTSTATUS Status;
708 ULONG CharsRead = 0;
709
710 Reply = RtlAllocateHeap(GetProcessHeap(),
711 HEAP_ZERO_MEMORY,
712 sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
713 if (Reply == NULL)
714 {
715 SetLastError(ERROR_OUTOFMEMORY);
716 return(FALSE);
717 }
718
719 Request.Type = CSRSS_READ_CONSOLE;
720 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
721 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
722 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
723 Status = CsrClientCallServer(&Request,
724 Reply,
725 sizeof(CSRSS_API_REQUEST),
726 sizeof(CSRSS_API_REPLY) +
727 Request.Data.ReadConsoleRequest.NrCharactersToRead);
728 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
729 {
730 DbgPrint( "CSR returned error in ReadConsole\n" );
731 SetLastErrorByStatus ( Status );
732 RtlFreeHeap( GetProcessHeap(), 0, Reply );
733 return(FALSE);
734 }
735 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
736 Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
737 /* There may not be any chars or lines to read yet, so wait */
738 while( Reply->Status == STATUS_PENDING )
739 {
740 /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
741 nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
742 /* don't overflow caller's buffer, even if you still don't have a complete line */
743 if( !nNumberOfCharsToRead )
744 break;
745 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
746 /* copy any chars already read to buffer */
747 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
748 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
749 /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
750 Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
751 if( !NT_SUCCESS( Status ) )
752 {
753 DbgPrint( "Wait for console input failed!\n" );
754 RtlFreeHeap( GetProcessHeap(), 0, Reply );
755 return FALSE;
756 }
757 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
758 Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
759 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
760 {
761 SetLastErrorByStatus ( Status );
762 RtlFreeHeap( GetProcessHeap(), 0, Reply );
763 return FALSE;
764 }
765 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
766 {
767 // delete last char
768 if( CharsRead )
769 {
770 CharsRead--;
771 nNumberOfCharsToRead++;
772 }
773 Reply->Status = STATUS_PENDING; // retry
774 }
775 }
776 /* copy data to buffer, count total returned, and return */
777 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
778 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
779 if (lpNumberOfCharsRead != NULL)
780 *lpNumberOfCharsRead = CharsRead;
781 RtlFreeHeap(GetProcessHeap(),
782 0,
783 Reply);
784
785 return(TRUE);
786 }
787
788
789 /*--------------------------------------------------------------
790 * AllocConsole
791 */
792 WINBOOL STDCALL AllocConsole(VOID)
793 {
794 CSRSS_API_REQUEST Request;
795 CSRSS_API_REPLY Reply;
796 NTSTATUS Status;
797
798 Request.Type = CSRSS_ALLOC_CONSOLE;
799 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
800 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
801 {
802 SetLastErrorByStatus ( Status );
803 return FALSE;
804 }
805 SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
806 SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
807 SetStdHandle( STD_ERROR_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
808 return TRUE;
809 }
810
811
812 /*--------------------------------------------------------------
813 * FreeConsole
814 */
815 WINBOOL STDCALL FreeConsole(VOID)
816 {
817 DbgPrint("FreeConsole() is unimplemented\n");
818 return FALSE;
819 }
820
821
822 /*--------------------------------------------------------------
823 * GetConsoleScreenBufferInfo
824 */
825 WINBOOL
826 STDCALL
827 GetConsoleScreenBufferInfo(
828 HANDLE hConsoleOutput,
829 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
830 )
831 {
832 CSRSS_API_REQUEST Request;
833 CSRSS_API_REPLY Reply;
834 NTSTATUS Status;
835
836 Request.Type = CSRSS_SCREEN_BUFFER_INFO;
837 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
838 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
839 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
840 {
841 SetLastErrorByStatus ( Status );
842 return FALSE;
843 }
844 *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
845 return TRUE;
846 }
847
848
849 /*--------------------------------------------------------------
850 * SetConsoleCursorPosition
851 */
852 WINBOOL
853 STDCALL
854 SetConsoleCursorPosition(
855 HANDLE hConsoleOutput,
856 COORD dwCursorPosition
857 )
858 {
859 CSRSS_API_REQUEST Request;
860 CSRSS_API_REPLY Reply;
861 NTSTATUS Status;
862
863 Request.Type = CSRSS_SET_CURSOR;
864 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
865 Request.Data.SetCursorRequest.Position = dwCursorPosition;
866 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
867 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
868 {
869 SetLastErrorByStatus ( Status );
870 return FALSE;
871 }
872 return TRUE;
873 }
874
875
876 /*--------------------------------------------------------------
877 * FillConsoleOutputCharacterA
878 */
879 WINBOOL STDCALL
880 FillConsoleOutputCharacterA(
881 HANDLE hConsoleOutput,
882 CHAR cCharacter,
883 DWORD nLength,
884 COORD dwWriteCoord,
885 LPDWORD lpNumberOfCharsWritten
886 )
887 {
888 CSRSS_API_REQUEST Request;
889 CSRSS_API_REPLY Reply;
890 NTSTATUS Status;
891
892 Request.Type = CSRSS_FILL_OUTPUT;
893 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
894 Request.Data.FillOutputRequest.Char = cCharacter;
895 Request.Data.FillOutputRequest.Position = dwWriteCoord;
896 Request.Data.FillOutputRequest.Length = nLength;
897 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
898 if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
899 {
900 SetLastErrorByStatus(Status);
901 return(FALSE);
902 }
903 if (lpNumberOfCharsWritten != NULL)
904 *lpNumberOfCharsWritten = nLength;
905 return(TRUE);
906 }
907
908
909 /*--------------------------------------------------------------
910 * FillConsoleOutputCharacterW
911 */
912 WINBOOL
913 STDCALL
914 FillConsoleOutputCharacterW(
915 HANDLE hConsoleOutput,
916 WCHAR cCharacter,
917 DWORD nLength,
918 COORD dwWriteCoord,
919 LPDWORD lpNumberOfCharsWritten
920 )
921 {
922 /* TO DO */
923 return FALSE;
924 }
925
926
927 /*--------------------------------------------------------------
928 * PeekConsoleInputA
929 */
930 WINBASEAPI
931 BOOL
932 WINAPI
933 PeekConsoleInputA(
934 HANDLE hConsoleInput,
935 PINPUT_RECORD lpBuffer,
936 DWORD nLength,
937 LPDWORD lpNumberOfEventsRead
938 )
939 {
940 PCSRSS_API_REQUEST Request;
941 CSRSS_API_REPLY Reply;
942 NTSTATUS Status;
943 PVOID BufferBase;
944 PVOID BufferTargetBase;
945 DWORD Size;
946
947 if(lpBuffer == NULL)
948 {
949 SetLastError(ERROR_INVALID_PARAMETER);
950 return FALSE;
951 }
952
953 Size = nLength * sizeof(INPUT_RECORD);
954
955 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
956 if(!NT_SUCCESS(Status))
957 {
958 SetLastErrorByStatus(Status);
959 return FALSE;
960 }
961
962 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
963 if(Request == NULL)
964 {
965 CsrReleaseParameterBuffer(BufferBase);
966 SetLastError(ERROR_OUTOFMEMORY);
967 return FALSE;
968 }
969
970 Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
971 Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
972 Request->Data.PeekConsoleInputRequest.Length = nLength;
973 Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
974
975 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
976
977 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
978 {
979 RtlFreeHeap(GetProcessHeap(), 0, Request);
980 CsrReleaseParameterBuffer(BufferBase);
981 return FALSE;
982 }
983
984 memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
985
986 if(lpNumberOfEventsRead != NULL)
987 *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
988
989 RtlFreeHeap(GetProcessHeap(), 0, Request);
990 CsrReleaseParameterBuffer(BufferBase);
991
992 return TRUE;
993 }
994
995
996 /*--------------------------------------------------------------
997 * PeekConsoleInputW
998 */
999 WINBASEAPI
1000 BOOL
1001 WINAPI
1002 PeekConsoleInputW(
1003 HANDLE hConsoleInput,
1004 PINPUT_RECORD lpBuffer,
1005 DWORD nLength,
1006 LPDWORD lpNumberOfEventsRead
1007 )
1008 {
1009 /* TO DO */
1010 return FALSE;
1011 }
1012
1013
1014 /*--------------------------------------------------------------
1015 * ReadConsoleInputA
1016 */
1017 WINBASEAPI BOOL WINAPI
1018 ReadConsoleInputA(HANDLE hConsoleInput,
1019 PINPUT_RECORD lpBuffer,
1020 DWORD nLength,
1021 LPDWORD lpNumberOfEventsRead)
1022 {
1023 CSRSS_API_REQUEST Request;
1024 CSRSS_API_REPLY Reply;
1025 DWORD NumEventsRead;
1026 NTSTATUS Status;
1027
1028 Request.Type = CSRSS_READ_INPUT;
1029 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1030 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1031 sizeof(CSRSS_API_REPLY));
1032 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1033 {
1034 SetLastErrorByStatus(Status);
1035 return(FALSE);
1036 }
1037
1038 while (Status == STATUS_PENDING)
1039 {
1040 Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE,
1041 0);
1042 if(!NT_SUCCESS(Status))
1043 {
1044 SetLastErrorByStatus(Status);
1045 return FALSE;
1046 }
1047
1048 Request.Type = CSRSS_READ_INPUT;
1049 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1050 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1051 sizeof(CSRSS_API_REPLY));
1052 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1053 {
1054 SetLastErrorByStatus(Status);
1055 return(FALSE);
1056 }
1057 }
1058
1059 NumEventsRead = 0;
1060 *lpBuffer = Reply.Data.ReadInputReply.Input;
1061 lpBuffer++;
1062 NumEventsRead++;
1063
1064 while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
1065 {
1066 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1067 sizeof(CSRSS_API_REPLY));
1068 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1069 {
1070 SetLastErrorByStatus(Status);
1071 return(FALSE);
1072 }
1073
1074 if (Status == STATUS_PENDING)
1075 {
1076 break;
1077 }
1078
1079 *lpBuffer = Reply.Data.ReadInputReply.Input;
1080 lpBuffer++;
1081 NumEventsRead++;
1082
1083 }
1084 *lpNumberOfEventsRead = NumEventsRead;
1085
1086 return TRUE;
1087 }
1088
1089
1090 /*--------------------------------------------------------------
1091 * ReadConsoleInputW
1092 */
1093 WINBASEAPI
1094 BOOL
1095 WINAPI
1096 ReadConsoleInputW(
1097 HANDLE hConsoleInput,
1098 PINPUT_RECORD lpBuffer,
1099 DWORD nLength,
1100 LPDWORD lpNumberOfEventsRead
1101 )
1102 {
1103 /* TO DO */
1104 return FALSE;
1105 }
1106
1107
1108 /*--------------------------------------------------------------
1109 * WriteConsoleInputA
1110 */
1111 WINBASEAPI
1112 BOOL
1113 WINAPI
1114 WriteConsoleInputA(
1115 HANDLE hConsoleInput,
1116 CONST INPUT_RECORD *lpBuffer,
1117 DWORD nLength,
1118 LPDWORD lpNumberOfEventsWritten
1119 )
1120 {
1121 PCSRSS_API_REQUEST Request;
1122 CSRSS_API_REPLY Reply;
1123 PVOID BufferBase, BufferTargetBase;
1124 NTSTATUS Status;
1125 DWORD Size;
1126
1127 if(lpBuffer == NULL)
1128 {
1129 SetLastError(ERROR_INVALID_PARAMETER);
1130 return FALSE;
1131 }
1132
1133 Size = nLength * sizeof(INPUT_RECORD);
1134
1135 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1136 if(!NT_SUCCESS(Status))
1137 {
1138 SetLastErrorByStatus(Status);
1139 return FALSE;
1140 }
1141
1142 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1143 if(Request == NULL)
1144 {
1145 SetLastError(ERROR_OUTOFMEMORY);
1146 CsrReleaseParameterBuffer(BufferBase);
1147 return FALSE;
1148 }
1149
1150 Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
1151 Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
1152 Request->Data.WriteConsoleInputRequest.Length = nLength;
1153 Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
1154
1155 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1156 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1157 {
1158 RtlFreeHeap(GetProcessHeap(), 0, Request);
1159 CsrReleaseParameterBuffer(BufferBase);
1160 return FALSE;
1161 }
1162
1163 if(lpNumberOfEventsWritten != NULL)
1164 lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
1165
1166 RtlFreeHeap(GetProcessHeap(), 0, Request);
1167 CsrReleaseParameterBuffer(BufferBase);
1168
1169 return TRUE;
1170 }
1171
1172
1173 /*--------------------------------------------------------------
1174 * WriteConsoleInputW
1175 */
1176 WINBASEAPI
1177 BOOL
1178 WINAPI
1179 WriteConsoleInputW(
1180 HANDLE hConsoleInput,
1181 CONST INPUT_RECORD *lpBuffer,
1182 DWORD nLength,
1183 LPDWORD lpNumberOfEventsWritten
1184 )
1185 {
1186 /* TO DO */
1187 return FALSE;
1188 }
1189
1190
1191 /*--------------------------------------------------------------
1192 * ReadConsoleOutputA
1193 */
1194 WINBASEAPI
1195 BOOL
1196 WINAPI
1197 ReadConsoleOutputA(
1198 HANDLE hConsoleOutput,
1199 PCHAR_INFO lpBuffer,
1200 COORD dwBufferSize,
1201 COORD dwBufferCoord,
1202 PSMALL_RECT lpReadRegion
1203 )
1204 {
1205 PCSRSS_API_REQUEST Request;
1206 CSRSS_API_REPLY Reply;
1207 PVOID BufferBase;
1208 PVOID BufferTargetBase;
1209 NTSTATUS Status;
1210 DWORD Size, SizeX, SizeY;
1211
1212 if(lpBuffer == NULL)
1213 {
1214 SetLastError(ERROR_INVALID_PARAMETER);
1215 return FALSE;
1216 }
1217
1218 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
1219
1220 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1221 if(!NT_SUCCESS(Status))
1222 {
1223 SetLastErrorByStatus(Status);
1224 return FALSE;
1225 }
1226
1227 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1228 if(Request == NULL)
1229 {
1230 SetLastError(ERROR_OUTOFMEMORY);
1231 CsrReleaseParameterBuffer(BufferBase);
1232 return FALSE;
1233 }
1234
1235 Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
1236 Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1237 Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
1238 Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
1239 Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
1240 Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
1241
1242 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1243 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1244 {
1245 SetLastErrorByStatus(Status);
1246 RtlFreeHeap(GetProcessHeap(), 0, Request);
1247 CsrReleaseParameterBuffer(BufferBase);
1248 return FALSE;
1249 }
1250
1251 SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
1252 SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
1253
1254 memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
1255 *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
1256
1257 RtlFreeHeap(GetProcessHeap(), 0, Request);
1258 CsrReleaseParameterBuffer(BufferBase);
1259
1260 return TRUE;
1261 }
1262
1263
1264 /*--------------------------------------------------------------
1265 * ReadConsoleOutputW
1266 */
1267 WINBASEAPI
1268 BOOL
1269 WINAPI
1270 ReadConsoleOutputW(
1271 HANDLE hConsoleOutput,
1272 PCHAR_INFO lpBuffer,
1273 COORD dwBufferSize,
1274 COORD dwBufferCoord,
1275 PSMALL_RECT lpReadRegion
1276 )
1277 {
1278 /* TO DO */
1279 return FALSE;
1280 }
1281
1282 /*--------------------------------------------------------------
1283 * WriteConsoleOutputA
1284 */
1285 WINBASEAPI BOOL WINAPI
1286 WriteConsoleOutputA(HANDLE hConsoleOutput,
1287 CONST CHAR_INFO *lpBuffer,
1288 COORD dwBufferSize,
1289 COORD dwBufferCoord,
1290 PSMALL_RECT lpWriteRegion)
1291 {
1292 PCSRSS_API_REQUEST Request;
1293 CSRSS_API_REPLY Reply;
1294 NTSTATUS Status;
1295 ULONG Size;
1296 BOOLEAN Result;
1297 ULONG i, j;
1298 PVOID BufferBase;
1299 PVOID BufferTargetBase;
1300
1301 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
1302
1303 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
1304 Size,
1305 &BufferBase,
1306 &BufferTargetBase);
1307 if (!NT_SUCCESS(Status))
1308 {
1309 SetLastErrorByStatus(Status);
1310 return(FALSE);
1311 }
1312
1313 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY,
1314 sizeof(CSRSS_API_REQUEST));
1315 if (Request == NULL)
1316 {
1317 SetLastError(ERROR_OUTOFMEMORY);
1318 return FALSE;
1319 }
1320 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
1321 Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1322 Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
1323 Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
1324 Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
1325 Request->Data.WriteConsoleOutputRequest.CharInfo =
1326 (CHAR_INFO*)BufferTargetBase;
1327
1328 Status = CsrClientCallServer(Request, &Reply,
1329 sizeof(CSRSS_API_REQUEST),
1330 sizeof(CSRSS_API_REPLY));
1331 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1332 {
1333 RtlFreeHeap(GetProcessHeap(), 0, Request);
1334 SetLastErrorByStatus(Status);
1335 return FALSE;
1336 }
1337
1338 *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
1339 RtlFreeHeap(GetProcessHeap(), 0, Request);
1340 CsrReleaseParameterBuffer(BufferBase);
1341 return(TRUE);
1342 }
1343
1344
1345 /*--------------------------------------------------------------
1346 * WriteConsoleOutputW
1347 */
1348 WINBASEAPI
1349 BOOL
1350 WINAPI
1351 WriteConsoleOutputW(
1352 HANDLE hConsoleOutput,
1353 CONST CHAR_INFO *lpBuffer,
1354 COORD dwBufferSize,
1355 COORD dwBufferCoord,
1356 PSMALL_RECT lpWriteRegion
1357 )
1358 {
1359 /* TO DO */
1360 return FALSE;
1361 }
1362
1363
1364 /*--------------------------------------------------------------
1365 * ReadConsoleOutputCharacterA
1366 */
1367 WINBASEAPI
1368 BOOL
1369 WINAPI
1370 ReadConsoleOutputCharacterA(
1371 HANDLE hConsoleOutput,
1372 LPSTR lpCharacter,
1373 DWORD nLength,
1374 COORD dwReadCoord,
1375 LPDWORD lpNumberOfCharsRead
1376 )
1377 {
1378 CSRSS_API_REQUEST Request;
1379 PCSRSS_API_REPLY Reply;
1380 NTSTATUS Status;
1381 DWORD Size;
1382
1383 Reply = RtlAllocateHeap(GetProcessHeap(),
1384 HEAP_ZERO_MEMORY,
1385 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR);
1386 if (Reply == NULL)
1387 {
1388 SetLastError(ERROR_OUTOFMEMORY);
1389 return(FALSE);
1390 }
1391
1392 if (lpNumberOfCharsRead != NULL)
1393 *lpNumberOfCharsRead = nLength;
1394
1395 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
1396 Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1397 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
1398
1399 while (nLength != 0)
1400 {
1401 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
1402 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
1403 else
1404 Size = nLength;
1405
1406 Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
1407
1408 Status = CsrClientCallServer(&Request,
1409 Reply,
1410 sizeof(CSRSS_API_REQUEST),
1411 sizeof(CSRSS_API_REPLY) + Size);
1412 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1413 {
1414 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1415 SetLastErrorByStatus(Status);
1416 return(FALSE);
1417 }
1418
1419 memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
1420 lpCharacter += Size;
1421 nLength -= Size;
1422 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
1423 }
1424
1425 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1426
1427 return(TRUE);
1428 }
1429
1430
1431 /*--------------------------------------------------------------
1432 * ReadConsoleOutputCharacterW
1433 */
1434 WINBASEAPI
1435 BOOL
1436 WINAPI
1437 ReadConsoleOutputCharacterW(
1438 HANDLE hConsoleOutput,
1439 LPWSTR lpCharacter,
1440 DWORD nLength,
1441 COORD dwReadCoord,
1442 LPDWORD lpNumberOfCharsRead
1443 )
1444 {
1445 /* TO DO */
1446 return FALSE;
1447 }
1448
1449
1450 /*--------------------------------------------------------------
1451 * ReadConsoleOutputAttribute
1452 */
1453 WINBASEAPI
1454 BOOL
1455 WINAPI
1456 ReadConsoleOutputAttribute(
1457 HANDLE hConsoleOutput,
1458 LPWORD lpAttribute,
1459 DWORD nLength,
1460 COORD dwReadCoord,
1461 LPDWORD lpNumberOfAttrsRead
1462 )
1463 {
1464 CSRSS_API_REQUEST Request;
1465 PCSRSS_API_REPLY Reply;
1466 NTSTATUS Status;
1467 DWORD Size, i;
1468
1469 Reply = RtlAllocateHeap(GetProcessHeap(),
1470 HEAP_ZERO_MEMORY,
1471 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
1472 if (Reply == NULL)
1473 {
1474 SetLastError(ERROR_OUTOFMEMORY);
1475 return(FALSE);
1476 }
1477
1478 if (lpNumberOfAttrsRead != NULL)
1479 *lpNumberOfAttrsRead = nLength;
1480
1481 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
1482 Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1483 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
1484
1485 while (nLength != 0)
1486 {
1487 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
1488 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
1489 else
1490 Size = nLength;
1491
1492 Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
1493
1494 Status = CsrClientCallServer(&Request,
1495 Reply,
1496 sizeof(CSRSS_API_REQUEST),
1497 sizeof(CSRSS_API_REPLY) + Size);
1498 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1499 {
1500 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1501 SetLastErrorByStatus(Status);
1502 return(FALSE);
1503 }
1504
1505 // Convert CHARs to WORDs
1506 for(i = 0; i < Size; ++i)
1507 *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
1508
1509 nLength -= Size;
1510 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
1511 }
1512
1513 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1514
1515 return(TRUE);
1516 }
1517
1518
1519 /*--------------------------------------------------------------
1520 * WriteConsoleOutputCharacterA
1521 */
1522 WINBASEAPI BOOL WINAPI
1523 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
1524 LPCSTR lpCharacter,
1525 DWORD nLength,
1526 COORD dwWriteCoord,
1527 LPDWORD lpNumberOfCharsWritten)
1528 {
1529 PCSRSS_API_REQUEST Request;
1530 CSRSS_API_REPLY Reply;
1531 NTSTATUS Status;
1532 WORD Size;
1533
1534 Request = RtlAllocateHeap(GetProcessHeap(),
1535 HEAP_ZERO_MEMORY,
1536 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR);
1537 if( !Request )
1538 {
1539 SetLastError( ERROR_OUTOFMEMORY );
1540 return FALSE;
1541 }
1542 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
1543 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1544 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
1545 if( lpNumberOfCharsWritten )
1546 *lpNumberOfCharsWritten = nLength;
1547 while( nLength )
1548 {
1549 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
1550 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
1551 memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
1552 lpCharacter,
1553 Size );
1554 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
1555 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1556 {
1557 RtlFreeHeap( GetProcessHeap(), 0, Request );
1558 SetLastErrorByStatus ( Status );
1559 return FALSE;
1560 }
1561 nLength -= Size;
1562 lpCharacter += Size;
1563 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
1564 }
1565 return TRUE;
1566 }
1567
1568
1569 /*--------------------------------------------------------------
1570 * WriteConsoleOutputCharacterW
1571 */
1572 WINBASEAPI
1573 BOOL
1574 WINAPI
1575 WriteConsoleOutputCharacterW(
1576 HANDLE hConsoleOutput,
1577 LPCWSTR lpCharacter,
1578 DWORD nLength,
1579 COORD dwWriteCoord,
1580 LPDWORD lpNumberOfCharsWritten
1581 )
1582 {
1583 /* TO DO */
1584 return FALSE;
1585 }
1586
1587
1588
1589 /*--------------------------------------------------------------
1590 * WriteConsoleOutputAttribute
1591 */
1592 WINBASEAPI
1593 BOOL
1594 WINAPI
1595 WriteConsoleOutputAttribute(
1596 HANDLE hConsoleOutput,
1597 CONST WORD *lpAttribute,
1598 DWORD nLength,
1599 COORD dwWriteCoord,
1600 LPDWORD lpNumberOfAttrsWritten
1601 )
1602 {
1603 PCSRSS_API_REQUEST Request;
1604 CSRSS_API_REPLY Reply;
1605 NTSTATUS Status;
1606 WORD Size;
1607 int c;
1608
1609 Request = RtlAllocateHeap(GetProcessHeap(),
1610 HEAP_ZERO_MEMORY,
1611 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
1612 if( !Request )
1613 {
1614 SetLastError( ERROR_OUTOFMEMORY );
1615 return FALSE;
1616 }
1617 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
1618 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1619 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
1620 if( lpNumberOfAttrsWritten )
1621 *lpNumberOfAttrsWritten = nLength;
1622 while( nLength )
1623 {
1624 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
1625 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
1626 for( c = 0; c < ( Size * 2 ); c++ )
1627 Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
1628 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
1629 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1630 {
1631 RtlFreeHeap( GetProcessHeap(), 0, Request );
1632 SetLastErrorByStatus ( Status );
1633 return FALSE;
1634 }
1635 nLength -= Size;
1636 lpAttribute += Size;
1637 Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
1638 }
1639 return TRUE;
1640 }
1641
1642
1643 /*--------------------------------------------------------------
1644 * FillConsoleOutputAttribute
1645 */
1646 WINBASEAPI
1647 BOOL
1648 WINAPI
1649 FillConsoleOutputAttribute(
1650 HANDLE hConsoleOutput,
1651 WORD wAttribute,
1652 DWORD nLength,
1653 COORD dwWriteCoord,
1654 LPDWORD lpNumberOfAttrsWritten
1655 )
1656 {
1657 CSRSS_API_REQUEST Request;
1658 CSRSS_API_REPLY Reply;
1659 NTSTATUS Status;
1660
1661 Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
1662 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1663 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
1664 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
1665 Request.Data.FillOutputAttribRequest.Length = nLength;
1666 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1667 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1668 {
1669 SetLastErrorByStatus ( Status );
1670 return FALSE;
1671 }
1672 if( lpNumberOfAttrsWritten )
1673 *lpNumberOfAttrsWritten = nLength;
1674 return TRUE;
1675 }
1676
1677
1678 /*--------------------------------------------------------------
1679 * GetConsoleMode
1680 */
1681 WINBASEAPI
1682 BOOL
1683 WINAPI
1684 GetConsoleMode(
1685 HANDLE hConsoleHandle,
1686 LPDWORD lpMode
1687 )
1688 {
1689 CSRSS_API_REQUEST Request;
1690 CSRSS_API_REPLY Reply;
1691 NTSTATUS Status;
1692
1693 Request.Type = CSRSS_GET_MODE;
1694 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
1695 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1696 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1697 {
1698 SetLastErrorByStatus ( Status );
1699 return FALSE;
1700 }
1701 *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
1702 return TRUE;
1703 }
1704
1705
1706 /*--------------------------------------------------------------
1707 * GetNumberOfConsoleInputEvents
1708 */
1709 WINBASEAPI
1710 BOOL
1711 WINAPI
1712 GetNumberOfConsoleInputEvents(
1713 HANDLE hConsoleInput,
1714 LPDWORD lpNumberOfEvents
1715 )
1716 {
1717 CSRSS_API_REQUEST Request;
1718 CSRSS_API_REPLY Reply;
1719 NTSTATUS Status;
1720
1721 if(lpNumberOfEvents == NULL)
1722 {
1723 SetLastError(ERROR_INVALID_PARAMETER);
1724 return FALSE;
1725 }
1726
1727 Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
1728 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
1729 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1730 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Reply.Status))
1731 {
1732 SetLastErrorByStatus(Reply.Status);
1733 return FALSE;
1734 }
1735
1736 *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
1737
1738 return TRUE;
1739 }
1740
1741
1742 /*--------------------------------------------------------------
1743 * GetLargestConsoleWindowSize
1744 */
1745 WINBASEAPI
1746 COORD
1747 WINAPI
1748 GetLargestConsoleWindowSize(
1749 HANDLE hConsoleOutput
1750 )
1751 {
1752 #if 1 /* FIXME: */
1753 COORD Coord = {80,25};
1754
1755 /* TO DO */
1756 return Coord;
1757 #endif
1758 }
1759
1760
1761 /*--------------------------------------------------------------
1762 * GetConsoleCursorInfo
1763 */
1764 WINBASEAPI
1765 BOOL
1766 WINAPI
1767 GetConsoleCursorInfo(
1768 HANDLE hConsoleOutput,
1769 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
1770 )
1771 {
1772 CSRSS_API_REQUEST Request;
1773 CSRSS_API_REPLY Reply;
1774 NTSTATUS Status;
1775
1776 Request.Type = CSRSS_GET_CURSOR_INFO;
1777 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
1778 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1779
1780 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1781 {
1782 SetLastErrorByStatus ( Status );
1783 return FALSE;
1784 }
1785 *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
1786 return TRUE;
1787 }
1788
1789
1790 /*--------------------------------------------------------------
1791 * GetNumberOfConsoleMouseButtons
1792 */
1793 WINBASEAPI
1794 BOOL
1795 WINAPI
1796 GetNumberOfConsoleMouseButtons(
1797 LPDWORD lpNumberOfMouseButtons
1798 )
1799 {
1800 /* TO DO */
1801 return FALSE;
1802 }
1803
1804
1805 /*--------------------------------------------------------------
1806 * SetConsoleMode
1807 */
1808 WINBASEAPI
1809 BOOL
1810 WINAPI
1811 SetConsoleMode(
1812 HANDLE hConsoleHandle,
1813 DWORD dwMode
1814 )
1815 {
1816 CSRSS_API_REQUEST Request;
1817 CSRSS_API_REPLY Reply;
1818 NTSTATUS Status;
1819
1820 Request.Type = CSRSS_SET_MODE;
1821 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
1822 Request.Data.SetConsoleModeRequest.Mode = dwMode;
1823 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1824 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1825 {
1826 SetLastErrorByStatus ( Status );
1827 return FALSE;
1828 }
1829 return TRUE;
1830 }
1831
1832
1833 /*--------------------------------------------------------------
1834 * SetConsoleActiveScreenBuffer
1835 */
1836 WINBASEAPI
1837 BOOL
1838 WINAPI
1839 SetConsoleActiveScreenBuffer(
1840 HANDLE hConsoleOutput
1841 )
1842 {
1843 CSRSS_API_REQUEST Request;
1844 CSRSS_API_REPLY Reply;
1845 NTSTATUS Status;
1846
1847 Request.Type = CSRSS_SET_SCREEN_BUFFER;
1848 Request.Data.SetActiveScreenBufferRequest.OutputHandle = hConsoleOutput;
1849 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1850 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1851 {
1852 SetLastErrorByStatus ( Status );
1853 return FALSE;
1854 }
1855 return TRUE;
1856 }
1857
1858
1859 /*--------------------------------------------------------------
1860 * FlushConsoleInputBuffer
1861 */
1862 WINBASEAPI
1863 BOOL
1864 WINAPI
1865 FlushConsoleInputBuffer(
1866 HANDLE hConsoleInput
1867 )
1868 {
1869 CSRSS_API_REQUEST Request;
1870 CSRSS_API_REPLY Reply;
1871 NTSTATUS Status;
1872
1873 Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
1874 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
1875 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1876 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1877 {
1878 SetLastErrorByStatus ( Status );
1879 return FALSE;
1880 }
1881 return TRUE;
1882 }
1883
1884
1885 /*--------------------------------------------------------------
1886 * SetConsoleScreenBufferSize
1887 */
1888 WINBASEAPI
1889 BOOL
1890 WINAPI
1891 SetConsoleScreenBufferSize(
1892 HANDLE hConsoleOutput,
1893 COORD dwSize
1894 )
1895 {
1896 /* TO DO */
1897 return FALSE;
1898 }
1899
1900 /*--------------------------------------------------------------
1901 * SetConsoleCursorInfo
1902 */
1903 WINBASEAPI
1904 BOOL
1905 WINAPI
1906 SetConsoleCursorInfo(
1907 HANDLE hConsoleOutput,
1908 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
1909 )
1910 {
1911 CSRSS_API_REQUEST Request;
1912 CSRSS_API_REPLY Reply;
1913 NTSTATUS Status;
1914
1915 Request.Type = CSRSS_SET_CURSOR_INFO;
1916 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
1917 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
1918 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1919
1920 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1921 {
1922 SetLastErrorByStatus ( Status );
1923 return FALSE;
1924 }
1925 return TRUE;
1926 }
1927
1928
1929 /*--------------------------------------------------------------
1930 * ScrollConsoleScreenBufferA
1931 */
1932 WINBASEAPI
1933 BOOL
1934 WINAPI
1935 ScrollConsoleScreenBufferA(
1936 HANDLE hConsoleOutput,
1937 CONST SMALL_RECT *lpScrollRectangle,
1938 CONST SMALL_RECT *lpClipRectangle,
1939 COORD dwDestinationOrigin,
1940 CONST CHAR_INFO *lpFill
1941 )
1942 {
1943 CSRSS_API_REQUEST Request;
1944 CSRSS_API_REPLY Reply;
1945 NTSTATUS Status;
1946
1947 Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
1948 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
1949 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
1950
1951 if (lpClipRectangle != NULL)
1952 {
1953 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
1954 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
1955 }
1956 else
1957 {
1958 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
1959 }
1960
1961 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
1962 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
1963 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1964
1965 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1966 {
1967 SetLastErrorByStatus ( Status );
1968 return FALSE;
1969 }
1970 return TRUE;
1971 }
1972
1973
1974 /*--------------------------------------------------------------
1975 * ScrollConsoleScreenBufferW
1976 */
1977 WINBASEAPI
1978 BOOL
1979 WINAPI
1980 ScrollConsoleScreenBufferW(
1981 HANDLE hConsoleOutput,
1982 CONST SMALL_RECT *lpScrollRectangle,
1983 CONST SMALL_RECT *lpClipRectangle,
1984 COORD dwDestinationOrigin,
1985 CONST CHAR_INFO *lpFill
1986 )
1987 {
1988 /* TO DO */
1989 return FALSE;
1990 }
1991
1992
1993 /*--------------------------------------------------------------
1994 * SetConsoleWindowInfo
1995 */
1996 WINBASEAPI
1997 BOOL
1998 WINAPI
1999 SetConsoleWindowInfo(
2000 HANDLE hConsoleOutput,
2001 BOOL bAbsolute,
2002 CONST SMALL_RECT *lpConsoleWindow
2003 )
2004 {
2005 /* TO DO */
2006 return FALSE;
2007 }
2008
2009
2010 /*--------------------------------------------------------------
2011 * SetConsoleTextAttribute
2012 */
2013 WINBASEAPI
2014 BOOL
2015 WINAPI
2016 SetConsoleTextAttribute(
2017 HANDLE hConsoleOutput,
2018 WORD wAttributes
2019 )
2020 {
2021 CSRSS_API_REQUEST Request;
2022 CSRSS_API_REPLY Reply;
2023 NTSTATUS Status;
2024
2025 Request.Type = CSRSS_SET_ATTRIB;
2026 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2027 Request.Data.SetAttribRequest.Attrib = wAttributes;
2028 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2029 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2030 {
2031 SetLastErrorByStatus ( Status );
2032 return FALSE;
2033 }
2034 return TRUE;
2035 }
2036
2037 BOOL STATIC
2038 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2039 {
2040 if (HandlerRoutine == NULL)
2041 {
2042 IgnoreCtrlEvents = TRUE;
2043 return(TRUE);
2044 }
2045 else
2046 {
2047 NrCtrlHandlers++;
2048 CtrlHandlers =
2049 RtlReAllocateHeap(RtlGetProcessHeap(),
2050 HEAP_ZERO_MEMORY,
2051 (PVOID)CtrlHandlers,
2052 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2053 if (CtrlHandlers == NULL)
2054 {
2055 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2056 return(FALSE);
2057 }
2058 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2059 return(TRUE);
2060 }
2061 }
2062
2063 BOOL STATIC
2064 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2065 {
2066 ULONG i;
2067
2068 if (HandlerRoutine == NULL)
2069 {
2070 IgnoreCtrlEvents = FALSE;
2071 return(TRUE);
2072 }
2073 else
2074 {
2075 for (i = 0; i < NrCtrlHandlers; i++)
2076 {
2077 if (CtrlHandlers[i] == HandlerRoutine)
2078 {
2079 CtrlHandlers[i] = CtrlHandlers[NrCtrlHandlers - 1];
2080 NrCtrlHandlers--;
2081 CtrlHandlers =
2082 RtlReAllocateHeap(RtlGetProcessHeap(),
2083 HEAP_ZERO_MEMORY,
2084 (PVOID)CtrlHandlers,
2085 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2086 return(TRUE);
2087 }
2088 }
2089 }
2090 return(FALSE);
2091 }
2092
2093 WINBASEAPI BOOL WINAPI
2094 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2095 BOOL Add)
2096 {
2097 BOOLEAN Ret;
2098
2099 RtlEnterCriticalSection(&DllLock);
2100 if (Add)
2101 {
2102 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2103 }
2104 else
2105 {
2106 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2107 }
2108 RtlLeaveCriticalSection(&DllLock);
2109 return(Ret);
2110 }
2111
2112
2113 /*--------------------------------------------------------------
2114 * GenerateConsoleCtrlEvent
2115 */
2116 WINBASEAPI BOOL WINAPI
2117 GenerateConsoleCtrlEvent(
2118 DWORD dwCtrlEvent,
2119 DWORD dwProcessGroupId
2120 )
2121 {
2122 /* TO DO */
2123 return FALSE;
2124 }
2125
2126
2127 /*--------------------------------------------------------------
2128 * GetConsoleTitleW
2129 */
2130 #define MAX_CONSOLE_TITLE_LENGTH 80
2131
2132 WINBASEAPI
2133 DWORD
2134 WINAPI
2135 GetConsoleTitleW(
2136 LPWSTR lpConsoleTitle,
2137 DWORD nSize
2138 )
2139 {
2140 union {
2141 CSRSS_API_REQUEST quest;
2142 CSRSS_API_REPLY ply;
2143 } Re;
2144 NTSTATUS Status;
2145
2146 /* Marshall data */
2147 Re.quest.Type = CSRSS_GET_TITLE;
2148 Re.quest.Data.GetTitleRequest.ConsoleHandle =
2149 GetStdHandle (STD_INPUT_HANDLE);
2150
2151 /* Call CSRSS */
2152 Status = CsrClientCallServer (
2153 & Re.quest,
2154 & Re.ply,
2155 (sizeof (CSRSS_GET_TITLE_REQUEST) +
2156 sizeof (LPC_MESSAGE) +
2157 sizeof (ULONG)),
2158 sizeof (CSRSS_API_REPLY)
2159 );
2160 if ( !NT_SUCCESS(Status)
2161 || !NT_SUCCESS (Status = Re.ply.Status)
2162 )
2163 {
2164 SetLastErrorByStatus (Status);
2165 return (0);
2166 }
2167
2168 /* Convert size in characters to size in bytes */
2169 nSize = sizeof (WCHAR) * nSize;
2170
2171 /* Unmarshall data */
2172 if (nSize < Re.ply.Data.GetTitleReply.Length)
2173 {
2174 DbgPrint ("%s: ret=%d\n", __FUNCTION__, Re.ply.Data.GetTitleReply.Length);
2175 nSize /= sizeof (WCHAR);
2176 if (nSize > 1)
2177 {
2178 wcsncpy (
2179 lpConsoleTitle,
2180 Re.ply.Data.GetTitleReply.Title,
2181 (nSize - 1)
2182 );
2183 /* Add null */
2184 lpConsoleTitle [nSize --] = L'\0';
2185 }
2186 }
2187 else
2188 {
2189 nSize = Re.ply.Data.GetTitleReply.Length / sizeof (WCHAR);
2190 wcscpy (lpConsoleTitle, Re.ply.Data.GetTitleReply.Title);
2191 }
2192
2193 return nSize;
2194 }
2195
2196
2197 /*--------------------------------------------------------------
2198 * GetConsoleTitleA
2199 *
2200 * 19990306 EA
2201 */
2202 WINBASEAPI
2203 DWORD
2204 WINAPI
2205 GetConsoleTitleA(
2206 LPSTR lpConsoleTitle,
2207 DWORD nSize
2208 )
2209 {
2210 wchar_t WideTitle [MAX_CONSOLE_TITLE_LENGTH];
2211 DWORD nWideTitle = sizeof WideTitle;
2212 // DWORD nWritten;
2213
2214 if (!lpConsoleTitle || !nSize) return 0;
2215 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
2216 if (!nWideTitle) return 0;
2217 #if 0
2218 if ( (nWritten = WideCharToMultiByte(
2219 CP_ACP, // ANSI code page
2220 0, // performance and mapping flags
2221 (LPWSTR) WideTitle, // address of wide-character string
2222 nWideTitle, // number of characters in string
2223 lpConsoleTitle, // address of buffer for new string
2224 nSize, // size of buffer
2225 NULL, // FAST
2226 NULL // FAST
2227 )))
2228 {
2229 lpConsoleTitle[nWritten] = '\0';
2230 return nWritten;
2231 }
2232 #endif
2233 return 0;
2234 }
2235
2236
2237 /*--------------------------------------------------------------
2238 * SetConsoleTitleW
2239 */
2240 WINBASEAPI
2241 BOOL
2242 WINAPI
2243 SetConsoleTitleW(
2244 LPCWSTR lpConsoleTitle
2245 )
2246 {
2247 PCSRSS_API_REQUEST Request;
2248 CSRSS_API_REPLY Reply;
2249 NTSTATUS Status;
2250 unsigned int c;
2251
2252 Request = RtlAllocateHeap(GetProcessHeap(),
2253 HEAP_ZERO_MEMORY,
2254 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2255 if (Request == NULL)
2256 {
2257 SetLastError(ERROR_OUTOFMEMORY);
2258 return(FALSE);
2259 }
2260
2261 Request->Type = CSRSS_SET_TITLE;
2262 Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE );
2263
2264 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2265 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2266 // add null
2267 Request->Data.SetTitleRequest.Title[c] = 0;
2268 Request->Data.SetTitleRequest.Length = c;
2269 Status = CsrClientCallServer(Request,
2270 &Reply,
2271 sizeof(CSRSS_SET_TITLE_REQUEST) +
2272 c +
2273 sizeof( LPC_MESSAGE ) +
2274 sizeof( ULONG ),
2275 sizeof(CSRSS_API_REPLY));
2276
2277 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2278 {
2279 RtlFreeHeap( GetProcessHeap(), 0, Request );
2280 SetLastErrorByStatus (Status);
2281 return(FALSE);
2282 }
2283 RtlFreeHeap( GetProcessHeap(), 0, Request );
2284 return TRUE;
2285 }
2286
2287
2288 /*--------------------------------------------------------------
2289 * SetConsoleTitleA
2290 *
2291 * 19990204 EA Added
2292 */
2293 WINBASEAPI
2294 BOOL
2295 WINAPI
2296 SetConsoleTitleA(
2297 LPCSTR lpConsoleTitle
2298 )
2299 {
2300 PCSRSS_API_REQUEST Request;
2301 CSRSS_API_REPLY Reply;
2302 NTSTATUS Status;
2303 unsigned int c;
2304
2305 Request = RtlAllocateHeap(GetProcessHeap(),
2306 HEAP_ZERO_MEMORY,
2307 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2308 if (Request == NULL)
2309 {
2310 SetLastError(ERROR_OUTOFMEMORY);
2311 return(FALSE);
2312 }
2313
2314 Request->Type = CSRSS_SET_TITLE;
2315 Request->Data.SetTitleRequest.Console = GetStdHandle( STD_INPUT_HANDLE );
2316
2317 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2318 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2319 // add null
2320 Request->Data.SetTitleRequest.Title[c] = 0;
2321 Request->Data.SetTitleRequest.Length = c;
2322 Status = CsrClientCallServer(Request,
2323 &Reply,
2324 sizeof(CSRSS_SET_TITLE_REQUEST) +
2325 c +
2326 sizeof( LPC_MESSAGE ) +
2327 sizeof( ULONG ),
2328 sizeof(CSRSS_API_REPLY));
2329
2330 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2331 {
2332 RtlFreeHeap( GetProcessHeap(), 0, Request );
2333 SetLastErrorByStatus (Status);
2334 return(FALSE);
2335 }
2336 RtlFreeHeap( GetProcessHeap(), 0, Request );
2337 return TRUE;
2338 }
2339
2340
2341 /*--------------------------------------------------------------
2342 * ReadConsoleW
2343 */
2344 WINBASEAPI
2345 BOOL
2346 WINAPI
2347 ReadConsoleW(
2348 HANDLE hConsoleInput,
2349 LPVOID lpBuffer,
2350 DWORD nNumberOfCharsToRead,
2351 LPDWORD lpNumberOfCharsRead,
2352 LPVOID lpReserved
2353 )
2354 {
2355 /* --- TO DO --- */
2356 return FALSE;
2357 }
2358
2359
2360 /*--------------------------------------------------------------
2361 * WriteConsoleW
2362 */
2363 WINBASEAPI
2364 BOOL
2365 WINAPI
2366 WriteConsoleW(
2367 HANDLE hConsoleOutput,
2368 CONST VOID *lpBuffer,
2369 DWORD nNumberOfCharsToWrite,
2370 LPDWORD lpNumberOfCharsWritten,
2371 LPVOID lpReserved
2372 )
2373 {
2374 #if 0
2375 PCSRSS_API_REQUEST Request;
2376 CSRSS_API_REPLY Reply;
2377 NTSTATUS Status;
2378
2379 Request = RtlAllocateHeap(GetProcessHeap(),
2380 HEAP_ZERO_MEMORY,
2381 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
2382 if (Request == NULL)
2383 {
2384 SetLastError(ERROR_OUTOFMEMORY);
2385 return(FALSE);
2386 }
2387
2388 Request->Type = CSRSS_WRITE_CONSOLE;
2389 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
2390 Request->Data.WriteConsoleRequest.NrCharactersToWrite =
2391 nNumberOfCharsToWrite;
2392 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
2393 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
2394 memcpy(Request->Data.WriteConsoleRequest.Buffer,
2395 lpBuffer,
2396 nNumberOfCharsToWrite * sizeof(WCHAR));
2397
2398 Status = CsrClientCallServer(Request,
2399 &Reply,
2400 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
2401 sizeof(CSRSS_API_REPLY));
2402
2403 RtlFreeHeap(GetProcessHeap(),
2404 0,
2405 Request);
2406
2407 if (!NT_SUCCESS(Status))
2408 {
2409 return(FALSE);
2410 }
2411
2412 if (lpNumberOfCharsWritten != NULL)
2413 {
2414 *lpNumberOfCharsWritten =
2415 Reply.Data.WriteConsoleReply.NrCharactersWritten;
2416 }
2417
2418 return(TRUE);
2419 #endif
2420 return(FALSE);
2421 }
2422
2423
2424 /*--------------------------------------------------------------
2425 * CreateConsoleScreenBuffer
2426 */
2427 WINBASEAPI
2428 HANDLE
2429 WINAPI
2430 CreateConsoleScreenBuffer(
2431 DWORD dwDesiredAccess,
2432 DWORD dwShareMode,
2433 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
2434 DWORD dwFlags,
2435 LPVOID lpScreenBufferData
2436 )
2437 {
2438 // FIXME: don't ignore access, share mode, and security
2439 CSRSS_API_REQUEST Request;
2440 CSRSS_API_REPLY Reply;
2441 NTSTATUS Status;
2442
2443 Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
2444 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2445 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2446 {
2447 SetLastErrorByStatus ( Status );
2448 return FALSE;
2449 }
2450 return Reply.Data.CreateScreenBufferReply.OutputHandle;
2451 }
2452
2453
2454 /*--------------------------------------------------------------
2455 * GetConsoleCP
2456 */
2457 WINBASEAPI
2458 UINT
2459 WINAPI
2460 GetConsoleCP( VOID )
2461 {
2462 /* --- TO DO --- */
2463 return CP_OEMCP; /* FIXME */
2464 }
2465
2466
2467 /*--------------------------------------------------------------
2468 * SetConsoleCP
2469 */
2470 WINBASEAPI
2471 BOOL
2472 WINAPI
2473 SetConsoleCP(
2474 UINT wCodePageID
2475 )
2476 {
2477 /* --- TO DO --- */
2478 return FALSE;
2479 }
2480
2481
2482 /*--------------------------------------------------------------
2483 * GetConsoleOutputCP
2484 */
2485 WINBASEAPI
2486 UINT
2487 WINAPI
2488 GetConsoleOutputCP( VOID )
2489 {
2490 /* --- TO DO --- */
2491 return 0; /* FIXME */
2492 }
2493
2494
2495 /*--------------------------------------------------------------
2496 * SetConsoleOutputCP
2497 */
2498 WINBASEAPI
2499 BOOL
2500 WINAPI
2501 SetConsoleOutputCP(
2502 UINT wCodePageID
2503 )
2504 {
2505 /* --- TO DO --- */
2506 return FALSE;
2507 }
2508
2509
2510 /*--------------------------------------------------------------
2511 * GetConsoleProcessList
2512 */
2513 DWORD STDCALL
2514 GetConsoleProcessList(LPDWORD lpdwProcessList,
2515 DWORD dwProcessCount)
2516 {
2517 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2518 return 0;
2519 }
2520
2521
2522
2523 /*--------------------------------------------------------------
2524 * GetConsoleSelectionInfo
2525 */
2526 BOOL STDCALL
2527 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2528 {
2529 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2530 return FALSE;
2531 }
2532
2533
2534
2535 /*--------------------------------------------------------------
2536 * AttachConsole
2537 */
2538 BOOL STDCALL
2539 AttachConsole(DWORD dwProcessId)
2540 {
2541 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2542 return FALSE;
2543 }
2544
2545 /* EOF */