- Change GlobalDiscard and LocalDiscard to macros.
[reactos.git] / reactos / lib / kernel32 / misc / console.c
1 /* $Id: console.c,v 1.78 2004/08/24 17:21:11 navaraf 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: James Tabor
8 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
9 * UPDATE HISTORY:
10 * 199901?? ?? Created
11 * 19990204 EA SetConsoleTitleA
12 * 19990306 EA Stubs
13 */
14
15 /* INCLUDES ******************************************************************/
16
17 #include <k32.h>
18
19 #define NDEBUG
20 #include "../include/debug.h"
21
22 #define _NOACHS(__X) (sizeof(__X) / sizeof((__X)[0]))
23 extern BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event);
24 extern __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag);
25 extern CRITICAL_SECTION ConsoleLock;
26 extern BOOL WINAPI IsDebuggerPresent(VOID);
27
28
29 /* GLOBALS *******************************************************************/
30
31 static BOOL IgnoreCtrlEvents = FALSE;
32
33 static PHANDLER_ROUTINE* CtrlHandlers = NULL;
34 static ULONG NrCtrlHandlers = 0;
35
36 /* Default Console Control Handler *******************************************/
37
38 BOOL WINAPI DefaultConsoleCtrlHandler(DWORD Event)
39 {
40 switch(Event)
41 {
42 case CTRL_C_EVENT:
43 DPRINT("Ctrl-C Event\n");
44 ExitProcess(0);
45 break;
46
47 case CTRL_BREAK_EVENT:
48 DPRINT("Ctrl-Break Event\n");
49 ExitProcess(0);
50 break;
51
52 case CTRL_SHUTDOWN_EVENT:
53 DPRINT("Ctrl Shutdown Event\n");
54 break;
55
56 case CTRL_CLOSE_EVENT:
57 DPRINT("Ctrl Close Event\n");
58 break;
59
60 case CTRL_LOGOFF_EVENT:
61 DPRINT("Ctrl Logoff Event\n");
62 break;
63 }
64 // ExitProcess((UINT)&ExitCode);
65 return TRUE;
66 }
67
68
69 __declspec(noreturn) VOID CALLBACK ConsoleControlDispatcher(DWORD CodeAndFlag)
70 {
71 DWORD nExitCode = 0;
72 DWORD nCode = CodeAndFlag & MAXLONG;
73 UINT i;
74
75 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
76
77 switch(nCode)
78 {
79 case CTRL_C_EVENT:
80 case CTRL_BREAK_EVENT:
81 {
82 if(IsDebuggerPresent())
83 {
84 EXCEPTION_RECORD erException;
85 erException.ExceptionCode =
86 (nCode == CTRL_C_EVENT ? DBG_CONTROL_C : DBG_CONTROL_BREAK);
87 erException.ExceptionFlags = 0;
88 erException.ExceptionRecord = NULL;
89 erException.ExceptionAddress = &DefaultConsoleCtrlHandler;
90 erException.NumberParameters = 0;
91 RtlRaiseException(&erException);
92 }
93 RtlEnterCriticalSection(&ConsoleLock);
94
95 if(!(nCode == CTRL_C_EVENT &&
96 NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
97 {
98 for(i = NrCtrlHandlers; i > 0; -- i)
99 if(CtrlHandlers[i - 1](nCode)) break;
100 }
101 RtlLeaveCriticalSection(&ConsoleLock);
102 ExitThread(0);
103 }
104 case CTRL_CLOSE_EVENT:
105 case CTRL_LOGOFF_EVENT:
106 case CTRL_SHUTDOWN_EVENT:
107 break;
108
109 default: ExitThread(0);
110 }
111
112 RtlEnterCriticalSection(&ConsoleLock);
113
114 if(!(nCode == CTRL_C_EVENT &&
115 NtCurrentPeb()->ProcessParameters->ProcessGroup & 1))
116 {
117 i = NrCtrlHandlers;
118 while(i > 0)
119 {
120 if (i == 1 && (CodeAndFlag & MINLONG) &&
121 (nCode == CTRL_LOGOFF_EVENT || nCode == CTRL_SHUTDOWN_EVENT))
122 break;
123
124 if(CtrlHandlers[i - 1](nCode))
125 {
126 switch(nCode)
127 {
128 case CTRL_CLOSE_EVENT:
129 case CTRL_LOGOFF_EVENT:
130 case CTRL_SHUTDOWN_EVENT:
131 nExitCode = CodeAndFlag;
132 }
133 break;
134 }
135 --i;
136 }
137 }
138 RtlLeaveCriticalSection(&ConsoleLock);
139 ExitThread(nExitCode);
140 }
141
142
143 /* FUNCTIONS *****************************************************************/
144
145 /*
146 * @unimplemented
147 */
148 BOOL STDCALL
149 AddConsoleAliasA (LPSTR Source,
150 LPSTR Target,
151 LPSTR ExeName)
152 {
153 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
154 return FALSE;
155 }
156
157
158 /*
159 * @unimplemented
160 */
161 BOOL STDCALL
162 AddConsoleAliasW (LPWSTR Source,
163 LPWSTR Target,
164 LPWSTR ExeName)
165 {
166 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
167 return FALSE;
168 }
169
170
171 /*
172 * @unimplemented
173 */
174 BOOL STDCALL
175 ConsoleMenuControl (HANDLE hConsole,
176 DWORD Unknown1,
177 DWORD Unknown2)
178 /*
179 * Undocumented
180 */
181 {
182 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
183 return FALSE;
184 }
185
186
187 /*
188 * @implemented
189 */
190 HANDLE STDCALL
191 DuplicateConsoleHandle (HANDLE hConsole,
192 DWORD dwDesiredAccess,
193 BOOL bInheritHandle,
194 DWORD dwOptions)
195 {
196 CSRSS_API_REQUEST Request;
197 CSRSS_API_REPLY Reply;
198 NTSTATUS Status;
199
200 if (IsConsoleHandle (hConsole) == FALSE)
201 {
202 SetLastError (ERROR_INVALID_PARAMETER);
203 return INVALID_HANDLE_VALUE;
204 }
205
206 Request.Type = CSRSS_DUPLICATE_HANDLE;
207 Request.Data.DuplicateHandleRequest.Handle = hConsole;
208 Request.Data.DuplicateHandleRequest.ProcessId = GetCurrentProcessId();
209 Status = CsrClientCallServer(&Request,
210 &Reply,
211 sizeof(CSRSS_API_REQUEST),
212 sizeof(CSRSS_API_REPLY));
213 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status=Reply.Status))
214 {
215 SetLastErrorByStatus(Status);
216 return INVALID_HANDLE_VALUE;
217 }
218 return Reply.Data.DuplicateHandleReply.Handle;
219 }
220
221
222 /*
223 * @unimplemented
224 */
225 DWORD STDCALL
226 ExpungeConsoleCommandHistoryW (DWORD Unknown0)
227 /*
228 * Undocumented
229 */
230 {
231 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
232 return 0;
233 }
234
235
236 /*
237 * @unimplemented
238 */
239 DWORD STDCALL
240 ExpungeConsoleCommandHistoryA (DWORD Unknown0)
241 /*
242 * Undocumented
243 */
244 {
245 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
246 return 0;
247 }
248
249
250 /*
251 * @unimplemented
252 */
253 DWORD STDCALL
254 GetConsoleAliasW (DWORD Unknown0,
255 DWORD Unknown1,
256 DWORD Unknown2,
257 DWORD Unknown3)
258 /*
259 * Undocumented
260 */
261 {
262 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
263 return 0;
264 }
265
266
267 /*
268 * @unimplemented
269 */
270 DWORD STDCALL
271 GetConsoleAliasA (DWORD Unknown0,
272 DWORD Unknown1,
273 DWORD Unknown2,
274 DWORD Unknown3)
275 /*
276 * Undocumented
277 */
278 {
279 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
280 return 0;
281 }
282
283
284 /*
285 * @unimplemented
286 */
287 DWORD STDCALL
288 GetConsoleAliasExesW (DWORD Unknown0,
289 DWORD Unknown1)
290 /*
291 * Undocumented
292 */
293 {
294 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
295 return 0;
296 }
297
298
299 /*
300 * @unimplemented
301 */
302 DWORD STDCALL
303 GetConsoleAliasExesA (DWORD Unknown0,
304 DWORD Unknown1)
305 /*
306 * Undocumented
307 */
308 {
309 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
310 return 0;
311 }
312
313
314 /*
315 * @unimplemented
316 */
317 DWORD STDCALL
318 GetConsoleAliasExesLengthA (VOID)
319 /*
320 * Undocumented
321 */
322 {
323 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
324 return 0;
325 }
326
327
328 /*
329 * @unimplemented
330 */
331 DWORD STDCALL
332 GetConsoleAliasExesLengthW (VOID)
333 /*
334 * Undocumented
335 */
336 {
337 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
338 return 0;
339 }
340
341
342 /*
343 * @unimplemented
344 */
345 DWORD STDCALL
346 GetConsoleAliasesW (DWORD Unknown0,
347 DWORD Unknown1,
348 DWORD Unknown2)
349 /*
350 * Undocumented
351 */
352 {
353 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
354 return 0;
355 }
356
357
358 /*
359 * @unimplemented
360 */
361 DWORD STDCALL
362 GetConsoleAliasesA (DWORD Unknown0,
363 DWORD Unknown1,
364 DWORD Unknown2)
365 /*
366 * Undocumented
367 */
368 {
369 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
370 return 0;
371 }
372
373
374 /*
375 * @unimplemented
376 */
377 DWORD STDCALL
378 GetConsoleAliasesLengthW (DWORD Unknown0)
379 /*
380 * Undocumented
381 */
382 {
383 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
384 return 0;
385 }
386
387
388 /*
389 * @unimplemented
390 */
391 DWORD STDCALL
392 GetConsoleAliasesLengthA (DWORD Unknown0)
393 /*
394 * Undocumented
395 */
396 {
397 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
398 return 0;
399 }
400
401
402 /*
403 * @unimplemented
404 */
405 DWORD STDCALL
406 GetConsoleCommandHistoryW (DWORD Unknown0,
407 DWORD Unknown1,
408 DWORD Unknown2)
409 /*
410 * Undocumented
411 */
412 {
413 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
414 return 0;
415 }
416
417
418 /*
419 * @unimplemented
420 */
421 DWORD STDCALL
422 GetConsoleCommandHistoryA (DWORD Unknown0,
423 DWORD Unknown1,
424 DWORD Unknown2)
425 /*
426 * Undocumented
427 */
428 {
429 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
430 return 0;
431 }
432
433
434 /*
435 * @unimplemented
436 */
437 DWORD STDCALL
438 GetConsoleCommandHistoryLengthW (DWORD Unknown0)
439 /*
440 * Undocumented
441 */
442 {
443 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
444 return 0;
445 }
446
447
448 /*
449 * @unimplemented
450 */
451 DWORD STDCALL
452 GetConsoleCommandHistoryLengthA (DWORD Unknown0)
453 /*
454 * Undocumented
455 */
456 {
457 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
458 return 0;
459 }
460
461 /*
462 * @unimplemented
463 */
464 DWORD STDCALL
465 GetConsoleDisplayMode (LPDWORD lpdwMode)
466 /*
467 * FUNCTION: Get the console display mode
468 * ARGUMENTS:
469 * lpdwMode - Address of variable that receives the current value
470 * of display mode
471 * STATUS: Undocumented
472 */
473 {
474 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
475 return 0;
476 }
477
478
479 /*
480 * @unimplemented
481 */
482 DWORD STDCALL
483 GetConsoleFontInfo (DWORD Unknown0,
484 DWORD Unknown1,
485 DWORD Unknown2,
486 DWORD Unknown3)
487 /*
488 * Undocumented
489 */
490 {
491 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
492 return 0;
493 }
494
495
496 /*
497 * @unimplemented
498 */
499 DWORD STDCALL
500 GetConsoleFontSize(HANDLE hConsoleOutput,
501 DWORD nFont)
502 {
503 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
504 return 0;
505 }
506
507
508 /*
509 * @implemented
510 */
511 DWORD STDCALL
512 GetConsoleHardwareState (HANDLE hConsole,
513 DWORD Flags,
514 PDWORD State)
515 /*
516 * Undocumented
517 */
518 {
519 CSRSS_API_REQUEST Request;
520 CSRSS_API_REPLY Reply;
521 NTSTATUS Status;
522
523 Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
524 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
525 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_GET;
526
527 Status = CsrClientCallServer(& Request,
528 & Reply,
529 sizeof(CSRSS_API_REQUEST),
530 sizeof(CSRSS_API_REPLY));
531 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
532 {
533 SetLastErrorByStatus(Status);
534 return FALSE;
535 }
536 *State = Reply.Data.ConsoleHardwareStateReply.State;
537 return TRUE;
538 }
539
540
541 /*
542 * @unimplemented
543 */
544 DWORD STDCALL
545 GetConsoleInputWaitHandle (VOID)
546 /*
547 * Undocumented
548 */
549 {
550 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
551 return FALSE;
552 }
553
554
555 /*
556 * @unimplemented
557 */
558 DWORD STDCALL
559 GetCurrentConsoleFont(HANDLE hConsoleOutput,
560 BOOL bMaximumWindow,
561 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
562 {
563 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
564 return 0;
565 }
566
567
568 /*
569 * @unimplemented
570 */
571 ULONG STDCALL
572 GetNumberOfConsoleFonts (VOID)
573 /*
574 * Undocumented
575 */
576 {
577 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
578 return 1; /* FIXME: call csrss.exe */
579 }
580
581
582 /*
583 * @unimplemented
584 */
585 DWORD STDCALL
586 InvalidateConsoleDIBits (DWORD Unknown0,
587 DWORD Unknown1)
588 /*
589 * Undocumented
590 */
591 {
592 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
593 return 0;
594 }
595
596
597 /*
598 * @unimplemented
599 */
600 HANDLE STDCALL
601 OpenConsoleW (LPWSTR wsName,
602 DWORD dwDesiredAccess,
603 BOOL bInheritHandle,
604 DWORD dwCreationDistribution)
605 /*
606 * Undocumented
607 */
608 {
609 CSRSS_API_REQUEST Request;
610 CSRSS_API_REPLY Reply;
611 PHANDLE phConsole = NULL;
612 NTSTATUS Status = STATUS_SUCCESS;
613
614
615 if(0 == _wcsicmp(wsName, L"CONIN$"))
616 {
617 Request.Type = CSRSS_GET_INPUT_HANDLE;
618 phConsole = & Reply.Data.GetInputHandleReply.InputHandle;
619 }
620 else if (0 == _wcsicmp(wsName, L"CONOUT$"))
621 {
622 Request.Type = CSRSS_GET_OUTPUT_HANDLE;
623 phConsole = & Reply.Data.GetOutputHandleReply.OutputHandle;
624 }
625 else
626 {
627 SetLastError(ERROR_INVALID_PARAMETER);
628 return(INVALID_HANDLE_VALUE);
629 }
630 if ((GENERIC_READ|GENERIC_WRITE) != dwDesiredAccess)
631 {
632 SetLastError(ERROR_INVALID_PARAMETER);
633 return(INVALID_HANDLE_VALUE);
634 }
635 if (OPEN_EXISTING != dwCreationDistribution)
636 {
637 SetLastError(ERROR_INVALID_PARAMETER);
638 return(INVALID_HANDLE_VALUE);
639 }
640 Status = CsrClientCallServer(& Request,
641 & Reply,
642 sizeof(CSRSS_API_REQUEST),
643 sizeof(CSRSS_API_REPLY));
644 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
645 {
646 SetLastErrorByStatus(Status);
647 return INVALID_HANDLE_VALUE;
648 }
649 return(*phConsole);
650 }
651
652
653 /*
654 * @unimplemented
655 */
656 BOOL STDCALL
657 SetConsoleCommandHistoryMode (DWORD dwMode)
658 /*
659 * Undocumented
660 */
661 {
662 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
663 return FALSE;
664 }
665
666
667 /*
668 * @unimplemented
669 */
670 BOOL STDCALL
671 SetConsoleCursor (DWORD Unknown0,
672 DWORD Unknown1)
673 /*
674 * Undocumented
675 */
676 {
677 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
678 return FALSE;
679 }
680
681
682 /*
683 * @unimplemented
684 */
685 BOOL STDCALL
686 SetConsoleDisplayMode (HANDLE hOut,
687 DWORD dwNewMode,
688 LPDWORD lpdwOldMode)
689 /*
690 * FUNCTION: Set the console display mode.
691 * ARGUMENTS:
692 * hOut - Standard output handle.
693 * dwNewMode - New mode.
694 * lpdwOldMode - Address of a variable that receives the old mode.
695 */
696 {
697 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
698 return FALSE;
699 }
700
701
702 /*
703 * @unimplemented
704 */
705 BOOL STDCALL
706 SetConsoleFont (DWORD Unknown0,
707 DWORD Unknown1)
708 /*
709 * Undocumented
710 */
711 {
712 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
713 return FALSE;
714 }
715
716
717 /*
718 * @implemented
719 */
720 BOOL STDCALL
721 SetConsoleHardwareState (HANDLE hConsole,
722 DWORD Flags,
723 DWORD State)
724 /*
725 * Undocumented
726 */
727 {
728 CSRSS_API_REQUEST Request;
729 CSRSS_API_REPLY Reply;
730 NTSTATUS Status;
731
732 Request.Type = CSRSS_SETGET_CONSOLE_HW_STATE;
733 Request.Data.ConsoleHardwareStateRequest.ConsoleHandle = hConsole;
734 Request.Data.ConsoleHardwareStateRequest.SetGet = CONSOLE_HARDWARE_STATE_SET;
735 Request.Data.ConsoleHardwareStateRequest.State = State;
736
737 Status = CsrClientCallServer(& Request,
738 & Reply,
739 sizeof(CSRSS_API_REQUEST),
740 sizeof(CSRSS_API_REPLY));
741 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
742 {
743 SetLastErrorByStatus(Status);
744 return FALSE;
745 }
746 return TRUE;
747 }
748
749
750 /*
751 * @unimplemented
752 */
753 BOOL STDCALL
754 SetConsoleKeyShortcuts (DWORD Unknown0,
755 DWORD Unknown1,
756 DWORD Unknown2,
757 DWORD Unknown3)
758 /*
759 * Undocumented
760 */
761 {
762 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
763 return FALSE;
764 }
765
766
767 /*
768 * @unimplemented
769 */
770 BOOL STDCALL
771 SetConsoleMaximumWindowSize (DWORD Unknown0,
772 DWORD Unknown1)
773 /*
774 * Undocumented
775 */
776 {
777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
778 return FALSE;
779 }
780
781
782 /*
783 * @unimplemented
784 */
785 BOOL STDCALL
786 SetConsoleMenuClose (DWORD Unknown0)
787 /*
788 * Undocumented
789 */
790 {
791 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
792 return FALSE;
793 }
794
795
796 /*
797 * @unimplemented
798 */
799 BOOL STDCALL
800 SetConsoleNumberOfCommandsA (DWORD Unknown0,
801 DWORD Unknown1)
802 /*
803 * Undocumented
804 */
805 {
806 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
807 return FALSE;
808 }
809
810
811 /*
812 * @unimplemented
813 */
814 BOOL STDCALL
815 SetConsoleNumberOfCommandsW (DWORD Unknown0,
816 DWORD Unknown1)
817 /*
818 * Undocumented
819 */
820 {
821 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
822 return FALSE;
823 }
824
825
826 /*
827 * @unimplemented
828 */
829 BOOL STDCALL
830 SetConsolePalette (DWORD Unknown0,
831 DWORD Unknown1,
832 DWORD Unknown2)
833 /*
834 * Undocumented
835 */
836 {
837 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
838 return FALSE;
839 }
840
841
842 /*
843 * @unimplemented
844 */
845 BOOL STDCALL
846 SetLastConsoleEventActive (VOID)
847 /*
848 * Undocumented
849 */
850 {
851 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
852 return FALSE;
853 }
854
855
856 /*
857 * @unimplemented
858 */
859 DWORD STDCALL
860 ShowConsoleCursor (DWORD Unknown0,
861 DWORD Unknown1)
862 /*
863 * Undocumented
864 */
865 {
866 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
867 return 0;
868 }
869
870
871 /*
872 * FUNCTION: Checks whether the given handle is a valid console handle.
873 * ARGUMENTS:
874 * Handle - Handle to be checked
875 * RETURNS:
876 * TRUE: Handle is a valid console handle
877 * FALSE: Handle is not a valid console handle.
878 * STATUS: Officially undocumented
879 *
880 * @implemented
881 */
882 BOOL STDCALL
883 VerifyConsoleIoHandle(HANDLE Handle)
884 {
885 CSRSS_API_REQUEST Request;
886 CSRSS_API_REPLY Reply;
887 NTSTATUS Status;
888
889 Request.Type = CSRSS_VERIFY_HANDLE;
890 Request.Data.VerifyHandleRequest.Handle = Handle;
891 Status = CsrClientCallServer(&Request,
892 &Reply,
893 sizeof(CSRSS_API_REQUEST),
894 sizeof(CSRSS_API_REPLY));
895 if (!NT_SUCCESS(Status))
896 {
897 SetLastErrorByStatus(Status);
898 return FALSE;
899 }
900
901 return (BOOL)NT_SUCCESS(Reply.Status);
902 }
903
904
905 /*
906 * @unimplemented
907 */
908 DWORD STDCALL
909 WriteConsoleInputVDMA (DWORD Unknown0,
910 DWORD Unknown1,
911 DWORD Unknown2,
912 DWORD Unknown3)
913 {
914 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
915 return 0;
916 }
917
918
919 /*
920 * @unimplemented
921 */
922 DWORD STDCALL
923 WriteConsoleInputVDMW (DWORD Unknown0,
924 DWORD Unknown1,
925 DWORD Unknown2,
926 DWORD Unknown3)
927 {
928 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
929 return 0;
930 }
931
932
933 /*
934 * @implemented
935 */
936 BOOL STDCALL
937 CloseConsoleHandle(HANDLE Handle)
938 /*
939 * Undocumented
940 */
941 {
942 CSRSS_API_REQUEST Request;
943 CSRSS_API_REPLY Reply;
944 NTSTATUS Status;
945
946 if (IsConsoleHandle (Handle) == FALSE)
947 {
948 SetLastError (ERROR_INVALID_PARAMETER);
949 return FALSE;
950 }
951
952 Request.Type = CSRSS_CLOSE_HANDLE;
953 Request.Data.CloseHandleRequest.Handle = Handle;
954 Status = CsrClientCallServer(&Request,
955 &Reply,
956 sizeof(CSRSS_API_REQUEST),
957 sizeof(CSRSS_API_REPLY));
958 if (!NT_SUCCESS(Status))
959 {
960 SetLastErrorByStatus(Status);
961 return FALSE;
962 }
963
964 return TRUE;
965 }
966
967
968 /*
969 * internal function
970 */
971 BOOL STDCALL
972 IsConsoleHandle(HANDLE Handle)
973 {
974 if ((((ULONG)Handle) & 0x10000003) == 0x3)
975 {
976 return(TRUE);
977 }
978 return(FALSE);
979 }
980
981
982 /*
983 * @implemented
984 */
985 HANDLE STDCALL
986 GetStdHandle(DWORD nStdHandle)
987 /*
988 * FUNCTION: Get a handle for the standard input, standard output
989 * and a standard error device.
990 * ARGUMENTS:
991 * nStdHandle - Specifies the device for which to return the handle.
992 * RETURNS: If the function succeeds, the return value is the handle
993 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
994 */
995 {
996 PRTL_USER_PROCESS_PARAMETERS Ppb;
997
998 Ppb = NtCurrentPeb()->ProcessParameters;
999 switch (nStdHandle)
1000 {
1001 case STD_INPUT_HANDLE:
1002 return Ppb->hStdInput;
1003
1004 case STD_OUTPUT_HANDLE:
1005 return Ppb->hStdOutput;
1006
1007 case STD_ERROR_HANDLE:
1008 return Ppb->hStdError;
1009 }
1010
1011 SetLastError (ERROR_INVALID_PARAMETER);
1012 return INVALID_HANDLE_VALUE;
1013 }
1014
1015
1016 /*
1017 * @implemented
1018 */
1019 BOOL WINAPI
1020 SetStdHandle(DWORD nStdHandle,
1021 HANDLE hHandle)
1022 /*
1023 * FUNCTION: Set the handle for the standard input, standard output or
1024 * the standard error device.
1025 * ARGUMENTS:
1026 * nStdHandle - Specifies the handle to be set.
1027 * hHandle - The handle to set.
1028 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
1029 */
1030 {
1031 PRTL_USER_PROCESS_PARAMETERS Ppb;
1032
1033 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
1034
1035 Ppb = NtCurrentPeb()->ProcessParameters;
1036
1037 switch (nStdHandle)
1038 {
1039 case STD_INPUT_HANDLE:
1040 Ppb->hStdInput = hHandle;
1041 return TRUE;
1042
1043 case STD_OUTPUT_HANDLE:
1044 Ppb->hStdOutput = hHandle;
1045 return TRUE;
1046
1047 case STD_ERROR_HANDLE:
1048 Ppb->hStdError = hHandle;
1049 return TRUE;
1050 }
1051
1052 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
1053 SetLastError (ERROR_INVALID_HANDLE);
1054 return FALSE;
1055 }
1056
1057
1058 /*--------------------------------------------------------------
1059 * WriteConsoleA
1060 *
1061 * @implemented
1062 */
1063 BOOL STDCALL
1064 WriteConsoleA(HANDLE hConsoleOutput,
1065 CONST VOID *lpBuffer,
1066 DWORD nNumberOfCharsToWrite,
1067 LPDWORD lpNumberOfCharsWritten,
1068 LPVOID lpReserved)
1069 {
1070 PCSRSS_API_REQUEST Request;
1071 CSRSS_API_REPLY Reply;
1072 NTSTATUS Status;
1073 USHORT Size;
1074 ULONG MessageSize;
1075
1076 Request = RtlAllocateHeap(GetProcessHeap(), 0,
1077 sizeof(CSRSS_API_REQUEST) +
1078 min(nNumberOfCharsToWrite,
1079 CSRSS_MAX_WRITE_CONSOLE_REQUEST));
1080 if (Request == NULL)
1081 {
1082 SetLastError(ERROR_OUTOFMEMORY);
1083 return(FALSE);
1084 }
1085
1086 Request->Type = CSRSS_WRITE_CONSOLE;
1087 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
1088 if (lpNumberOfCharsWritten != NULL)
1089 *lpNumberOfCharsWritten = nNumberOfCharsToWrite;
1090 while (nNumberOfCharsToWrite)
1091 {
1092 if (nNumberOfCharsToWrite > CSRSS_MAX_WRITE_CONSOLE_REQUEST)
1093 {
1094 Size = CSRSS_MAX_WRITE_CONSOLE_REQUEST;
1095 }
1096 else
1097 {
1098 Size = nNumberOfCharsToWrite;
1099 }
1100 Request->Data.WriteConsoleRequest.NrCharactersToWrite = Size;
1101
1102 memcpy(Request->Data.WriteConsoleRequest.Buffer, lpBuffer, Size);
1103
1104 MessageSize = CSRSS_REQUEST_HEADER_SIZE +
1105 sizeof(CSRSS_WRITE_CONSOLE_REQUEST) + Size;
1106 Status = CsrClientCallServer(Request,
1107 &Reply,
1108 MessageSize,
1109 sizeof(CSRSS_API_REPLY));
1110
1111 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1112 {
1113 RtlFreeHeap(GetProcessHeap(), 0, Request);
1114 SetLastErrorByStatus(Status);
1115 return(FALSE);
1116 }
1117 nNumberOfCharsToWrite -= Size;
1118 lpBuffer += Size;
1119 }
1120
1121 RtlFreeHeap(GetProcessHeap(), 0, Request);
1122
1123 return TRUE;
1124 }
1125
1126
1127 /*--------------------------------------------------------------
1128 * ReadConsoleA
1129 *
1130 * @implemented
1131 */
1132 BOOL STDCALL ReadConsoleA(HANDLE hConsoleInput,
1133 LPVOID lpBuffer,
1134 DWORD nNumberOfCharsToRead,
1135 LPDWORD lpNumberOfCharsRead,
1136 LPVOID lpReserved)
1137 {
1138 CSRSS_API_REQUEST Request;
1139 PCSRSS_API_REPLY Reply;
1140 NTSTATUS Status;
1141 ULONG CharsRead = 0;
1142
1143 Reply = RtlAllocateHeap(GetProcessHeap(), 0,
1144 sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
1145 if (Reply == NULL)
1146 {
1147 SetLastError(ERROR_OUTOFMEMORY);
1148 return(FALSE);
1149 }
1150
1151 Request.Type = CSRSS_READ_CONSOLE;
1152 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1153 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
1154 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
1155 Status = CsrClientCallServer(&Request,
1156 Reply,
1157 sizeof(CSRSS_API_REQUEST),
1158 sizeof(CSRSS_API_REPLY) +
1159 Request.Data.ReadConsoleRequest.NrCharactersToRead);
1160 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
1161 {
1162 DbgPrint( "CSR returned error in ReadConsole\n" );
1163 SetLastErrorByStatus ( Status );
1164 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1165 return(FALSE);
1166 }
1167 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
1168 Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
1169 /* There may not be any chars or lines to read yet, so wait */
1170 while( Reply->Status == STATUS_PENDING )
1171 {
1172 /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
1173 nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
1174 /* don't overflow caller's buffer, even if you still don't have a complete line */
1175 if( !nNumberOfCharsToRead )
1176 break;
1177 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
1178 /* copy any chars already read to buffer */
1179 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
1180 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
1181 /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
1182 Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
1183 if( !NT_SUCCESS( Status ) )
1184 {
1185 DbgPrint( "Wait for console input failed!\n" );
1186 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1187 return FALSE;
1188 }
1189 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
1190 Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
1191 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
1192 {
1193 SetLastErrorByStatus ( Status );
1194 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1195 return FALSE;
1196 }
1197 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
1198 {
1199 // delete last char
1200 if( CharsRead )
1201 {
1202 CharsRead--;
1203 nNumberOfCharsToRead++;
1204 }
1205 Reply->Status = STATUS_PENDING; // retry
1206 }
1207 }
1208 /* copy data to buffer, count total returned, and return */
1209 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
1210 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
1211 if (lpNumberOfCharsRead != NULL)
1212 *lpNumberOfCharsRead = CharsRead;
1213 RtlFreeHeap(GetProcessHeap(),
1214 0,
1215 Reply);
1216
1217 return(TRUE);
1218 }
1219
1220
1221 /*--------------------------------------------------------------
1222 * AllocConsole
1223 *
1224 * @implemented
1225 */
1226 BOOL STDCALL AllocConsole(VOID)
1227 {
1228 CSRSS_API_REQUEST Request;
1229 CSRSS_API_REPLY Reply;
1230 NTSTATUS Status;
1231 HANDLE hStdError;
1232
1233 if(NtCurrentPeb()->ProcessParameters->hConsole)
1234 {
1235 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1236 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1237 return FALSE;
1238 }
1239
1240 Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher;
1241
1242 Request.Type = CSRSS_ALLOC_CONSOLE;
1243 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1244 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1245 {
1246 SetLastErrorByStatus ( Status );
1247 return FALSE;
1248 }
1249 NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console;
1250 SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
1251 SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
1252 hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
1253 0,
1254 TRUE,
1255 DUPLICATE_SAME_ACCESS);
1256 SetStdHandle( STD_ERROR_HANDLE, hStdError );
1257 return TRUE;
1258 }
1259
1260
1261 /*--------------------------------------------------------------
1262 * FreeConsole
1263 *
1264 * @implemented
1265 */
1266 BOOL STDCALL FreeConsole(VOID)
1267 {
1268 // AG: I'm not sure if this is correct (what happens to std handles?)
1269 // but I just tried to reverse what AllocConsole() does...
1270
1271 CSRSS_API_REQUEST Request;
1272 CSRSS_API_REPLY Reply;
1273 NTSTATUS Status;
1274
1275 Request.Type = CSRSS_FREE_CONSOLE;
1276 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1277 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1278 {
1279 SetLastErrorByStatus ( Status );
1280 return FALSE;
1281 }
1282
1283 return TRUE;
1284 }
1285
1286
1287 /*--------------------------------------------------------------
1288 * GetConsoleScreenBufferInfo
1289 *
1290 * @implemented
1291 */
1292 BOOL
1293 STDCALL
1294 GetConsoleScreenBufferInfo(
1295 HANDLE hConsoleOutput,
1296 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
1297 )
1298 {
1299 CSRSS_API_REQUEST Request;
1300 CSRSS_API_REPLY Reply;
1301 NTSTATUS Status;
1302
1303 Request.Type = CSRSS_SCREEN_BUFFER_INFO;
1304 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1305 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1306 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1307 {
1308 SetLastErrorByStatus ( Status );
1309 return FALSE;
1310 }
1311 *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
1312 return TRUE;
1313 }
1314
1315
1316 /*--------------------------------------------------------------
1317 * SetConsoleCursorPosition
1318 *
1319 * @implemented
1320 */
1321 BOOL
1322 STDCALL
1323 SetConsoleCursorPosition(
1324 HANDLE hConsoleOutput,
1325 COORD dwCursorPosition
1326 )
1327 {
1328 CSRSS_API_REQUEST Request;
1329 CSRSS_API_REPLY Reply;
1330 NTSTATUS Status;
1331
1332 Request.Type = CSRSS_SET_CURSOR;
1333 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1334 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1335 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1336 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1337 {
1338 SetLastErrorByStatus ( Status );
1339 return FALSE;
1340 }
1341 return TRUE;
1342 }
1343
1344
1345 /*--------------------------------------------------------------
1346 * FillConsoleOutputCharacterA
1347 *
1348 * @implemented
1349 */
1350 BOOL STDCALL
1351 FillConsoleOutputCharacterA(
1352 HANDLE hConsoleOutput,
1353 CHAR cCharacter,
1354 DWORD nLength,
1355 COORD dwWriteCoord,
1356 LPDWORD lpNumberOfCharsWritten
1357 )
1358 {
1359 CSRSS_API_REQUEST Request;
1360 CSRSS_API_REPLY Reply;
1361 NTSTATUS Status;
1362
1363 Request.Type = CSRSS_FILL_OUTPUT;
1364 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1365 Request.Data.FillOutputRequest.Char = cCharacter;
1366 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1367 Request.Data.FillOutputRequest.Length = nLength;
1368 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1369 if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1370 {
1371 SetLastErrorByStatus(Status);
1372 return(FALSE);
1373 }
1374 if (lpNumberOfCharsWritten != NULL)
1375 *lpNumberOfCharsWritten = nLength;
1376 return(TRUE);
1377 }
1378
1379
1380 /*--------------------------------------------------------------
1381 * FillConsoleOutputCharacterW
1382 *
1383 * @unimplemented
1384 */
1385 BOOL
1386 STDCALL
1387 FillConsoleOutputCharacterW(
1388 HANDLE hConsoleOutput,
1389 WCHAR cCharacter,
1390 DWORD nLength,
1391 COORD dwWriteCoord,
1392 LPDWORD lpNumberOfCharsWritten
1393 )
1394 {
1395 /* TO DO */
1396 DbgPrint("%s unimplemented\n", __FUNCTION__);
1397 return FALSE;
1398 }
1399
1400
1401 /*--------------------------------------------------------------
1402 * IntPeekConsoleInput
1403 *
1404 * INTERNAL
1405 */
1406 BOOL
1407 WINAPI
1408 IntPeekConsoleInput(
1409 HANDLE hConsoleInput,
1410 PINPUT_RECORD lpBuffer,
1411 DWORD nLength,
1412 LPDWORD lpNumberOfEventsRead,
1413 BOOL bUnicode
1414 )
1415 {
1416 PCSRSS_API_REQUEST Request;
1417 CSRSS_API_REPLY Reply;
1418 NTSTATUS Status;
1419 PVOID BufferBase;
1420 PVOID BufferTargetBase;
1421 DWORD Size;
1422
1423 if(lpBuffer == NULL)
1424 {
1425 SetLastError(ERROR_INVALID_PARAMETER);
1426 return FALSE;
1427 }
1428
1429 Size = nLength * sizeof(INPUT_RECORD);
1430
1431 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1432 if(!NT_SUCCESS(Status))
1433 {
1434 SetLastErrorByStatus(Status);
1435 return FALSE;
1436 }
1437
1438 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1439 if(Request == NULL)
1440 {
1441 CsrReleaseParameterBuffer(BufferBase);
1442 SetLastError(ERROR_OUTOFMEMORY);
1443 return FALSE;
1444 }
1445
1446 Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
1447 Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1448 Request->Data.PeekConsoleInputRequest.Unicode = bUnicode;
1449 Request->Data.PeekConsoleInputRequest.Length = nLength;
1450 Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
1451
1452 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1453
1454 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1455 {
1456 RtlFreeHeap(GetProcessHeap(), 0, Request);
1457 CsrReleaseParameterBuffer(BufferBase);
1458 return FALSE;
1459 }
1460
1461 memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
1462
1463 if(lpNumberOfEventsRead != NULL)
1464 *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
1465
1466 RtlFreeHeap(GetProcessHeap(), 0, Request);
1467 CsrReleaseParameterBuffer(BufferBase);
1468
1469 return TRUE;
1470 }
1471
1472 /*--------------------------------------------------------------
1473 * PeekConsoleInputA
1474 *
1475 * @implemented
1476 */
1477 BOOL
1478 WINAPI
1479 PeekConsoleInputA(
1480 HANDLE hConsoleInput,
1481 PINPUT_RECORD lpBuffer,
1482 DWORD nLength,
1483 LPDWORD lpNumberOfEventsRead
1484 )
1485 {
1486 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1487 lpNumberOfEventsRead, FALSE);
1488 }
1489
1490
1491 /*--------------------------------------------------------------
1492 * PeekConsoleInputW
1493 *
1494 * @implemented
1495 */
1496 BOOL
1497 WINAPI
1498 PeekConsoleInputW(
1499 HANDLE hConsoleInput,
1500 PINPUT_RECORD lpBuffer,
1501 DWORD nLength,
1502 LPDWORD lpNumberOfEventsRead
1503 )
1504 {
1505 return IntPeekConsoleInput(hConsoleInput, lpBuffer, nLength,
1506 lpNumberOfEventsRead, TRUE);
1507 }
1508
1509
1510 /*--------------------------------------------------------------
1511 * IntReadConsoleInput
1512 *
1513 * INTERNAL
1514 */
1515 BOOL WINAPI
1516 IntReadConsoleInput(HANDLE hConsoleInput,
1517 PINPUT_RECORD lpBuffer,
1518 DWORD nLength,
1519 LPDWORD lpNumberOfEventsRead,
1520 BOOL bUnicode)
1521 {
1522 CSRSS_API_REQUEST Request;
1523 CSRSS_API_REPLY Reply;
1524 DWORD NumEventsRead;
1525 NTSTATUS Status;
1526
1527 Request.Type = CSRSS_READ_INPUT;
1528 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1529 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1530 sizeof(CSRSS_API_REPLY));
1531 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1532 {
1533 SetLastErrorByStatus(Status);
1534 return(FALSE);
1535 }
1536
1537 while (Status == STATUS_PENDING)
1538 {
1539 Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE,
1540 0);
1541 if(!NT_SUCCESS(Status))
1542 {
1543 SetLastErrorByStatus(Status);
1544 return FALSE;
1545 }
1546
1547 Request.Type = CSRSS_READ_INPUT;
1548 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1549 Request.Data.ReadInputRequest.Unicode = bUnicode;
1550 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1551 sizeof(CSRSS_API_REPLY));
1552 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1553 {
1554 SetLastErrorByStatus(Status);
1555 return(FALSE);
1556 }
1557 }
1558
1559 NumEventsRead = 1;
1560 *lpBuffer = Reply.Data.ReadInputReply.Input;
1561 lpBuffer++;
1562
1563 while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
1564 {
1565 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1566 sizeof(CSRSS_API_REPLY));
1567 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1568 {
1569 SetLastErrorByStatus(Status);
1570 return(FALSE);
1571 }
1572
1573 if (Status == STATUS_PENDING)
1574 {
1575 break;
1576 }
1577
1578 *lpBuffer = Reply.Data.ReadInputReply.Input;
1579 lpBuffer++;
1580 NumEventsRead++;
1581
1582 }
1583 *lpNumberOfEventsRead = NumEventsRead;
1584
1585 return TRUE;
1586 }
1587
1588
1589 /*--------------------------------------------------------------
1590 * ReadConsoleInputA
1591 *
1592 * @implemented
1593 */
1594 BOOL WINAPI
1595 ReadConsoleInputA(HANDLE hConsoleInput,
1596 PINPUT_RECORD lpBuffer,
1597 DWORD nLength,
1598 LPDWORD lpNumberOfEventsRead)
1599 {
1600 return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
1601 lpNumberOfEventsRead, FALSE);
1602 }
1603
1604
1605 /*--------------------------------------------------------------
1606 * ReadConsoleInputW
1607 *
1608 * @implemented
1609 */
1610 BOOL
1611 WINAPI
1612 ReadConsoleInputW(
1613 HANDLE hConsoleInput,
1614 PINPUT_RECORD lpBuffer,
1615 DWORD nLength,
1616 LPDWORD lpNumberOfEventsRead
1617 )
1618 {
1619 return IntReadConsoleInput(hConsoleInput, lpBuffer, nLength,
1620 lpNumberOfEventsRead, TRUE);
1621 }
1622
1623
1624 /*--------------------------------------------------------------
1625 * WriteConsoleInputA
1626 *
1627 * @implemented
1628 */
1629 BOOL
1630 WINAPI
1631 WriteConsoleInputA(
1632 HANDLE hConsoleInput,
1633 CONST INPUT_RECORD *lpBuffer,
1634 DWORD nLength,
1635 LPDWORD lpNumberOfEventsWritten
1636 )
1637 {
1638 PCSRSS_API_REQUEST Request;
1639 CSRSS_API_REPLY Reply;
1640 PVOID BufferBase, BufferTargetBase;
1641 NTSTATUS Status;
1642 DWORD Size;
1643
1644 if(lpBuffer == NULL)
1645 {
1646 SetLastError(ERROR_INVALID_PARAMETER);
1647 return FALSE;
1648 }
1649
1650 Size = nLength * sizeof(INPUT_RECORD);
1651
1652 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1653 if(!NT_SUCCESS(Status))
1654 {
1655 SetLastErrorByStatus(Status);
1656 return FALSE;
1657 }
1658
1659 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1660 if(Request == NULL)
1661 {
1662 SetLastError(ERROR_OUTOFMEMORY);
1663 CsrReleaseParameterBuffer(BufferBase);
1664 return FALSE;
1665 }
1666
1667 Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
1668 Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
1669 Request->Data.WriteConsoleInputRequest.Length = nLength;
1670 Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
1671
1672 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1673 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1674 {
1675 RtlFreeHeap(GetProcessHeap(), 0, Request);
1676 CsrReleaseParameterBuffer(BufferBase);
1677 return FALSE;
1678 }
1679
1680 if(lpNumberOfEventsWritten != NULL)
1681 *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
1682
1683 RtlFreeHeap(GetProcessHeap(), 0, Request);
1684 CsrReleaseParameterBuffer(BufferBase);
1685
1686 return TRUE;
1687 }
1688
1689
1690 /*--------------------------------------------------------------
1691 * WriteConsoleInputW
1692 *
1693 * @unimplemented
1694 */
1695 BOOL
1696 WINAPI
1697 WriteConsoleInputW(
1698 HANDLE hConsoleInput,
1699 CONST INPUT_RECORD *lpBuffer,
1700 DWORD nLength,
1701 LPDWORD lpNumberOfEventsWritten
1702 )
1703 {
1704 /* TO DO */
1705 DbgPrint("%s unimplemented\n", __FUNCTION__);
1706 return FALSE;
1707 }
1708
1709
1710 /*--------------------------------------------------------------
1711 * IntReadConsoleOutput
1712 *
1713 * INTERNAL
1714 */
1715 BOOL
1716 WINAPI
1717 IntReadConsoleOutput(
1718 HANDLE hConsoleOutput,
1719 PCHAR_INFO lpBuffer,
1720 COORD dwBufferSize,
1721 COORD dwBufferCoord,
1722 PSMALL_RECT lpReadRegion,
1723 BOOL bUnicode
1724 )
1725 {
1726 PCSRSS_API_REQUEST Request;
1727 CSRSS_API_REPLY Reply;
1728 PVOID BufferBase;
1729 PVOID BufferTargetBase;
1730 NTSTATUS Status;
1731 DWORD Size, SizeX, SizeY;
1732
1733 if(lpBuffer == NULL)
1734 {
1735 SetLastError(ERROR_INVALID_PARAMETER);
1736 return FALSE;
1737 }
1738
1739 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
1740
1741 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1742 if(!NT_SUCCESS(Status))
1743 {
1744 SetLastErrorByStatus(Status);
1745 return FALSE;
1746 }
1747
1748 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1749 if(Request == NULL)
1750 {
1751 SetLastError(ERROR_OUTOFMEMORY);
1752 CsrReleaseParameterBuffer(BufferBase);
1753 return FALSE;
1754 }
1755
1756 Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
1757 Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1758 Request->Data.ReadConsoleOutputRequest.Unicode = bUnicode;
1759 Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
1760 Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
1761 Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
1762 Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
1763
1764 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1765 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1766 {
1767 SetLastErrorByStatus(Status);
1768 RtlFreeHeap(GetProcessHeap(), 0, Request);
1769 CsrReleaseParameterBuffer(BufferBase);
1770 return FALSE;
1771 }
1772
1773 SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
1774 SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
1775
1776 memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
1777 *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
1778
1779 RtlFreeHeap(GetProcessHeap(), 0, Request);
1780 CsrReleaseParameterBuffer(BufferBase);
1781
1782 return TRUE;
1783 }
1784
1785 /*--------------------------------------------------------------
1786 * ReadConsoleOutputA
1787 *
1788 * @implemented
1789 */
1790 BOOL
1791 WINAPI
1792 ReadConsoleOutputA(
1793 HANDLE hConsoleOutput,
1794 PCHAR_INFO lpBuffer,
1795 COORD dwBufferSize,
1796 COORD dwBufferCoord,
1797 PSMALL_RECT lpReadRegion
1798 )
1799 {
1800 return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1801 dwBufferCoord, lpReadRegion, FALSE);
1802 }
1803
1804
1805 /*--------------------------------------------------------------
1806 * ReadConsoleOutputW
1807 *
1808 * @implemented
1809 */
1810 BOOL
1811 WINAPI
1812 ReadConsoleOutputW(
1813 HANDLE hConsoleOutput,
1814 PCHAR_INFO lpBuffer,
1815 COORD dwBufferSize,
1816 COORD dwBufferCoord,
1817 PSMALL_RECT lpReadRegion
1818 )
1819 {
1820 return IntReadConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1821 dwBufferCoord, lpReadRegion, TRUE);
1822 }
1823
1824
1825 /*--------------------------------------------------------------
1826 * IntWriteConsoleOutput
1827 *
1828 * INTERNAL
1829 */
1830 BOOL WINAPI
1831 IntWriteConsoleOutput(HANDLE hConsoleOutput,
1832 CONST CHAR_INFO *lpBuffer,
1833 COORD dwBufferSize,
1834 COORD dwBufferCoord,
1835 PSMALL_RECT lpWriteRegion,
1836 BOOL bUnicode)
1837 {
1838 PCSRSS_API_REQUEST Request;
1839 CSRSS_API_REPLY Reply;
1840 NTSTATUS Status;
1841 ULONG Size;
1842 PVOID BufferBase;
1843 PVOID BufferTargetBase;
1844
1845 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
1846
1847 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
1848 Size,
1849 &BufferBase,
1850 &BufferTargetBase);
1851 if (!NT_SUCCESS(Status))
1852 {
1853 SetLastErrorByStatus(Status);
1854 return(FALSE);
1855 }
1856
1857 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY,
1858 sizeof(CSRSS_API_REQUEST));
1859 if (Request == NULL)
1860 {
1861 CsrReleaseParameterBuffer(BufferBase);
1862 SetLastError(ERROR_OUTOFMEMORY);
1863 return FALSE;
1864 }
1865 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
1866 Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1867 Request->Data.WriteConsoleOutputRequest.Unicode = bUnicode;
1868 Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
1869 Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
1870 Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
1871 Request->Data.WriteConsoleOutputRequest.CharInfo =
1872 (CHAR_INFO*)BufferTargetBase;
1873
1874 Status = CsrClientCallServer(Request, &Reply,
1875 sizeof(CSRSS_API_REQUEST),
1876 sizeof(CSRSS_API_REPLY));
1877 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1878 {
1879 CsrReleaseParameterBuffer(BufferBase);
1880 RtlFreeHeap(GetProcessHeap(), 0, Request);
1881 SetLastErrorByStatus(Status);
1882 return FALSE;
1883 }
1884
1885 *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
1886 RtlFreeHeap(GetProcessHeap(), 0, Request);
1887 CsrReleaseParameterBuffer(BufferBase);
1888 return(TRUE);
1889 }
1890
1891 /*--------------------------------------------------------------
1892 * WriteConsoleOutputA
1893 *
1894 * @implemented
1895 */
1896 BOOL WINAPI
1897 WriteConsoleOutputA(HANDLE hConsoleOutput,
1898 CONST CHAR_INFO *lpBuffer,
1899 COORD dwBufferSize,
1900 COORD dwBufferCoord,
1901 PSMALL_RECT lpWriteRegion)
1902 {
1903 return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1904 dwBufferCoord, lpWriteRegion, FALSE);
1905 }
1906
1907
1908 /*--------------------------------------------------------------
1909 * WriteConsoleOutputW
1910 *
1911 * @implemented
1912 */
1913 BOOL
1914 WINAPI
1915 WriteConsoleOutputW(
1916 HANDLE hConsoleOutput,
1917 CONST CHAR_INFO *lpBuffer,
1918 COORD dwBufferSize,
1919 COORD dwBufferCoord,
1920 PSMALL_RECT lpWriteRegion
1921 )
1922 {
1923 return IntWriteConsoleOutput(hConsoleOutput, lpBuffer, dwBufferSize,
1924 dwBufferCoord, lpWriteRegion, TRUE);
1925 }
1926
1927
1928 /*--------------------------------------------------------------
1929 * ReadConsoleOutputCharacterA
1930 *
1931 * @implemented
1932 */
1933 BOOL
1934 WINAPI
1935 ReadConsoleOutputCharacterA(
1936 HANDLE hConsoleOutput,
1937 LPSTR lpCharacter,
1938 DWORD nLength,
1939 COORD dwReadCoord,
1940 LPDWORD lpNumberOfCharsRead
1941 )
1942 {
1943 CSRSS_API_REQUEST Request;
1944 PCSRSS_API_REPLY Reply;
1945 NTSTATUS Status;
1946 DWORD Size;
1947
1948 Reply = RtlAllocateHeap(GetProcessHeap(), 0,
1949 sizeof(CSRSS_API_REPLY) +
1950 min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR));
1951 if (Reply == NULL)
1952 {
1953 SetLastError(ERROR_OUTOFMEMORY);
1954 return(FALSE);
1955 }
1956
1957 if (lpNumberOfCharsRead != NULL)
1958 *lpNumberOfCharsRead = nLength;
1959
1960 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
1961 Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1962 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
1963
1964 while (nLength != 0)
1965 {
1966 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
1967 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
1968 else
1969 Size = nLength;
1970
1971 Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
1972
1973 Status = CsrClientCallServer(&Request,
1974 Reply,
1975 sizeof(CSRSS_API_REQUEST),
1976 sizeof(CSRSS_API_REPLY) + Size);
1977 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1978 {
1979 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1980 SetLastErrorByStatus(Status);
1981 return(FALSE);
1982 }
1983
1984 memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
1985 lpCharacter += Size;
1986 nLength -= Size;
1987 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
1988 }
1989
1990 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1991
1992 return(TRUE);
1993 }
1994
1995
1996 /*--------------------------------------------------------------
1997 * ReadConsoleOutputCharacterW
1998 *
1999 * @unimplemented
2000 */
2001 BOOL
2002 WINAPI
2003 ReadConsoleOutputCharacterW(
2004 HANDLE hConsoleOutput,
2005 LPWSTR lpCharacter,
2006 DWORD nLength,
2007 COORD dwReadCoord,
2008 LPDWORD lpNumberOfCharsRead
2009 )
2010 {
2011 /* TO DO */
2012 DbgPrint("%s unimplemented\n", __FUNCTION__);
2013 return FALSE;
2014 }
2015
2016
2017 /*--------------------------------------------------------------
2018 * ReadConsoleOutputAttribute
2019 *
2020 * @implemented
2021 */
2022 BOOL
2023 WINAPI
2024 ReadConsoleOutputAttribute(
2025 HANDLE hConsoleOutput,
2026 LPWORD lpAttribute,
2027 DWORD nLength,
2028 COORD dwReadCoord,
2029 LPDWORD lpNumberOfAttrsRead
2030 )
2031 {
2032 CSRSS_API_REQUEST Request;
2033 PCSRSS_API_REPLY Reply;
2034 NTSTATUS Status;
2035 DWORD Size, i;
2036
2037 Reply = RtlAllocateHeap(GetProcessHeap(), 0,
2038 sizeof(CSRSS_API_REPLY) +
2039 min(nLength, CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB));
2040 if (Reply == NULL)
2041 {
2042 SetLastError(ERROR_OUTOFMEMORY);
2043 return(FALSE);
2044 }
2045
2046 if (lpNumberOfAttrsRead != NULL)
2047 *lpNumberOfAttrsRead = nLength;
2048
2049 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
2050 Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2051 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
2052
2053 while (nLength != 0)
2054 {
2055 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
2056 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
2057 else
2058 Size = nLength;
2059
2060 Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
2061
2062 Status = CsrClientCallServer(&Request,
2063 Reply,
2064 sizeof(CSRSS_API_REQUEST),
2065 sizeof(CSRSS_API_REPLY) + Size);
2066 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
2067 {
2068 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2069 SetLastErrorByStatus(Status);
2070 return(FALSE);
2071 }
2072
2073 // Convert CHARs to WORDs
2074 for(i = 0; i < Size; ++i)
2075 *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
2076
2077 nLength -= Size;
2078 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
2079 }
2080
2081 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2082
2083 return(TRUE);
2084 }
2085
2086
2087 /*--------------------------------------------------------------
2088 * WriteConsoleOutputCharacterA
2089 *
2090 * @implemented
2091 */
2092 BOOL WINAPI
2093 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2094 LPCSTR lpCharacter,
2095 DWORD nLength,
2096 COORD dwWriteCoord,
2097 LPDWORD lpNumberOfCharsWritten)
2098 {
2099 PCSRSS_API_REQUEST Request;
2100 CSRSS_API_REPLY Reply;
2101 NTSTATUS Status;
2102 WORD Size;
2103
2104 Request = RtlAllocateHeap(GetProcessHeap(), 0,
2105 sizeof(CSRSS_API_REQUEST) +
2106 min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
2107 if( !Request )
2108 {
2109 SetLastError( ERROR_OUTOFMEMORY );
2110 return FALSE;
2111 }
2112 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
2113 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2114 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2115 if( lpNumberOfCharsWritten )
2116 *lpNumberOfCharsWritten = nLength;
2117 while( nLength )
2118 {
2119 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
2120 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
2121 memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
2122 lpCharacter,
2123 Size );
2124 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
2125 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2126 {
2127 RtlFreeHeap( GetProcessHeap(), 0, Request );
2128 SetLastErrorByStatus ( Status );
2129 return FALSE;
2130 }
2131 nLength -= Size;
2132 lpCharacter += Size;
2133 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
2134 }
2135
2136 RtlFreeHeap( GetProcessHeap(), 0, Request );
2137 return TRUE;
2138 }
2139
2140
2141 /*--------------------------------------------------------------
2142 * WriteConsoleOutputCharacterW
2143 *
2144 * @implemented
2145 */
2146 BOOL WINAPI
2147 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2148 LPCWSTR lpCharacter,
2149 DWORD nLength,
2150 COORD dwWriteCoord,
2151 LPDWORD lpNumberOfCharsWritten)
2152 {
2153 PCSRSS_API_REQUEST Request;
2154 CSRSS_API_REPLY Reply;
2155 NTSTATUS Status;
2156 WORD Size;
2157
2158 Request = RtlAllocateHeap(GetProcessHeap(), 0,
2159 sizeof(CSRSS_API_REQUEST) +
2160 min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR));
2161 if( !Request )
2162 {
2163 SetLastError( ERROR_OUTOFMEMORY );
2164 return FALSE;
2165 }
2166 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
2167 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2168 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2169 if( lpNumberOfCharsWritten )
2170 *lpNumberOfCharsWritten = nLength;
2171 while( nLength )
2172 {
2173 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
2174 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
2175 Status = RtlUnicodeToOemN (&Request->Data.WriteConsoleOutputCharRequest.String[0],
2176 Size,
2177 NULL,
2178 (PWCHAR)lpCharacter,
2179 Size * sizeof(WCHAR));
2180 if (!NT_SUCCESS(Status))
2181 {
2182 RtlFreeHeap (GetProcessHeap(), 0, Request);
2183 SetLastErrorByStatus (Status);
2184 return FALSE;
2185 }
2186
2187 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
2188 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2189 {
2190 RtlFreeHeap( GetProcessHeap(), 0, Request );
2191 SetLastErrorByStatus ( Status );
2192 return FALSE;
2193 }
2194 nLength -= Size;
2195 lpCharacter += Size;
2196 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
2197 }
2198
2199 RtlFreeHeap( GetProcessHeap(), 0, Request );
2200 return TRUE;
2201 }
2202
2203
2204 /*--------------------------------------------------------------
2205 * WriteConsoleOutputAttribute
2206 *
2207 * @implemented
2208 */
2209 BOOL
2210 WINAPI
2211 WriteConsoleOutputAttribute(
2212 HANDLE hConsoleOutput,
2213 CONST WORD *lpAttribute,
2214 DWORD nLength,
2215 COORD dwWriteCoord,
2216 LPDWORD lpNumberOfAttrsWritten
2217 )
2218 {
2219 PCSRSS_API_REQUEST Request;
2220 CSRSS_API_REPLY Reply;
2221 NTSTATUS Status;
2222 WORD Size;
2223 int c;
2224
2225 Request = RtlAllocateHeap(GetProcessHeap(), 0,
2226 sizeof(CSRSS_API_REQUEST) +
2227 min(nLength, CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB));
2228 if( !Request )
2229 {
2230 SetLastError( ERROR_OUTOFMEMORY );
2231 return FALSE;
2232 }
2233 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
2234 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2235 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2236 if( lpNumberOfAttrsWritten )
2237 *lpNumberOfAttrsWritten = nLength;
2238 while( nLength )
2239 {
2240 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
2241 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2242 for( c = 0; c < ( Size * 2 ); c++ )
2243 Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
2244 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
2245 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2246 {
2247 RtlFreeHeap( GetProcessHeap(), 0, Request );
2248 SetLastErrorByStatus ( Status );
2249 return FALSE;
2250 }
2251 nLength -= Size;
2252 lpAttribute += Size;
2253 Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
2254 }
2255
2256 RtlFreeHeap( GetProcessHeap(), 0, Request );
2257 return TRUE;
2258 }
2259
2260
2261 /*--------------------------------------------------------------
2262 * FillConsoleOutputAttribute
2263 *
2264 * @implemented
2265 */
2266 BOOL
2267 WINAPI
2268 FillConsoleOutputAttribute(
2269 HANDLE hConsoleOutput,
2270 WORD wAttribute,
2271 DWORD nLength,
2272 COORD dwWriteCoord,
2273 LPDWORD lpNumberOfAttrsWritten
2274 )
2275 {
2276 CSRSS_API_REQUEST Request;
2277 CSRSS_API_REPLY Reply;
2278 NTSTATUS Status;
2279
2280 Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
2281 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2282 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
2283 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2284 Request.Data.FillOutputAttribRequest.Length = nLength;
2285 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2286 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2287 {
2288 SetLastErrorByStatus ( Status );
2289 return FALSE;
2290 }
2291 if( lpNumberOfAttrsWritten )
2292 *lpNumberOfAttrsWritten = nLength;
2293 return TRUE;
2294 }
2295
2296
2297 /*--------------------------------------------------------------
2298 * GetConsoleMode
2299 *
2300 * @implemented
2301 */
2302 BOOL
2303 WINAPI
2304 GetConsoleMode(
2305 HANDLE hConsoleHandle,
2306 LPDWORD lpMode
2307 )
2308 {
2309 CSRSS_API_REQUEST Request;
2310 CSRSS_API_REPLY Reply;
2311 NTSTATUS Status;
2312
2313 Request.Type = CSRSS_GET_CONSOLE_MODE;
2314 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2315 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2316 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2317 {
2318 SetLastErrorByStatus ( Status );
2319 return FALSE;
2320 }
2321 *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
2322 return TRUE;
2323 }
2324
2325
2326 /*--------------------------------------------------------------
2327 * GetNumberOfConsoleInputEvents
2328 *
2329 * @implemented
2330 */
2331 BOOL
2332 WINAPI
2333 GetNumberOfConsoleInputEvents(
2334 HANDLE hConsoleInput,
2335 LPDWORD lpNumberOfEvents
2336 )
2337 {
2338 CSRSS_API_REQUEST Request;
2339 CSRSS_API_REPLY Reply;
2340 NTSTATUS Status;
2341
2342 if(lpNumberOfEvents == NULL)
2343 {
2344 SetLastError(ERROR_INVALID_PARAMETER);
2345 return FALSE;
2346 }
2347
2348 Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
2349 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2350 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
2351 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
2352 {
2353 SetLastErrorByStatus(Status);
2354 return FALSE;
2355 }
2356
2357 *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
2358
2359 return TRUE;
2360 }
2361
2362
2363 /*--------------------------------------------------------------
2364 * GetLargestConsoleWindowSize
2365 *
2366 * @unimplemented
2367 */
2368 COORD
2369 WINAPI
2370 GetLargestConsoleWindowSize(
2371 HANDLE hConsoleOutput
2372 )
2373 {
2374 #if 1 /* FIXME: */
2375 COORD Coord = {80,25};
2376
2377 /* TO DO */
2378 return Coord;
2379 #endif
2380 }
2381
2382
2383 /*--------------------------------------------------------------
2384 * GetConsoleCursorInfo
2385 *
2386 * @implemented
2387 */
2388 BOOL
2389 WINAPI
2390 GetConsoleCursorInfo(
2391 HANDLE hConsoleOutput,
2392 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
2393 )
2394 {
2395 CSRSS_API_REQUEST Request;
2396 CSRSS_API_REPLY Reply;
2397 NTSTATUS Status;
2398
2399 Request.Type = CSRSS_GET_CURSOR_INFO;
2400 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2401 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2402
2403 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2404 {
2405 SetLastErrorByStatus ( Status );
2406 return FALSE;
2407 }
2408 *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
2409 return TRUE;
2410 }
2411
2412
2413 /*--------------------------------------------------------------
2414 * GetNumberOfConsoleMouseButtons
2415 *
2416 * @unimplemented
2417 */
2418 BOOL
2419 WINAPI
2420 GetNumberOfConsoleMouseButtons(
2421 LPDWORD lpNumberOfMouseButtons
2422 )
2423 {
2424 /* TO DO */
2425 return FALSE;
2426 }
2427
2428
2429 /*--------------------------------------------------------------
2430 * SetConsoleMode
2431 *
2432 * @implemented
2433 */
2434 BOOL
2435 WINAPI
2436 SetConsoleMode(
2437 HANDLE hConsoleHandle,
2438 DWORD dwMode
2439 )
2440 {
2441 CSRSS_API_REQUEST Request;
2442 CSRSS_API_REPLY Reply;
2443 NTSTATUS Status;
2444
2445 Request.Type = CSRSS_SET_CONSOLE_MODE;
2446 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2447 Request.Data.SetConsoleModeRequest.Mode = dwMode;
2448 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2449 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2450 {
2451 SetLastErrorByStatus ( Status );
2452 return FALSE;
2453 }
2454 return TRUE;
2455 }
2456
2457
2458 /*--------------------------------------------------------------
2459 * SetConsoleActiveScreenBuffer
2460 *
2461 * @implemented
2462 */
2463 BOOL
2464 WINAPI
2465 SetConsoleActiveScreenBuffer(
2466 HANDLE hConsoleOutput
2467 )
2468 {
2469 CSRSS_API_REQUEST Request;
2470 CSRSS_API_REPLY Reply;
2471 NTSTATUS Status;
2472
2473 Request.Type = CSRSS_SET_SCREEN_BUFFER;
2474 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
2475 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2476 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2477 {
2478 SetLastErrorByStatus ( Status );
2479 return FALSE;
2480 }
2481 return TRUE;
2482 }
2483
2484
2485 /*--------------------------------------------------------------
2486 * FlushConsoleInputBuffer
2487 *
2488 * @implemented
2489 */
2490 BOOL
2491 WINAPI
2492 FlushConsoleInputBuffer(
2493 HANDLE hConsoleInput
2494 )
2495 {
2496 CSRSS_API_REQUEST Request;
2497 CSRSS_API_REPLY Reply;
2498 NTSTATUS Status;
2499
2500 Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
2501 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
2502 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2503 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2504 {
2505 SetLastErrorByStatus ( Status );
2506 return FALSE;
2507 }
2508 return TRUE;
2509 }
2510
2511
2512 /*--------------------------------------------------------------
2513 * SetConsoleScreenBufferSize
2514 *
2515 * @unimplemented
2516 */
2517 BOOL
2518 WINAPI
2519 SetConsoleScreenBufferSize(
2520 HANDLE hConsoleOutput,
2521 COORD dwSize
2522 )
2523 {
2524 /* TO DO */
2525 DbgPrint("%s unimplemented\n", __FUNCTION__);
2526 return FALSE;
2527 }
2528
2529 /*--------------------------------------------------------------
2530 * SetConsoleCursorInfo
2531 *
2532 * @implemented
2533 */
2534 BOOL
2535 WINAPI
2536 SetConsoleCursorInfo(
2537 HANDLE hConsoleOutput,
2538 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
2539 )
2540 {
2541 CSRSS_API_REQUEST Request;
2542 CSRSS_API_REPLY Reply;
2543 NTSTATUS Status;
2544
2545 Request.Type = CSRSS_SET_CURSOR_INFO;
2546 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2547 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
2548 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2549
2550 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2551 {
2552 SetLastErrorByStatus ( Status );
2553 return FALSE;
2554 }
2555 return TRUE;
2556 }
2557
2558
2559 /*--------------------------------------------------------------
2560 * ScrollConsoleScreenBufferA
2561 *
2562 * @implemented
2563 */
2564 BOOL
2565 WINAPI
2566 ScrollConsoleScreenBufferA(
2567 HANDLE hConsoleOutput,
2568 CONST SMALL_RECT *lpScrollRectangle,
2569 CONST SMALL_RECT *lpClipRectangle,
2570 COORD dwDestinationOrigin,
2571 CONST CHAR_INFO *lpFill
2572 )
2573 {
2574 CSRSS_API_REQUEST Request;
2575 CSRSS_API_REPLY Reply;
2576 NTSTATUS Status;
2577
2578 Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
2579 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
2580 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
2581
2582 if (lpClipRectangle != NULL)
2583 {
2584 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
2585 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
2586 }
2587 else
2588 {
2589 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
2590 }
2591
2592 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
2593 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
2594 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2595
2596 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2597 {
2598 SetLastErrorByStatus ( Status );
2599 return FALSE;
2600 }
2601 return TRUE;
2602 }
2603
2604
2605 /*--------------------------------------------------------------
2606 * ScrollConsoleScreenBufferW
2607 *
2608 * @unimplemented
2609 */
2610 BOOL
2611 WINAPI
2612 ScrollConsoleScreenBufferW(
2613 HANDLE hConsoleOutput,
2614 CONST SMALL_RECT *lpScrollRectangle,
2615 CONST SMALL_RECT *lpClipRectangle,
2616 COORD dwDestinationOrigin,
2617 CONST CHAR_INFO *lpFill
2618 )
2619 {
2620 /* TO DO */
2621 DbgPrint("%s unimplemented\n", __FUNCTION__);
2622 return FALSE;
2623 }
2624
2625
2626 /*--------------------------------------------------------------
2627 * SetConsoleWindowInfo
2628 *
2629 * @unimplemented
2630 */
2631 BOOL
2632 WINAPI
2633 SetConsoleWindowInfo(
2634 HANDLE hConsoleOutput,
2635 BOOL bAbsolute,
2636 CONST SMALL_RECT *lpConsoleWindow
2637 )
2638 {
2639 /* TO DO */
2640 DbgPrint("%s unimplemented\n", __FUNCTION__);
2641 return FALSE;
2642 }
2643
2644
2645 /*--------------------------------------------------------------
2646 * SetConsoleTextAttribute
2647 *
2648 * @implemented
2649 */
2650 BOOL
2651 WINAPI
2652 SetConsoleTextAttribute(
2653 HANDLE hConsoleOutput,
2654 WORD wAttributes
2655 )
2656 {
2657 CSRSS_API_REQUEST Request;
2658 CSRSS_API_REPLY Reply;
2659 NTSTATUS Status;
2660
2661 Request.Type = CSRSS_SET_ATTRIB;
2662 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2663 Request.Data.SetAttribRequest.Attrib = wAttributes;
2664 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2665 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2666 {
2667 SetLastErrorByStatus ( Status );
2668 return FALSE;
2669 }
2670 return TRUE;
2671 }
2672
2673
2674 BOOL STATIC
2675 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2676 {
2677 if (HandlerRoutine == NULL)
2678 {
2679 IgnoreCtrlEvents = TRUE;
2680 return(TRUE);
2681 }
2682 else
2683 {
2684 NrCtrlHandlers++;
2685 CtrlHandlers =
2686 RtlReAllocateHeap(RtlGetProcessHeap(),
2687 HEAP_ZERO_MEMORY,
2688 (PVOID)CtrlHandlers,
2689 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2690 if (CtrlHandlers == NULL)
2691 {
2692 NrCtrlHandlers = 0;
2693 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2694 return(FALSE);
2695 }
2696 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2697 return(TRUE);
2698 }
2699 }
2700
2701
2702 BOOL STATIC
2703 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2704 {
2705 ULONG i;
2706
2707 if (HandlerRoutine == NULL)
2708 {
2709 IgnoreCtrlEvents = FALSE;
2710 return(TRUE);
2711 }
2712 else
2713 {
2714 for (i = 0; i < NrCtrlHandlers; i++)
2715 {
2716 if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
2717 {
2718 NrCtrlHandlers--;
2719 memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
2720 (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
2721 CtrlHandlers =
2722 RtlReAllocateHeap(RtlGetProcessHeap(),
2723 HEAP_ZERO_MEMORY,
2724 (PVOID)CtrlHandlers,
2725 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2726 return(TRUE);
2727 }
2728 }
2729 }
2730 return(FALSE);
2731 }
2732
2733
2734 /*
2735 * @implemented
2736 */
2737 BOOL WINAPI
2738 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2739 BOOL Add)
2740 {
2741 BOOLEAN Ret;
2742
2743 RtlEnterCriticalSection(&DllLock);
2744 if (Add)
2745 {
2746 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2747 }
2748 else
2749 {
2750 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2751 }
2752 RtlLeaveCriticalSection(&DllLock);
2753 return(Ret);
2754 }
2755
2756
2757 /*--------------------------------------------------------------
2758 * GenerateConsoleCtrlEvent
2759 *
2760 * @unimplemented
2761 */
2762 BOOL WINAPI
2763 GenerateConsoleCtrlEvent(
2764 DWORD dwCtrlEvent,
2765 DWORD dwProcessGroupId
2766 )
2767 {
2768 /* TO DO */
2769 return FALSE;
2770 }
2771
2772
2773 /*--------------------------------------------------------------
2774 * GetConsoleTitleW
2775 *
2776 * @implemented
2777 */
2778 DWORD
2779 WINAPI
2780 GetConsoleTitleW(
2781 LPWSTR lpConsoleTitle,
2782 DWORD nSize
2783 )
2784 {
2785 CSRSS_API_REQUEST Request;
2786 PCSRSS_API_REPLY Reply;
2787 NTSTATUS Status;
2788 HANDLE hConsole;
2789
2790 hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2791 if (hConsole == INVALID_HANDLE_VALUE)
2792 {
2793 return 0;
2794 }
2795
2796 Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2797 if(Reply == NULL)
2798 {
2799 CloseHandle(hConsole);
2800 SetLastError(ERROR_OUTOFMEMORY);
2801 return 0;
2802 }
2803
2804 Request.Type = CSRSS_GET_TITLE;
2805 Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
2806
2807 Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2808 CloseHandle(hConsole);
2809 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
2810 {
2811 SetLastErrorByStatus(Status);
2812 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2813 return 0;
2814 }
2815
2816 if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
2817 {
2818 wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
2819 lpConsoleTitle[nSize--] = L'\0';
2820 }
2821 else
2822 {
2823 nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
2824 wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
2825 lpConsoleTitle[nSize] = L'\0';
2826 }
2827
2828 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2829 return nSize;
2830 }
2831
2832
2833 /*--------------------------------------------------------------
2834 * GetConsoleTitleA
2835 *
2836 * 19990306 EA
2837 *
2838 * @implemented
2839 */
2840 DWORD
2841 WINAPI
2842 GetConsoleTitleA(
2843 LPSTR lpConsoleTitle,
2844 DWORD nSize
2845 )
2846 {
2847 wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
2848 DWORD nWideTitle = sizeof WideTitle;
2849 DWORD nWritten;
2850
2851 if (!lpConsoleTitle || !nSize) return 0;
2852 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
2853 if (!nWideTitle) return 0;
2854
2855 if ( (nWritten = WideCharToMultiByte(
2856 CP_ACP, // ANSI code page
2857 0, // performance and mapping flags
2858 (LPWSTR) WideTitle, // address of wide-character string
2859 nWideTitle, // number of characters in string
2860 lpConsoleTitle, // address of buffer for new string
2861 nSize, // size of buffer
2862 NULL, // FAST
2863 NULL // FAST
2864 )))
2865 {
2866 lpConsoleTitle[nWritten] = '\0';
2867 return nWritten;
2868 }
2869
2870 return 0;
2871 }
2872
2873
2874 /*--------------------------------------------------------------
2875 * SetConsoleTitleW
2876 *
2877 * @implemented
2878 */
2879 BOOL
2880 WINAPI
2881 SetConsoleTitleW(
2882 LPCWSTR lpConsoleTitle
2883 )
2884 {
2885 PCSRSS_API_REQUEST Request;
2886 CSRSS_API_REPLY Reply;
2887 NTSTATUS Status;
2888 unsigned int c;
2889 HANDLE hConsole;
2890
2891 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2892 if (hConsole == INVALID_HANDLE_VALUE)
2893 {
2894 return FALSE;
2895 }
2896
2897 Request = RtlAllocateHeap(GetProcessHeap(),
2898 HEAP_ZERO_MEMORY,
2899 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2900 if (Request == NULL)
2901 {
2902 CloseHandle(hConsole);
2903 SetLastError(ERROR_OUTOFMEMORY);
2904 return(FALSE);
2905 }
2906
2907 Request->Type = CSRSS_SET_TITLE;
2908 Request->Data.SetTitleRequest.Console = hConsole;
2909
2910 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2911 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2912 // add null
2913 Request->Data.SetTitleRequest.Title[c] = 0;
2914 Request->Data.SetTitleRequest.Length = c;
2915 Status = CsrClientCallServer(Request,
2916 &Reply,
2917 sizeof(CSRSS_API_REQUEST) +
2918 c * sizeof(WCHAR),
2919 sizeof(CSRSS_API_REPLY));
2920 CloseHandle(hConsole);
2921 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2922 {
2923 RtlFreeHeap( GetProcessHeap(), 0, Request );
2924 SetLastErrorByStatus (Status);
2925 return(FALSE);
2926 }
2927 RtlFreeHeap( GetProcessHeap(), 0, Request );
2928 return TRUE;
2929 }
2930
2931
2932 /*--------------------------------------------------------------
2933 * SetConsoleTitleA
2934 *
2935 * 19990204 EA Added
2936 *
2937 * @implemented
2938 */
2939 BOOL
2940 WINAPI
2941 SetConsoleTitleA(
2942 LPCSTR lpConsoleTitle
2943 )
2944 {
2945 PCSRSS_API_REQUEST Request;
2946 CSRSS_API_REPLY Reply;
2947 NTSTATUS Status;
2948 unsigned int c;
2949 HANDLE hConsole;
2950
2951 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2952 if (hConsole == INVALID_HANDLE_VALUE)
2953 {
2954 return FALSE;
2955 }
2956
2957 Request = RtlAllocateHeap(GetProcessHeap(),
2958 HEAP_ZERO_MEMORY,
2959 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2960 if (Request == NULL)
2961 {
2962 CloseHandle(hConsole);
2963 SetLastError(ERROR_OUTOFMEMORY);
2964 return(FALSE);
2965 }
2966
2967 Request->Type = CSRSS_SET_TITLE;
2968 Request->Data.SetTitleRequest.Console = hConsole;
2969
2970 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2971 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2972 // add null
2973 Request->Data.SetTitleRequest.Title[c] = 0;
2974 Request->Data.SetTitleRequest.Length = c;
2975 Status = CsrClientCallServer(Request,
2976 &Reply,
2977 sizeof(CSRSS_API_REQUEST) +
2978 c * sizeof(WCHAR),
2979 sizeof(CSRSS_API_REPLY));
2980 CloseHandle(hConsole);
2981 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2982 {
2983 RtlFreeHeap( GetProcessHeap(), 0, Request );
2984 SetLastErrorByStatus (Status);
2985 return(FALSE);
2986 }
2987 RtlFreeHeap( GetProcessHeap(), 0, Request );
2988 return TRUE;
2989 }
2990
2991
2992 /*--------------------------------------------------------------
2993 * ReadConsoleW
2994 *
2995 * @unimplemented
2996 */
2997 BOOL
2998 WINAPI
2999 ReadConsoleW(
3000 HANDLE hConsoleInput,
3001 LPVOID lpBuffer,
3002 DWORD nNumberOfCharsToRead,
3003 LPDWORD lpNumberOfCharsRead,
3004 LPVOID lpReserved
3005 )
3006 {
3007 /* --- TO DO --- */
3008 DbgPrint("%s unimplemented\n", __FUNCTION__);
3009 return FALSE;
3010 }
3011
3012
3013 /*--------------------------------------------------------------
3014 * WriteConsoleW
3015 *
3016 * @unimplemented
3017 */
3018 BOOL
3019 WINAPI
3020 WriteConsoleW(
3021 HANDLE hConsoleOutput,
3022 CONST VOID *lpBuffer,
3023 DWORD nNumberOfCharsToWrite,
3024 LPDWORD lpNumberOfCharsWritten,
3025 LPVOID lpReserved
3026 )
3027 {
3028 DbgPrint("%s unimplemented\n", __FUNCTION__);
3029 #if 0
3030 PCSRSS_API_REQUEST Request;
3031 CSRSS_API_REPLY Reply;
3032 NTSTATUS Status;
3033
3034 Request = RtlAllocateHeap(GetProcessHeap(),
3035 HEAP_ZERO_MEMORY,
3036 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
3037 if (Request == NULL)
3038 {
3039 SetLastError(ERROR_OUTOFMEMORY);
3040 return(FALSE);
3041 }
3042
3043 Request->Type = CSRSS_WRITE_CONSOLE;
3044 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
3045 Request->Data.WriteConsoleRequest.NrCharactersToWrite =
3046 nNumberOfCharsToWrite;
3047 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
3048 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
3049 memcpy(Request->Data.WriteConsoleRequest.Buffer,
3050 lpBuffer,
3051 nNumberOfCharsToWrite * sizeof(WCHAR));
3052
3053 Status = CsrClientCallServer(Request,
3054 &Reply,
3055 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
3056 sizeof(CSRSS_API_REPLY));
3057
3058 RtlFreeHeap(GetProcessHeap(),
3059 0,
3060 Request);
3061
3062 if (!NT_SUCCESS(Status))
3063 {
3064 return(FALSE);
3065 }
3066
3067 if (lpNumberOfCharsWritten != NULL)
3068 {
3069 *lpNumberOfCharsWritten =
3070 Reply.Data.WriteConsoleReply.NrCharactersWritten;
3071 }
3072
3073 return(TRUE);
3074 #endif
3075 return(FALSE);
3076 }
3077
3078
3079 /*--------------------------------------------------------------
3080 * CreateConsoleScreenBuffer
3081 *
3082 * @implemented
3083 */
3084 HANDLE
3085 WINAPI
3086 CreateConsoleScreenBuffer(
3087 DWORD dwDesiredAccess,
3088 DWORD dwShareMode,
3089 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3090 DWORD dwFlags,
3091 LPVOID lpScreenBufferData
3092 )
3093 {
3094 // FIXME: don't ignore access, share mode, and security
3095 CSRSS_API_REQUEST Request;
3096 CSRSS_API_REPLY Reply;
3097 NTSTATUS Status;
3098
3099 Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
3100 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3101 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
3102 {
3103 SetLastErrorByStatus ( Status );
3104 return FALSE;
3105 }
3106 return Reply.Data.CreateScreenBufferReply.OutputHandle;
3107 }
3108
3109
3110 /*--------------------------------------------------------------
3111 * GetConsoleCP
3112 *
3113 * @implemented
3114 */
3115 UINT
3116 WINAPI
3117 GetConsoleCP( VOID )
3118 {
3119 CSRSS_API_REQUEST Request;
3120 CSRSS_API_REPLY Reply;
3121 NTSTATUS Status;
3122
3123 Request.Type = CSRSS_GET_CONSOLE_CP;
3124 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
3125 sizeof(CSRSS_API_REPLY));
3126 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3127 {
3128 SetLastErrorByStatus (Status);
3129 return 0;
3130 }
3131 return Reply.Data.GetConsoleCodePage.CodePage;
3132 }
3133
3134
3135 /*--------------------------------------------------------------
3136 * SetConsoleCP
3137 *
3138 * @implemented
3139 */
3140 BOOL
3141 WINAPI
3142 SetConsoleCP(
3143 UINT wCodePageID
3144 )
3145 {
3146 CSRSS_API_REQUEST Request;
3147 CSRSS_API_REPLY Reply;
3148 NTSTATUS Status;
3149
3150 Request.Type = CSRSS_SET_CONSOLE_CP;
3151 Request.Data.SetConsoleCodePage.CodePage = wCodePageID;
3152 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
3153 sizeof(CSRSS_API_REPLY));
3154 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3155 {
3156 SetLastErrorByStatus (Status);
3157 }
3158 return NT_SUCCESS(Status);
3159 }
3160
3161
3162 /*--------------------------------------------------------------
3163 * GetConsoleOutputCP
3164 *
3165 * @implemented
3166 */
3167 UINT
3168 WINAPI
3169 GetConsoleOutputCP( VOID )
3170 {
3171 CSRSS_API_REQUEST Request;
3172 CSRSS_API_REPLY Reply;
3173 NTSTATUS Status;
3174
3175 Request.Type = CSRSS_GET_CONSOLE_OUTPUT_CP;
3176 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
3177 sizeof(CSRSS_API_REPLY));
3178 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3179 {
3180 SetLastErrorByStatus (Status);
3181 return 0;
3182 }
3183 return Reply.Data.GetConsoleOutputCodePage.CodePage;
3184 }
3185
3186
3187 /*--------------------------------------------------------------
3188 * SetConsoleOutputCP
3189 *
3190 * @implemented
3191 */
3192 BOOL
3193 WINAPI
3194 SetConsoleOutputCP(
3195 UINT wCodePageID
3196 )
3197 {
3198 CSRSS_API_REQUEST Request;
3199 CSRSS_API_REPLY Reply;
3200 NTSTATUS Status;
3201
3202 Request.Type = CSRSS_SET_CONSOLE_OUTPUT_CP;
3203 Request.Data.SetConsoleOutputCodePage.CodePage = wCodePageID;
3204 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
3205 sizeof(CSRSS_API_REPLY));
3206 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3207 {
3208 SetLastErrorByStatus (Status);
3209 }
3210 return NT_SUCCESS(Status);
3211 }
3212
3213
3214 /*--------------------------------------------------------------
3215 * GetConsoleProcessList
3216 *
3217 * @unimplemented
3218 */
3219 DWORD STDCALL
3220 GetConsoleProcessList(LPDWORD lpdwProcessList,
3221 DWORD dwProcessCount)
3222 {
3223 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3224 return 0;
3225 }
3226
3227
3228
3229 /*--------------------------------------------------------------
3230 * GetConsoleSelectionInfo
3231 *
3232 * @unimplemented
3233 */
3234 BOOL STDCALL
3235 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3236 {
3237 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3238 return FALSE;
3239 }
3240
3241
3242
3243 /*--------------------------------------------------------------
3244 * AttachConsole
3245 *
3246 * @unimplemented
3247 */
3248 BOOL STDCALL
3249 AttachConsole(DWORD dwProcessId)
3250 {
3251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3252 return FALSE;
3253 }
3254
3255 /*--------------------------------------------------------------
3256 * GetConsoleWindow
3257 *
3258 * @implemented
3259 */
3260 HWND STDCALL
3261 GetConsoleWindow (VOID)
3262 {
3263 CSRSS_API_REQUEST Request;
3264 CSRSS_API_REPLY Reply;
3265 NTSTATUS Status;
3266
3267 Request.Type = CSRSS_GET_CONSOLE_WINDOW;
3268 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3269 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
3270 {
3271 SetLastErrorByStatus (Status);
3272 return (HWND) NULL;
3273 }
3274 return Reply.Data.GetConsoleWindowReply.WindowHandle;
3275 }
3276
3277
3278 /*--------------------------------------------------------------
3279 * SetConsoleIcon
3280 *
3281 * @implemented
3282 */
3283 BOOL STDCALL SetConsoleIcon(HICON hicon)
3284 {
3285 CSRSS_API_REQUEST Request;
3286 CSRSS_API_REPLY Reply;
3287 NTSTATUS Status;
3288
3289 Request.Type = CSRSS_SET_CONSOLE_ICON;
3290 Request.Data.SetConsoleIconRequest.WindowIcon = hicon;
3291 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3292 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3293 {
3294 SetLastErrorByStatus (Status);
3295 return FALSE;
3296 }
3297 return NT_SUCCESS(Status);
3298 }
3299
3300 /* EOF */