- Compile kernel32 using w32api.
[reactos.git] / reactos / lib / kernel32 / misc / console.c
1 /* $Id: console.c,v 1.76 2004/06/13 20:04:56 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(),
1077 HEAP_ZERO_MEMORY,
1078 sizeof(CSRSS_API_REQUEST) +
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(),
1144 HEAP_ZERO_MEMORY,
1145 sizeof(CSRSS_API_REPLY) + nNumberOfCharsToRead);
1146 if (Reply == NULL)
1147 {
1148 SetLastError(ERROR_OUTOFMEMORY);
1149 return(FALSE);
1150 }
1151
1152 Request.Type = CSRSS_READ_CONSOLE;
1153 Request.Data.ReadConsoleRequest.ConsoleHandle = hConsoleInput;
1154 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
1155 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = 0;
1156 Status = CsrClientCallServer(&Request,
1157 Reply,
1158 sizeof(CSRSS_API_REQUEST),
1159 sizeof(CSRSS_API_REPLY) +
1160 Request.Data.ReadConsoleRequest.NrCharactersToRead);
1161 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply->Status ))
1162 {
1163 DbgPrint( "CSR returned error in ReadConsole\n" );
1164 SetLastErrorByStatus ( Status );
1165 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1166 return(FALSE);
1167 }
1168 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
1169 Reply->Status = STATUS_PENDING; // ignore backspace because we have no chars to backspace
1170 /* There may not be any chars or lines to read yet, so wait */
1171 while( Reply->Status == STATUS_PENDING )
1172 {
1173 /* some chars may have been returned, but not a whole line yet, so recompute buffer and try again */
1174 nNumberOfCharsToRead -= Reply->Data.ReadConsoleReply.NrCharactersRead;
1175 /* don't overflow caller's buffer, even if you still don't have a complete line */
1176 if( !nNumberOfCharsToRead )
1177 break;
1178 Request.Data.ReadConsoleRequest.NrCharactersToRead = nNumberOfCharsToRead > CSRSS_MAX_READ_CONSOLE_REQUEST ? CSRSS_MAX_READ_CONSOLE_REQUEST : nNumberOfCharsToRead;
1179 /* copy any chars already read to buffer */
1180 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
1181 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
1182 /* wait for csrss to signal there is more data to read, but not if we got STATUS_NOTIFY_CLEANUP for backspace */
1183 Status = NtWaitForSingleObject( Reply->Data.ReadConsoleReply.EventHandle, FALSE, 0 );
1184 if( !NT_SUCCESS( Status ) )
1185 {
1186 DbgPrint( "Wait for console input failed!\n" );
1187 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1188 return FALSE;
1189 }
1190 Request.Data.ReadConsoleRequest.nCharsCanBeDeleted = CharsRead;
1191 Status = CsrClientCallServer( &Request, Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) + Request.Data.ReadConsoleRequest.NrCharactersToRead );
1192 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply->Status ) )
1193 {
1194 SetLastErrorByStatus ( Status );
1195 RtlFreeHeap( GetProcessHeap(), 0, Reply );
1196 return FALSE;
1197 }
1198 if( Reply->Status == STATUS_NOTIFY_CLEANUP )
1199 {
1200 // delete last char
1201 if( CharsRead )
1202 {
1203 CharsRead--;
1204 nNumberOfCharsToRead++;
1205 }
1206 Reply->Status = STATUS_PENDING; // retry
1207 }
1208 }
1209 /* copy data to buffer, count total returned, and return */
1210 memcpy( lpBuffer + CharsRead, Reply->Data.ReadConsoleReply.Buffer, Reply->Data.ReadConsoleReply.NrCharactersRead );
1211 CharsRead += Reply->Data.ReadConsoleReply.NrCharactersRead;
1212 if (lpNumberOfCharsRead != NULL)
1213 *lpNumberOfCharsRead = CharsRead;
1214 RtlFreeHeap(GetProcessHeap(),
1215 0,
1216 Reply);
1217
1218 return(TRUE);
1219 }
1220
1221
1222 /*--------------------------------------------------------------
1223 * AllocConsole
1224 *
1225 * @implemented
1226 */
1227 BOOL STDCALL AllocConsole(VOID)
1228 {
1229 CSRSS_API_REQUEST Request;
1230 CSRSS_API_REPLY Reply;
1231 NTSTATUS Status;
1232 HANDLE hStdError;
1233
1234 if(NtCurrentPeb()->ProcessParameters->hConsole)
1235 {
1236 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
1237 SetLastErrorByStatus (STATUS_OBJECT_NAME_EXISTS);
1238 return FALSE;
1239 }
1240
1241 Request.Data.AllocConsoleRequest.CtrlDispatcher = (PCONTROLDISPATCHER) &ConsoleControlDispatcher;
1242
1243 Request.Type = CSRSS_ALLOC_CONSOLE;
1244 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1245 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1246 {
1247 SetLastErrorByStatus ( Status );
1248 return FALSE;
1249 }
1250 NtCurrentPeb()->ProcessParameters->hConsole = Reply.Data.AllocConsoleReply.Console;
1251 SetStdHandle( STD_INPUT_HANDLE, Reply.Data.AllocConsoleReply.InputHandle );
1252 SetStdHandle( STD_OUTPUT_HANDLE, Reply.Data.AllocConsoleReply.OutputHandle );
1253 hStdError = DuplicateConsoleHandle(Reply.Data.AllocConsoleReply.OutputHandle,
1254 0,
1255 TRUE,
1256 DUPLICATE_SAME_ACCESS);
1257 SetStdHandle( STD_ERROR_HANDLE, hStdError );
1258 return TRUE;
1259 }
1260
1261
1262 /*--------------------------------------------------------------
1263 * FreeConsole
1264 *
1265 * @implemented
1266 */
1267 BOOL STDCALL FreeConsole(VOID)
1268 {
1269 // AG: I'm not sure if this is correct (what happens to std handles?)
1270 // but I just tried to reverse what AllocConsole() does...
1271
1272 CSRSS_API_REQUEST Request;
1273 CSRSS_API_REPLY Reply;
1274 NTSTATUS Status;
1275
1276 Request.Type = CSRSS_FREE_CONSOLE;
1277 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1278 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1279 {
1280 SetLastErrorByStatus ( Status );
1281 return FALSE;
1282 }
1283
1284 return TRUE;
1285 }
1286
1287
1288 /*--------------------------------------------------------------
1289 * GetConsoleScreenBufferInfo
1290 *
1291 * @implemented
1292 */
1293 BOOL
1294 STDCALL
1295 GetConsoleScreenBufferInfo(
1296 HANDLE hConsoleOutput,
1297 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo
1298 )
1299 {
1300 CSRSS_API_REQUEST Request;
1301 CSRSS_API_REPLY Reply;
1302 NTSTATUS Status;
1303
1304 Request.Type = CSRSS_SCREEN_BUFFER_INFO;
1305 Request.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
1306 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1307 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1308 {
1309 SetLastErrorByStatus ( Status );
1310 return FALSE;
1311 }
1312 *lpConsoleScreenBufferInfo = Reply.Data.ScreenBufferInfoReply.Info;
1313 return TRUE;
1314 }
1315
1316
1317 /*--------------------------------------------------------------
1318 * SetConsoleCursorPosition
1319 *
1320 * @implemented
1321 */
1322 BOOL
1323 STDCALL
1324 SetConsoleCursorPosition(
1325 HANDLE hConsoleOutput,
1326 COORD dwCursorPosition
1327 )
1328 {
1329 CSRSS_API_REQUEST Request;
1330 CSRSS_API_REPLY Reply;
1331 NTSTATUS Status;
1332
1333 Request.Type = CSRSS_SET_CURSOR;
1334 Request.Data.SetCursorRequest.ConsoleHandle = hConsoleOutput;
1335 Request.Data.SetCursorRequest.Position = dwCursorPosition;
1336 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1337 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1338 {
1339 SetLastErrorByStatus ( Status );
1340 return FALSE;
1341 }
1342 return TRUE;
1343 }
1344
1345
1346 /*--------------------------------------------------------------
1347 * FillConsoleOutputCharacterA
1348 *
1349 * @implemented
1350 */
1351 BOOL STDCALL
1352 FillConsoleOutputCharacterA(
1353 HANDLE hConsoleOutput,
1354 CHAR cCharacter,
1355 DWORD nLength,
1356 COORD dwWriteCoord,
1357 LPDWORD lpNumberOfCharsWritten
1358 )
1359 {
1360 CSRSS_API_REQUEST Request;
1361 CSRSS_API_REPLY Reply;
1362 NTSTATUS Status;
1363
1364 Request.Type = CSRSS_FILL_OUTPUT;
1365 Request.Data.FillOutputRequest.ConsoleHandle = hConsoleOutput;
1366 Request.Data.FillOutputRequest.Char = cCharacter;
1367 Request.Data.FillOutputRequest.Position = dwWriteCoord;
1368 Request.Data.FillOutputRequest.Length = nLength;
1369 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
1370 if ( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
1371 {
1372 SetLastErrorByStatus(Status);
1373 return(FALSE);
1374 }
1375 if (lpNumberOfCharsWritten != NULL)
1376 *lpNumberOfCharsWritten = nLength;
1377 return(TRUE);
1378 }
1379
1380
1381 /*--------------------------------------------------------------
1382 * FillConsoleOutputCharacterW
1383 *
1384 * @unimplemented
1385 */
1386 BOOL
1387 STDCALL
1388 FillConsoleOutputCharacterW(
1389 HANDLE hConsoleOutput,
1390 WCHAR cCharacter,
1391 DWORD nLength,
1392 COORD dwWriteCoord,
1393 LPDWORD lpNumberOfCharsWritten
1394 )
1395 {
1396 /* TO DO */
1397 return FALSE;
1398 }
1399
1400
1401 /*--------------------------------------------------------------
1402 * PeekConsoleInputA
1403 *
1404 * @implemented
1405 */
1406 BOOL
1407 WINAPI
1408 PeekConsoleInputA(
1409 HANDLE hConsoleInput,
1410 PINPUT_RECORD lpBuffer,
1411 DWORD nLength,
1412 LPDWORD lpNumberOfEventsRead
1413 )
1414 {
1415 PCSRSS_API_REQUEST Request;
1416 CSRSS_API_REPLY Reply;
1417 NTSTATUS Status;
1418 PVOID BufferBase;
1419 PVOID BufferTargetBase;
1420 DWORD Size;
1421
1422 if(lpBuffer == NULL)
1423 {
1424 SetLastError(ERROR_INVALID_PARAMETER);
1425 return FALSE;
1426 }
1427
1428 Size = nLength * sizeof(INPUT_RECORD);
1429
1430 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1431 if(!NT_SUCCESS(Status))
1432 {
1433 SetLastErrorByStatus(Status);
1434 return FALSE;
1435 }
1436
1437 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1438 if(Request == NULL)
1439 {
1440 CsrReleaseParameterBuffer(BufferBase);
1441 SetLastError(ERROR_OUTOFMEMORY);
1442 return FALSE;
1443 }
1444
1445 Request->Type = CSRSS_PEEK_CONSOLE_INPUT;
1446 Request->Data.PeekConsoleInputRequest.ConsoleHandle = hConsoleInput;
1447 Request->Data.PeekConsoleInputRequest.Length = nLength;
1448 Request->Data.PeekConsoleInputRequest.InputRecord = (INPUT_RECORD*)BufferTargetBase;
1449
1450 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1451
1452 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1453 {
1454 RtlFreeHeap(GetProcessHeap(), 0, Request);
1455 CsrReleaseParameterBuffer(BufferBase);
1456 return FALSE;
1457 }
1458
1459 memcpy(lpBuffer, BufferBase, sizeof(INPUT_RECORD) * Reply.Data.PeekConsoleInputReply.Length);
1460
1461 if(lpNumberOfEventsRead != NULL)
1462 *lpNumberOfEventsRead = Reply.Data.PeekConsoleInputReply.Length;
1463
1464 RtlFreeHeap(GetProcessHeap(), 0, Request);
1465 CsrReleaseParameterBuffer(BufferBase);
1466
1467 return TRUE;
1468 }
1469
1470
1471 /*--------------------------------------------------------------
1472 * PeekConsoleInputW
1473 *
1474 * @unimplemented
1475 */
1476 BOOL
1477 WINAPI
1478 PeekConsoleInputW(
1479 HANDLE hConsoleInput,
1480 PINPUT_RECORD lpBuffer,
1481 DWORD nLength,
1482 LPDWORD lpNumberOfEventsRead
1483 )
1484 {
1485 /* TO DO */
1486 return FALSE;
1487 }
1488
1489
1490 /*--------------------------------------------------------------
1491 * ReadConsoleInputA
1492 *
1493 * @implemented
1494 */
1495 BOOL WINAPI
1496 ReadConsoleInputA(HANDLE hConsoleInput,
1497 PINPUT_RECORD lpBuffer,
1498 DWORD nLength,
1499 LPDWORD lpNumberOfEventsRead)
1500 {
1501 CSRSS_API_REQUEST Request;
1502 CSRSS_API_REPLY Reply;
1503 DWORD NumEventsRead;
1504 NTSTATUS Status;
1505
1506 Request.Type = CSRSS_READ_INPUT;
1507 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1508 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1509 sizeof(CSRSS_API_REPLY));
1510 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1511 {
1512 SetLastErrorByStatus(Status);
1513 return(FALSE);
1514 }
1515
1516 while (Status == STATUS_PENDING)
1517 {
1518 Status = NtWaitForSingleObject(Reply.Data.ReadInputReply.Event, FALSE,
1519 0);
1520 if(!NT_SUCCESS(Status))
1521 {
1522 SetLastErrorByStatus(Status);
1523 return FALSE;
1524 }
1525
1526 Request.Type = CSRSS_READ_INPUT;
1527 Request.Data.ReadInputRequest.ConsoleHandle = hConsoleInput;
1528 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1529 sizeof(CSRSS_API_REPLY));
1530 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1531 {
1532 SetLastErrorByStatus(Status);
1533 return(FALSE);
1534 }
1535 }
1536
1537 NumEventsRead = 0;
1538 *lpBuffer = Reply.Data.ReadInputReply.Input;
1539 lpBuffer++;
1540 NumEventsRead++;
1541
1542 while ((NumEventsRead < nLength) && (Reply.Data.ReadInputReply.MoreEvents))
1543 {
1544 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST),
1545 sizeof(CSRSS_API_REPLY));
1546 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1547 {
1548 SetLastErrorByStatus(Status);
1549 return(FALSE);
1550 }
1551
1552 if (Status == STATUS_PENDING)
1553 {
1554 break;
1555 }
1556
1557 *lpBuffer = Reply.Data.ReadInputReply.Input;
1558 lpBuffer++;
1559 NumEventsRead++;
1560
1561 }
1562 *lpNumberOfEventsRead = NumEventsRead;
1563
1564 return TRUE;
1565 }
1566
1567
1568 /*--------------------------------------------------------------
1569 * ReadConsoleInputW
1570 *
1571 * @unimplemented
1572 */
1573 BOOL
1574 WINAPI
1575 ReadConsoleInputW(
1576 HANDLE hConsoleInput,
1577 PINPUT_RECORD lpBuffer,
1578 DWORD nLength,
1579 LPDWORD lpNumberOfEventsRead
1580 )
1581 {
1582 /* TO DO */
1583 return FALSE;
1584 }
1585
1586
1587 /*--------------------------------------------------------------
1588 * WriteConsoleInputA
1589 *
1590 * @implemented
1591 */
1592 BOOL
1593 WINAPI
1594 WriteConsoleInputA(
1595 HANDLE hConsoleInput,
1596 CONST INPUT_RECORD *lpBuffer,
1597 DWORD nLength,
1598 LPDWORD lpNumberOfEventsWritten
1599 )
1600 {
1601 PCSRSS_API_REQUEST Request;
1602 CSRSS_API_REPLY Reply;
1603 PVOID BufferBase, BufferTargetBase;
1604 NTSTATUS Status;
1605 DWORD Size;
1606
1607 if(lpBuffer == NULL)
1608 {
1609 SetLastError(ERROR_INVALID_PARAMETER);
1610 return FALSE;
1611 }
1612
1613 Size = nLength * sizeof(INPUT_RECORD);
1614
1615 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1616 if(!NT_SUCCESS(Status))
1617 {
1618 SetLastErrorByStatus(Status);
1619 return FALSE;
1620 }
1621
1622 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1623 if(Request == NULL)
1624 {
1625 SetLastError(ERROR_OUTOFMEMORY);
1626 CsrReleaseParameterBuffer(BufferBase);
1627 return FALSE;
1628 }
1629
1630 Request->Type = CSRSS_WRITE_CONSOLE_INPUT;
1631 Request->Data.WriteConsoleInputRequest.ConsoleHandle = hConsoleInput;
1632 Request->Data.WriteConsoleInputRequest.Length = nLength;
1633 Request->Data.WriteConsoleInputRequest.InputRecord = (PINPUT_RECORD)BufferTargetBase;
1634
1635 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1636 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1637 {
1638 RtlFreeHeap(GetProcessHeap(), 0, Request);
1639 CsrReleaseParameterBuffer(BufferBase);
1640 return FALSE;
1641 }
1642
1643 if(lpNumberOfEventsWritten != NULL)
1644 *lpNumberOfEventsWritten = Reply.Data.WriteConsoleInputReply.Length;
1645
1646 RtlFreeHeap(GetProcessHeap(), 0, Request);
1647 CsrReleaseParameterBuffer(BufferBase);
1648
1649 return TRUE;
1650 }
1651
1652
1653 /*--------------------------------------------------------------
1654 * WriteConsoleInputW
1655 *
1656 * @unimplemented
1657 */
1658 BOOL
1659 WINAPI
1660 WriteConsoleInputW(
1661 HANDLE hConsoleInput,
1662 CONST INPUT_RECORD *lpBuffer,
1663 DWORD nLength,
1664 LPDWORD lpNumberOfEventsWritten
1665 )
1666 {
1667 /* TO DO */
1668 return FALSE;
1669 }
1670
1671
1672 /*--------------------------------------------------------------
1673 * ReadConsoleOutputA
1674 *
1675 * @implemented
1676 */
1677 BOOL
1678 WINAPI
1679 ReadConsoleOutputA(
1680 HANDLE hConsoleOutput,
1681 PCHAR_INFO lpBuffer,
1682 COORD dwBufferSize,
1683 COORD dwBufferCoord,
1684 PSMALL_RECT lpReadRegion
1685 )
1686 {
1687 PCSRSS_API_REQUEST Request;
1688 CSRSS_API_REPLY Reply;
1689 PVOID BufferBase;
1690 PVOID BufferTargetBase;
1691 NTSTATUS Status;
1692 DWORD Size, SizeX, SizeY;
1693
1694 if(lpBuffer == NULL)
1695 {
1696 SetLastError(ERROR_INVALID_PARAMETER);
1697 return FALSE;
1698 }
1699
1700 Size = dwBufferSize.X * dwBufferSize.Y * sizeof(CHAR_INFO);
1701
1702 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer, Size, &BufferBase, &BufferTargetBase);
1703 if(!NT_SUCCESS(Status))
1704 {
1705 SetLastErrorByStatus(Status);
1706 return FALSE;
1707 }
1708
1709 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REQUEST));
1710 if(Request == NULL)
1711 {
1712 SetLastError(ERROR_OUTOFMEMORY);
1713 CsrReleaseParameterBuffer(BufferBase);
1714 return FALSE;
1715 }
1716
1717 Request->Type = CSRSS_READ_CONSOLE_OUTPUT;
1718 Request->Data.ReadConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1719 Request->Data.ReadConsoleOutputRequest.BufferSize = dwBufferSize;
1720 Request->Data.ReadConsoleOutputRequest.BufferCoord = dwBufferCoord;
1721 Request->Data.ReadConsoleOutputRequest.ReadRegion = *lpReadRegion;
1722 Request->Data.ReadConsoleOutputRequest.CharInfo = (PCHAR_INFO)BufferTargetBase;
1723
1724 Status = CsrClientCallServer(Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
1725 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1726 {
1727 SetLastErrorByStatus(Status);
1728 RtlFreeHeap(GetProcessHeap(), 0, Request);
1729 CsrReleaseParameterBuffer(BufferBase);
1730 return FALSE;
1731 }
1732
1733 SizeX = Reply.Data.ReadConsoleOutputReply.ReadRegion.Right - Reply.Data.ReadConsoleOutputReply.ReadRegion.Left + 1;
1734 SizeY = Reply.Data.ReadConsoleOutputReply.ReadRegion.Bottom - Reply.Data.ReadConsoleOutputReply.ReadRegion.Top + 1;
1735
1736 memcpy(lpBuffer, BufferBase, sizeof(CHAR_INFO) * SizeX * SizeY);
1737 *lpReadRegion = Reply.Data.ReadConsoleOutputReply.ReadRegion;
1738
1739 RtlFreeHeap(GetProcessHeap(), 0, Request);
1740 CsrReleaseParameterBuffer(BufferBase);
1741
1742 return TRUE;
1743 }
1744
1745
1746 /*--------------------------------------------------------------
1747 * ReadConsoleOutputW
1748 *
1749 * @unimplemented
1750 */
1751 BOOL
1752 WINAPI
1753 ReadConsoleOutputW(
1754 HANDLE hConsoleOutput,
1755 PCHAR_INFO lpBuffer,
1756 COORD dwBufferSize,
1757 COORD dwBufferCoord,
1758 PSMALL_RECT lpReadRegion
1759 )
1760 {
1761 /* TO DO */
1762 return FALSE;
1763 }
1764
1765 /*--------------------------------------------------------------
1766 * WriteConsoleOutputA
1767 *
1768 * @implemented
1769 */
1770 BOOL WINAPI
1771 WriteConsoleOutputA(HANDLE hConsoleOutput,
1772 CONST CHAR_INFO *lpBuffer,
1773 COORD dwBufferSize,
1774 COORD dwBufferCoord,
1775 PSMALL_RECT lpWriteRegion)
1776 {
1777 PCSRSS_API_REQUEST Request;
1778 CSRSS_API_REPLY Reply;
1779 NTSTATUS Status;
1780 ULONG Size;
1781 PVOID BufferBase;
1782 PVOID BufferTargetBase;
1783
1784 Size = dwBufferSize.Y * dwBufferSize.X * sizeof(CHAR_INFO);
1785
1786 Status = CsrCaptureParameterBuffer((PVOID)lpBuffer,
1787 Size,
1788 &BufferBase,
1789 &BufferTargetBase);
1790 if (!NT_SUCCESS(Status))
1791 {
1792 SetLastErrorByStatus(Status);
1793 return(FALSE);
1794 }
1795
1796 Request = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY,
1797 sizeof(CSRSS_API_REQUEST));
1798 if (Request == NULL)
1799 {
1800 CsrReleaseParameterBuffer(BufferBase);
1801 SetLastError(ERROR_OUTOFMEMORY);
1802 return FALSE;
1803 }
1804 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT;
1805 Request->Data.WriteConsoleOutputRequest.ConsoleHandle = hConsoleOutput;
1806 Request->Data.WriteConsoleOutputRequest.BufferSize = dwBufferSize;
1807 Request->Data.WriteConsoleOutputRequest.BufferCoord = dwBufferCoord;
1808 Request->Data.WriteConsoleOutputRequest.WriteRegion = *lpWriteRegion;
1809 Request->Data.WriteConsoleOutputRequest.CharInfo =
1810 (CHAR_INFO*)BufferTargetBase;
1811
1812 Status = CsrClientCallServer(Request, &Reply,
1813 sizeof(CSRSS_API_REQUEST),
1814 sizeof(CSRSS_API_REPLY));
1815 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
1816 {
1817 CsrReleaseParameterBuffer(BufferBase);
1818 RtlFreeHeap(GetProcessHeap(), 0, Request);
1819 SetLastErrorByStatus(Status);
1820 return FALSE;
1821 }
1822
1823 *lpWriteRegion = Reply.Data.WriteConsoleOutputReply.WriteRegion;
1824 RtlFreeHeap(GetProcessHeap(), 0, Request);
1825 CsrReleaseParameterBuffer(BufferBase);
1826 return(TRUE);
1827 }
1828
1829
1830 /*--------------------------------------------------------------
1831 * WriteConsoleOutputW
1832 *
1833 * @unimplemented
1834 */
1835 BOOL
1836 WINAPI
1837 WriteConsoleOutputW(
1838 HANDLE hConsoleOutput,
1839 CONST CHAR_INFO *lpBuffer,
1840 COORD dwBufferSize,
1841 COORD dwBufferCoord,
1842 PSMALL_RECT lpWriteRegion
1843 )
1844 {
1845 /* TO DO */
1846 return FALSE;
1847 }
1848
1849
1850 /*--------------------------------------------------------------
1851 * ReadConsoleOutputCharacterA
1852 *
1853 * @implemented
1854 */
1855 BOOL
1856 WINAPI
1857 ReadConsoleOutputCharacterA(
1858 HANDLE hConsoleOutput,
1859 LPSTR lpCharacter,
1860 DWORD nLength,
1861 COORD dwReadCoord,
1862 LPDWORD lpNumberOfCharsRead
1863 )
1864 {
1865 CSRSS_API_REQUEST Request;
1866 PCSRSS_API_REPLY Reply;
1867 NTSTATUS Status;
1868 DWORD Size;
1869
1870 Reply = RtlAllocateHeap(GetProcessHeap(),
1871 HEAP_ZERO_MEMORY,
1872 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR);
1873 if (Reply == NULL)
1874 {
1875 SetLastError(ERROR_OUTOFMEMORY);
1876 return(FALSE);
1877 }
1878
1879 if (lpNumberOfCharsRead != NULL)
1880 *lpNumberOfCharsRead = nLength;
1881
1882 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_CHAR;
1883 Request.Data.ReadConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
1884 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = dwReadCoord;
1885
1886 while (nLength != 0)
1887 {
1888 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR)
1889 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_CHAR;
1890 else
1891 Size = nLength;
1892
1893 Request.Data.ReadConsoleOutputCharRequest.NumCharsToRead = Size;
1894
1895 Status = CsrClientCallServer(&Request,
1896 Reply,
1897 sizeof(CSRSS_API_REQUEST),
1898 sizeof(CSRSS_API_REPLY) + Size);
1899 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1900 {
1901 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1902 SetLastErrorByStatus(Status);
1903 return(FALSE);
1904 }
1905
1906 memcpy(lpCharacter, &Reply->Data.ReadConsoleOutputCharReply.String[0], Size);
1907 lpCharacter += Size;
1908 nLength -= Size;
1909 Request.Data.ReadConsoleOutputCharRequest.ReadCoord = Reply->Data.ReadConsoleOutputCharReply.EndCoord;
1910 }
1911
1912 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1913
1914 return(TRUE);
1915 }
1916
1917
1918 /*--------------------------------------------------------------
1919 * ReadConsoleOutputCharacterW
1920 *
1921 * @unimplemented
1922 */
1923 BOOL
1924 WINAPI
1925 ReadConsoleOutputCharacterW(
1926 HANDLE hConsoleOutput,
1927 LPWSTR lpCharacter,
1928 DWORD nLength,
1929 COORD dwReadCoord,
1930 LPDWORD lpNumberOfCharsRead
1931 )
1932 {
1933 /* TO DO */
1934 return FALSE;
1935 }
1936
1937
1938 /*--------------------------------------------------------------
1939 * ReadConsoleOutputAttribute
1940 *
1941 * @implemented
1942 */
1943 BOOL
1944 WINAPI
1945 ReadConsoleOutputAttribute(
1946 HANDLE hConsoleOutput,
1947 LPWORD lpAttribute,
1948 DWORD nLength,
1949 COORD dwReadCoord,
1950 LPDWORD lpNumberOfAttrsRead
1951 )
1952 {
1953 CSRSS_API_REQUEST Request;
1954 PCSRSS_API_REPLY Reply;
1955 NTSTATUS Status;
1956 DWORD Size, i;
1957
1958 Reply = RtlAllocateHeap(GetProcessHeap(),
1959 HEAP_ZERO_MEMORY,
1960 sizeof(CSRSS_API_REPLY) + CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB);
1961 if (Reply == NULL)
1962 {
1963 SetLastError(ERROR_OUTOFMEMORY);
1964 return(FALSE);
1965 }
1966
1967 if (lpNumberOfAttrsRead != NULL)
1968 *lpNumberOfAttrsRead = nLength;
1969
1970 Request.Type = CSRSS_READ_CONSOLE_OUTPUT_ATTRIB;
1971 Request.Data.ReadConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
1972 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = dwReadCoord;
1973
1974 while (nLength != 0)
1975 {
1976 if (nLength > CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB)
1977 Size = CSRSS_MAX_READ_CONSOLE_OUTPUT_ATTRIB;
1978 else
1979 Size = nLength;
1980
1981 Request.Data.ReadConsoleOutputAttribRequest.NumAttrsToRead = Size;
1982
1983 Status = CsrClientCallServer(&Request,
1984 Reply,
1985 sizeof(CSRSS_API_REQUEST),
1986 sizeof(CSRSS_API_REPLY) + Size);
1987 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Reply->Status))
1988 {
1989 RtlFreeHeap(GetProcessHeap(), 0, Reply);
1990 SetLastErrorByStatus(Status);
1991 return(FALSE);
1992 }
1993
1994 // Convert CHARs to WORDs
1995 for(i = 0; i < Size; ++i)
1996 *lpAttribute++ = Reply->Data.ReadConsoleOutputAttribReply.String[i];
1997
1998 nLength -= Size;
1999 Request.Data.ReadConsoleOutputAttribRequest.ReadCoord = Reply->Data.ReadConsoleOutputAttribReply.EndCoord;
2000 }
2001
2002 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2003
2004 return(TRUE);
2005 }
2006
2007
2008 /*--------------------------------------------------------------
2009 * WriteConsoleOutputCharacterA
2010 *
2011 * @implemented
2012 */
2013 BOOL WINAPI
2014 WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,
2015 LPCSTR lpCharacter,
2016 DWORD nLength,
2017 COORD dwWriteCoord,
2018 LPDWORD lpNumberOfCharsWritten)
2019 {
2020 PCSRSS_API_REQUEST Request;
2021 CSRSS_API_REPLY Reply;
2022 NTSTATUS Status;
2023 WORD Size;
2024
2025 Request = RtlAllocateHeap(GetProcessHeap(),
2026 HEAP_ZERO_MEMORY,
2027 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR);
2028 if( !Request )
2029 {
2030 SetLastError( ERROR_OUTOFMEMORY );
2031 return FALSE;
2032 }
2033 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
2034 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2035 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2036 if( lpNumberOfCharsWritten )
2037 *lpNumberOfCharsWritten = nLength;
2038 while( nLength )
2039 {
2040 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
2041 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
2042 memcpy( &Request->Data.WriteConsoleOutputCharRequest.String[0],
2043 lpCharacter,
2044 Size );
2045 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
2046 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2047 {
2048 RtlFreeHeap( GetProcessHeap(), 0, Request );
2049 SetLastErrorByStatus ( Status );
2050 return FALSE;
2051 }
2052 nLength -= Size;
2053 lpCharacter += Size;
2054 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
2055 }
2056
2057 RtlFreeHeap( GetProcessHeap(), 0, Request );
2058 return TRUE;
2059 }
2060
2061
2062 /*--------------------------------------------------------------
2063 * WriteConsoleOutputCharacterW
2064 *
2065 * @implemented
2066 */
2067 BOOL WINAPI
2068 WriteConsoleOutputCharacterW(HANDLE hConsoleOutput,
2069 LPCWSTR lpCharacter,
2070 DWORD nLength,
2071 COORD dwWriteCoord,
2072 LPDWORD lpNumberOfCharsWritten)
2073 {
2074 PCSRSS_API_REQUEST Request;
2075 CSRSS_API_REPLY Reply;
2076 NTSTATUS Status;
2077 WORD Size;
2078
2079 Request = RtlAllocateHeap(GetProcessHeap(),
2080 HEAP_ZERO_MEMORY,
2081 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR);
2082 if( !Request )
2083 {
2084 SetLastError( ERROR_OUTOFMEMORY );
2085 return FALSE;
2086 }
2087 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_CHAR;
2088 Request->Data.WriteConsoleOutputCharRequest.ConsoleHandle = hConsoleOutput;
2089 Request->Data.WriteConsoleOutputCharRequest.Coord = dwWriteCoord;
2090 if( lpNumberOfCharsWritten )
2091 *lpNumberOfCharsWritten = nLength;
2092 while( nLength )
2093 {
2094 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_CHAR : nLength;
2095 Request->Data.WriteConsoleOutputCharRequest.Length = Size;
2096 Status = RtlUnicodeToOemN (&Request->Data.WriteConsoleOutputCharRequest.String[0],
2097 Size,
2098 NULL,
2099 (PWCHAR)lpCharacter,
2100 Size * sizeof(WCHAR));
2101 if (!NT_SUCCESS(Status))
2102 {
2103 RtlFreeHeap (GetProcessHeap(), 0, Request);
2104 SetLastErrorByStatus (Status);
2105 return FALSE;
2106 }
2107
2108 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + Size, sizeof( CSRSS_API_REPLY ) );
2109 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2110 {
2111 RtlFreeHeap( GetProcessHeap(), 0, Request );
2112 SetLastErrorByStatus ( Status );
2113 return FALSE;
2114 }
2115 nLength -= Size;
2116 lpCharacter += Size;
2117 Request->Data.WriteConsoleOutputCharRequest.Coord = Reply.Data.WriteConsoleOutputCharReply.EndCoord;
2118 }
2119
2120 RtlFreeHeap( GetProcessHeap(), 0, Request );
2121 return TRUE;
2122 }
2123
2124
2125 /*--------------------------------------------------------------
2126 * WriteConsoleOutputAttribute
2127 *
2128 * @implemented
2129 */
2130 BOOL
2131 WINAPI
2132 WriteConsoleOutputAttribute(
2133 HANDLE hConsoleOutput,
2134 CONST WORD *lpAttribute,
2135 DWORD nLength,
2136 COORD dwWriteCoord,
2137 LPDWORD lpNumberOfAttrsWritten
2138 )
2139 {
2140 PCSRSS_API_REQUEST Request;
2141 CSRSS_API_REPLY Reply;
2142 NTSTATUS Status;
2143 WORD Size;
2144 int c;
2145
2146 Request = RtlAllocateHeap(GetProcessHeap(),
2147 HEAP_ZERO_MEMORY,
2148 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB);
2149 if( !Request )
2150 {
2151 SetLastError( ERROR_OUTOFMEMORY );
2152 return FALSE;
2153 }
2154 Request->Type = CSRSS_WRITE_CONSOLE_OUTPUT_ATTRIB;
2155 Request->Data.WriteConsoleOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2156 Request->Data.WriteConsoleOutputAttribRequest.Coord = dwWriteCoord;
2157 if( lpNumberOfAttrsWritten )
2158 *lpNumberOfAttrsWritten = nLength;
2159 while( nLength )
2160 {
2161 Size = nLength > CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB ? CSRSS_MAX_WRITE_CONSOLE_OUTPUT_ATTRIB : nLength;
2162 Request->Data.WriteConsoleOutputAttribRequest.Length = Size;
2163 for( c = 0; c < ( Size * 2 ); c++ )
2164 Request->Data.WriteConsoleOutputAttribRequest.String[c] = (char)lpAttribute[c];
2165 Status = CsrClientCallServer( Request, &Reply, sizeof( CSRSS_API_REQUEST ) + (Size * 2), sizeof( CSRSS_API_REPLY ) );
2166 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2167 {
2168 RtlFreeHeap( GetProcessHeap(), 0, Request );
2169 SetLastErrorByStatus ( Status );
2170 return FALSE;
2171 }
2172 nLength -= Size;
2173 lpAttribute += Size;
2174 Request->Data.WriteConsoleOutputAttribRequest.Coord = Reply.Data.WriteConsoleOutputAttribReply.EndCoord;
2175 }
2176
2177 RtlFreeHeap( GetProcessHeap(), 0, Request );
2178 return TRUE;
2179 }
2180
2181
2182 /*--------------------------------------------------------------
2183 * FillConsoleOutputAttribute
2184 *
2185 * @implemented
2186 */
2187 BOOL
2188 WINAPI
2189 FillConsoleOutputAttribute(
2190 HANDLE hConsoleOutput,
2191 WORD wAttribute,
2192 DWORD nLength,
2193 COORD dwWriteCoord,
2194 LPDWORD lpNumberOfAttrsWritten
2195 )
2196 {
2197 CSRSS_API_REQUEST Request;
2198 CSRSS_API_REPLY Reply;
2199 NTSTATUS Status;
2200
2201 Request.Type = CSRSS_FILL_OUTPUT_ATTRIB;
2202 Request.Data.FillOutputAttribRequest.ConsoleHandle = hConsoleOutput;
2203 Request.Data.FillOutputAttribRequest.Attribute = wAttribute;
2204 Request.Data.FillOutputAttribRequest.Coord = dwWriteCoord;
2205 Request.Data.FillOutputAttribRequest.Length = nLength;
2206 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2207 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2208 {
2209 SetLastErrorByStatus ( Status );
2210 return FALSE;
2211 }
2212 if( lpNumberOfAttrsWritten )
2213 *lpNumberOfAttrsWritten = nLength;
2214 return TRUE;
2215 }
2216
2217
2218 /*--------------------------------------------------------------
2219 * GetConsoleMode
2220 *
2221 * @implemented
2222 */
2223 BOOL
2224 WINAPI
2225 GetConsoleMode(
2226 HANDLE hConsoleHandle,
2227 LPDWORD lpMode
2228 )
2229 {
2230 CSRSS_API_REQUEST Request;
2231 CSRSS_API_REPLY Reply;
2232 NTSTATUS Status;
2233
2234 Request.Type = CSRSS_GET_CONSOLE_MODE;
2235 Request.Data.GetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2236 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2237 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2238 {
2239 SetLastErrorByStatus ( Status );
2240 return FALSE;
2241 }
2242 *lpMode = Reply.Data.GetConsoleModeReply.ConsoleMode;
2243 return TRUE;
2244 }
2245
2246
2247 /*--------------------------------------------------------------
2248 * GetNumberOfConsoleInputEvents
2249 *
2250 * @implemented
2251 */
2252 BOOL
2253 WINAPI
2254 GetNumberOfConsoleInputEvents(
2255 HANDLE hConsoleInput,
2256 LPDWORD lpNumberOfEvents
2257 )
2258 {
2259 CSRSS_API_REQUEST Request;
2260 CSRSS_API_REPLY Reply;
2261 NTSTATUS Status;
2262
2263 if(lpNumberOfEvents == NULL)
2264 {
2265 SetLastError(ERROR_INVALID_PARAMETER);
2266 return FALSE;
2267 }
2268
2269 Request.Type = CSRSS_GET_NUM_INPUT_EVENTS;
2270 Request.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
2271 Status = CsrClientCallServer(&Request, &Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY));
2272 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
2273 {
2274 SetLastErrorByStatus(Status);
2275 return FALSE;
2276 }
2277
2278 *lpNumberOfEvents = Reply.Data.GetNumInputEventsReply.NumInputEvents;
2279
2280 return TRUE;
2281 }
2282
2283
2284 /*--------------------------------------------------------------
2285 * GetLargestConsoleWindowSize
2286 *
2287 * @unimplemented
2288 */
2289 COORD
2290 WINAPI
2291 GetLargestConsoleWindowSize(
2292 HANDLE hConsoleOutput
2293 )
2294 {
2295 #if 1 /* FIXME: */
2296 COORD Coord = {80,25};
2297
2298 /* TO DO */
2299 return Coord;
2300 #endif
2301 }
2302
2303
2304 /*--------------------------------------------------------------
2305 * GetConsoleCursorInfo
2306 *
2307 * @implemented
2308 */
2309 BOOL
2310 WINAPI
2311 GetConsoleCursorInfo(
2312 HANDLE hConsoleOutput,
2313 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo
2314 )
2315 {
2316 CSRSS_API_REQUEST Request;
2317 CSRSS_API_REPLY Reply;
2318 NTSTATUS Status;
2319
2320 Request.Type = CSRSS_GET_CURSOR_INFO;
2321 Request.Data.GetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2322 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2323
2324 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2325 {
2326 SetLastErrorByStatus ( Status );
2327 return FALSE;
2328 }
2329 *lpConsoleCursorInfo = Reply.Data.GetCursorInfoReply.Info;
2330 return TRUE;
2331 }
2332
2333
2334 /*--------------------------------------------------------------
2335 * GetNumberOfConsoleMouseButtons
2336 *
2337 * @unimplemented
2338 */
2339 BOOL
2340 WINAPI
2341 GetNumberOfConsoleMouseButtons(
2342 LPDWORD lpNumberOfMouseButtons
2343 )
2344 {
2345 /* TO DO */
2346 return FALSE;
2347 }
2348
2349
2350 /*--------------------------------------------------------------
2351 * SetConsoleMode
2352 *
2353 * @implemented
2354 */
2355 BOOL
2356 WINAPI
2357 SetConsoleMode(
2358 HANDLE hConsoleHandle,
2359 DWORD dwMode
2360 )
2361 {
2362 CSRSS_API_REQUEST Request;
2363 CSRSS_API_REPLY Reply;
2364 NTSTATUS Status;
2365
2366 Request.Type = CSRSS_SET_CONSOLE_MODE;
2367 Request.Data.SetConsoleModeRequest.ConsoleHandle = hConsoleHandle;
2368 Request.Data.SetConsoleModeRequest.Mode = dwMode;
2369 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2370 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2371 {
2372 SetLastErrorByStatus ( Status );
2373 return FALSE;
2374 }
2375 return TRUE;
2376 }
2377
2378
2379 /*--------------------------------------------------------------
2380 * SetConsoleActiveScreenBuffer
2381 *
2382 * @implemented
2383 */
2384 BOOL
2385 WINAPI
2386 SetConsoleActiveScreenBuffer(
2387 HANDLE hConsoleOutput
2388 )
2389 {
2390 CSRSS_API_REQUEST Request;
2391 CSRSS_API_REPLY Reply;
2392 NTSTATUS Status;
2393
2394 Request.Type = CSRSS_SET_SCREEN_BUFFER;
2395 Request.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
2396 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2397 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2398 {
2399 SetLastErrorByStatus ( Status );
2400 return FALSE;
2401 }
2402 return TRUE;
2403 }
2404
2405
2406 /*--------------------------------------------------------------
2407 * FlushConsoleInputBuffer
2408 *
2409 * @implemented
2410 */
2411 BOOL
2412 WINAPI
2413 FlushConsoleInputBuffer(
2414 HANDLE hConsoleInput
2415 )
2416 {
2417 CSRSS_API_REQUEST Request;
2418 CSRSS_API_REPLY Reply;
2419 NTSTATUS Status;
2420
2421 Request.Type = CSRSS_FLUSH_INPUT_BUFFER;
2422 Request.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
2423 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2424 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2425 {
2426 SetLastErrorByStatus ( Status );
2427 return FALSE;
2428 }
2429 return TRUE;
2430 }
2431
2432
2433 /*--------------------------------------------------------------
2434 * SetConsoleScreenBufferSize
2435 *
2436 * @unimplemented
2437 */
2438 BOOL
2439 WINAPI
2440 SetConsoleScreenBufferSize(
2441 HANDLE hConsoleOutput,
2442 COORD dwSize
2443 )
2444 {
2445 /* TO DO */
2446 return FALSE;
2447 }
2448
2449 /*--------------------------------------------------------------
2450 * SetConsoleCursorInfo
2451 *
2452 * @implemented
2453 */
2454 BOOL
2455 WINAPI
2456 SetConsoleCursorInfo(
2457 HANDLE hConsoleOutput,
2458 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
2459 )
2460 {
2461 CSRSS_API_REQUEST Request;
2462 CSRSS_API_REPLY Reply;
2463 NTSTATUS Status;
2464
2465 Request.Type = CSRSS_SET_CURSOR_INFO;
2466 Request.Data.SetCursorInfoRequest.ConsoleHandle = hConsoleOutput;
2467 Request.Data.SetCursorInfoRequest.Info = *lpConsoleCursorInfo;
2468 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2469
2470 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2471 {
2472 SetLastErrorByStatus ( Status );
2473 return FALSE;
2474 }
2475 return TRUE;
2476 }
2477
2478
2479 /*--------------------------------------------------------------
2480 * ScrollConsoleScreenBufferA
2481 *
2482 * @implemented
2483 */
2484 BOOL
2485 WINAPI
2486 ScrollConsoleScreenBufferA(
2487 HANDLE hConsoleOutput,
2488 CONST SMALL_RECT *lpScrollRectangle,
2489 CONST SMALL_RECT *lpClipRectangle,
2490 COORD dwDestinationOrigin,
2491 CONST CHAR_INFO *lpFill
2492 )
2493 {
2494 CSRSS_API_REQUEST Request;
2495 CSRSS_API_REPLY Reply;
2496 NTSTATUS Status;
2497
2498 Request.Type = CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER;
2499 Request.Data.ScrollConsoleScreenBufferRequest.ConsoleHandle = hConsoleOutput;
2500 Request.Data.ScrollConsoleScreenBufferRequest.ScrollRectangle = *lpScrollRectangle;
2501
2502 if (lpClipRectangle != NULL)
2503 {
2504 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = TRUE;
2505 Request.Data.ScrollConsoleScreenBufferRequest.ClipRectangle = *lpClipRectangle;
2506 }
2507 else
2508 {
2509 Request.Data.ScrollConsoleScreenBufferRequest.UseClipRectangle = FALSE;
2510 }
2511
2512 Request.Data.ScrollConsoleScreenBufferRequest.DestinationOrigin = dwDestinationOrigin;
2513 Request.Data.ScrollConsoleScreenBufferRequest.Fill = *lpFill;
2514 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2515
2516 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2517 {
2518 SetLastErrorByStatus ( Status );
2519 return FALSE;
2520 }
2521 return TRUE;
2522 }
2523
2524
2525 /*--------------------------------------------------------------
2526 * ScrollConsoleScreenBufferW
2527 *
2528 * @unimplemented
2529 */
2530 BOOL
2531 WINAPI
2532 ScrollConsoleScreenBufferW(
2533 HANDLE hConsoleOutput,
2534 CONST SMALL_RECT *lpScrollRectangle,
2535 CONST SMALL_RECT *lpClipRectangle,
2536 COORD dwDestinationOrigin,
2537 CONST CHAR_INFO *lpFill
2538 )
2539 {
2540 /* TO DO */
2541 return FALSE;
2542 }
2543
2544
2545 /*--------------------------------------------------------------
2546 * SetConsoleWindowInfo
2547 *
2548 * @unimplemented
2549 */
2550 BOOL
2551 WINAPI
2552 SetConsoleWindowInfo(
2553 HANDLE hConsoleOutput,
2554 BOOL bAbsolute,
2555 CONST SMALL_RECT *lpConsoleWindow
2556 )
2557 {
2558 /* TO DO */
2559 return FALSE;
2560 }
2561
2562
2563 /*--------------------------------------------------------------
2564 * SetConsoleTextAttribute
2565 *
2566 * @implemented
2567 */
2568 BOOL
2569 WINAPI
2570 SetConsoleTextAttribute(
2571 HANDLE hConsoleOutput,
2572 WORD wAttributes
2573 )
2574 {
2575 CSRSS_API_REQUEST Request;
2576 CSRSS_API_REPLY Reply;
2577 NTSTATUS Status;
2578
2579 Request.Type = CSRSS_SET_ATTRIB;
2580 Request.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
2581 Request.Data.SetAttribRequest.Attrib = wAttributes;
2582 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
2583 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
2584 {
2585 SetLastErrorByStatus ( Status );
2586 return FALSE;
2587 }
2588 return TRUE;
2589 }
2590
2591
2592 BOOL STATIC
2593 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2594 {
2595 if (HandlerRoutine == NULL)
2596 {
2597 IgnoreCtrlEvents = TRUE;
2598 return(TRUE);
2599 }
2600 else
2601 {
2602 NrCtrlHandlers++;
2603 CtrlHandlers =
2604 RtlReAllocateHeap(RtlGetProcessHeap(),
2605 HEAP_ZERO_MEMORY,
2606 (PVOID)CtrlHandlers,
2607 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2608 if (CtrlHandlers == NULL)
2609 {
2610 NrCtrlHandlers = 0;
2611 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2612 return(FALSE);
2613 }
2614 CtrlHandlers[NrCtrlHandlers - 1] = HandlerRoutine;
2615 return(TRUE);
2616 }
2617 }
2618
2619
2620 BOOL STATIC
2621 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2622 {
2623 ULONG i;
2624
2625 if (HandlerRoutine == NULL)
2626 {
2627 IgnoreCtrlEvents = FALSE;
2628 return(TRUE);
2629 }
2630 else
2631 {
2632 for (i = 0; i < NrCtrlHandlers; i++)
2633 {
2634 if ( ((void*)(CtrlHandlers[i])) == (void*)HandlerRoutine)
2635 {
2636 NrCtrlHandlers--;
2637 memmove(CtrlHandlers + i, CtrlHandlers + i + 1,
2638 (NrCtrlHandlers - i) * sizeof(PHANDLER_ROUTINE));
2639 CtrlHandlers =
2640 RtlReAllocateHeap(RtlGetProcessHeap(),
2641 HEAP_ZERO_MEMORY,
2642 (PVOID)CtrlHandlers,
2643 NrCtrlHandlers * sizeof(PHANDLER_ROUTINE));
2644 return(TRUE);
2645 }
2646 }
2647 }
2648 return(FALSE);
2649 }
2650
2651
2652 /*
2653 * @implemented
2654 */
2655 BOOL WINAPI
2656 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2657 BOOL Add)
2658 {
2659 BOOLEAN Ret;
2660
2661 RtlEnterCriticalSection(&DllLock);
2662 if (Add)
2663 {
2664 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2665 }
2666 else
2667 {
2668 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2669 }
2670 RtlLeaveCriticalSection(&DllLock);
2671 return(Ret);
2672 }
2673
2674
2675 /*--------------------------------------------------------------
2676 * GenerateConsoleCtrlEvent
2677 *
2678 * @unimplemented
2679 */
2680 BOOL WINAPI
2681 GenerateConsoleCtrlEvent(
2682 DWORD dwCtrlEvent,
2683 DWORD dwProcessGroupId
2684 )
2685 {
2686 /* TO DO */
2687 return FALSE;
2688 }
2689
2690
2691 /*--------------------------------------------------------------
2692 * GetConsoleTitleW
2693 *
2694 * @implemented
2695 */
2696 DWORD
2697 WINAPI
2698 GetConsoleTitleW(
2699 LPWSTR lpConsoleTitle,
2700 DWORD nSize
2701 )
2702 {
2703 CSRSS_API_REQUEST Request;
2704 PCSRSS_API_REPLY Reply;
2705 NTSTATUS Status;
2706 HANDLE hConsole;
2707
2708 hConsole = CreateFileW(L"CONIN$", GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2709 if (hConsole == INVALID_HANDLE_VALUE)
2710 {
2711 return 0;
2712 }
2713
2714 Reply = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2715 if(Reply == NULL)
2716 {
2717 CloseHandle(hConsole);
2718 SetLastError(ERROR_OUTOFMEMORY);
2719 return 0;
2720 }
2721
2722 Request.Type = CSRSS_GET_TITLE;
2723 Request.Data.GetTitleRequest.ConsoleHandle = hConsole;
2724
2725 Status = CsrClientCallServer(&Request, Reply, sizeof(CSRSS_API_REQUEST), sizeof(CSRSS_API_REPLY) + CSRSS_MAX_TITLE_LENGTH * sizeof(WCHAR));
2726 CloseHandle(hConsole);
2727 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = Reply->Status)))
2728 {
2729 SetLastErrorByStatus(Status);
2730 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2731 return 0;
2732 }
2733
2734 if(nSize * sizeof(WCHAR) < Reply->Data.GetTitleReply.Length)
2735 {
2736 wcsncpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title, nSize - 1);
2737 lpConsoleTitle[nSize--] = L'\0';
2738 }
2739 else
2740 {
2741 nSize = Reply->Data.GetTitleReply.Length / sizeof (WCHAR);
2742 wcscpy(lpConsoleTitle, Reply->Data.GetTitleReply.Title);
2743 lpConsoleTitle[nSize] = L'\0';
2744 }
2745
2746 RtlFreeHeap(GetProcessHeap(), 0, Reply);
2747 return nSize;
2748 }
2749
2750
2751 /*--------------------------------------------------------------
2752 * GetConsoleTitleA
2753 *
2754 * 19990306 EA
2755 *
2756 * @implemented
2757 */
2758 DWORD
2759 WINAPI
2760 GetConsoleTitleA(
2761 LPSTR lpConsoleTitle,
2762 DWORD nSize
2763 )
2764 {
2765 wchar_t WideTitle [CSRSS_MAX_TITLE_LENGTH];
2766 DWORD nWideTitle = sizeof WideTitle;
2767 DWORD nWritten;
2768
2769 if (!lpConsoleTitle || !nSize) return 0;
2770 nWideTitle = GetConsoleTitleW( (LPWSTR) WideTitle, nWideTitle );
2771 if (!nWideTitle) return 0;
2772
2773 if ( (nWritten = WideCharToMultiByte(
2774 CP_ACP, // ANSI code page
2775 0, // performance and mapping flags
2776 (LPWSTR) WideTitle, // address of wide-character string
2777 nWideTitle, // number of characters in string
2778 lpConsoleTitle, // address of buffer for new string
2779 nSize, // size of buffer
2780 NULL, // FAST
2781 NULL // FAST
2782 )))
2783 {
2784 lpConsoleTitle[nWritten] = '\0';
2785 return nWritten;
2786 }
2787
2788 return 0;
2789 }
2790
2791
2792 /*--------------------------------------------------------------
2793 * SetConsoleTitleW
2794 *
2795 * @implemented
2796 */
2797 BOOL
2798 WINAPI
2799 SetConsoleTitleW(
2800 LPCWSTR lpConsoleTitle
2801 )
2802 {
2803 PCSRSS_API_REQUEST Request;
2804 CSRSS_API_REPLY Reply;
2805 NTSTATUS Status;
2806 unsigned int c;
2807 HANDLE hConsole;
2808
2809 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2810 if (hConsole == INVALID_HANDLE_VALUE)
2811 {
2812 return FALSE;
2813 }
2814
2815 Request = RtlAllocateHeap(GetProcessHeap(),
2816 HEAP_ZERO_MEMORY,
2817 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2818 if (Request == NULL)
2819 {
2820 CloseHandle(hConsole);
2821 SetLastError(ERROR_OUTOFMEMORY);
2822 return(FALSE);
2823 }
2824
2825 Request->Type = CSRSS_SET_TITLE;
2826 Request->Data.SetTitleRequest.Console = hConsole;
2827
2828 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2829 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2830 // add null
2831 Request->Data.SetTitleRequest.Title[c] = 0;
2832 Request->Data.SetTitleRequest.Length = c;
2833 Status = CsrClientCallServer(Request,
2834 &Reply,
2835 sizeof(CSRSS_API_REQUEST) +
2836 c * sizeof(WCHAR),
2837 sizeof(CSRSS_API_REPLY));
2838 CloseHandle(hConsole);
2839 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2840 {
2841 RtlFreeHeap( GetProcessHeap(), 0, Request );
2842 SetLastErrorByStatus (Status);
2843 return(FALSE);
2844 }
2845 RtlFreeHeap( GetProcessHeap(), 0, Request );
2846 return TRUE;
2847 }
2848
2849
2850 /*--------------------------------------------------------------
2851 * SetConsoleTitleA
2852 *
2853 * 19990204 EA Added
2854 *
2855 * @implemented
2856 */
2857 BOOL
2858 WINAPI
2859 SetConsoleTitleA(
2860 LPCSTR lpConsoleTitle
2861 )
2862 {
2863 PCSRSS_API_REQUEST Request;
2864 CSRSS_API_REPLY Reply;
2865 NTSTATUS Status;
2866 unsigned int c;
2867 HANDLE hConsole;
2868
2869 hConsole = CreateFileW(L"CONIN$", GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
2870 if (hConsole == INVALID_HANDLE_VALUE)
2871 {
2872 return FALSE;
2873 }
2874
2875 Request = RtlAllocateHeap(GetProcessHeap(),
2876 HEAP_ZERO_MEMORY,
2877 sizeof(CSRSS_API_REQUEST) + CSRSS_MAX_SET_TITLE_REQUEST);
2878 if (Request == NULL)
2879 {
2880 CloseHandle(hConsole);
2881 SetLastError(ERROR_OUTOFMEMORY);
2882 return(FALSE);
2883 }
2884
2885 Request->Type = CSRSS_SET_TITLE;
2886 Request->Data.SetTitleRequest.Console = hConsole;
2887
2888 for( c = 0; lpConsoleTitle[c] && c < CSRSS_MAX_TITLE_LENGTH; c++ )
2889 Request->Data.SetTitleRequest.Title[c] = lpConsoleTitle[c];
2890 // add null
2891 Request->Data.SetTitleRequest.Title[c] = 0;
2892 Request->Data.SetTitleRequest.Length = c;
2893 Status = CsrClientCallServer(Request,
2894 &Reply,
2895 sizeof(CSRSS_API_REQUEST) +
2896 c * sizeof(WCHAR),
2897 sizeof(CSRSS_API_REPLY));
2898 CloseHandle(hConsole);
2899 if (!NT_SUCCESS(Status) || !NT_SUCCESS( Status = Reply.Status ) )
2900 {
2901 RtlFreeHeap( GetProcessHeap(), 0, Request );
2902 SetLastErrorByStatus (Status);
2903 return(FALSE);
2904 }
2905 RtlFreeHeap( GetProcessHeap(), 0, Request );
2906 return TRUE;
2907 }
2908
2909
2910 /*--------------------------------------------------------------
2911 * ReadConsoleW
2912 *
2913 * @unimplemented
2914 */
2915 BOOL
2916 WINAPI
2917 ReadConsoleW(
2918 HANDLE hConsoleInput,
2919 LPVOID lpBuffer,
2920 DWORD nNumberOfCharsToRead,
2921 LPDWORD lpNumberOfCharsRead,
2922 LPVOID lpReserved
2923 )
2924 {
2925 /* --- TO DO --- */
2926 return FALSE;
2927 }
2928
2929
2930 /*--------------------------------------------------------------
2931 * WriteConsoleW
2932 *
2933 * @unimplemented
2934 */
2935 BOOL
2936 WINAPI
2937 WriteConsoleW(
2938 HANDLE hConsoleOutput,
2939 CONST VOID *lpBuffer,
2940 DWORD nNumberOfCharsToWrite,
2941 LPDWORD lpNumberOfCharsWritten,
2942 LPVOID lpReserved
2943 )
2944 {
2945 #if 0
2946 PCSRSS_API_REQUEST Request;
2947 CSRSS_API_REPLY Reply;
2948 NTSTATUS Status;
2949
2950 Request = RtlAllocateHeap(GetProcessHeap(),
2951 HEAP_ZERO_MEMORY,
2952 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite * sizeof(WCHAR));
2953 if (Request == NULL)
2954 {
2955 SetLastError(ERROR_OUTOFMEMORY);
2956 return(FALSE);
2957 }
2958
2959 Request->Type = CSRSS_WRITE_CONSOLE;
2960 Request->Data.WriteConsoleRequest.ConsoleHandle = hConsoleOutput;
2961 Request->Data.WriteConsoleRequest.NrCharactersToWrite =
2962 nNumberOfCharsToWrite;
2963 // DbgPrint("nNumberOfCharsToWrite %d\n", nNumberOfCharsToWrite);
2964 // DbgPrint("Buffer %s\n", Request->Data.WriteConsoleRequest.Buffer);
2965 memcpy(Request->Data.WriteConsoleRequest.Buffer,
2966 lpBuffer,
2967 nNumberOfCharsToWrite * sizeof(WCHAR));
2968
2969 Status = CsrClientCallServer(Request,
2970 &Reply,
2971 sizeof(CSRSS_API_REQUEST) + nNumberOfCharsToWrite,
2972 sizeof(CSRSS_API_REPLY));
2973
2974 RtlFreeHeap(GetProcessHeap(),
2975 0,
2976 Request);
2977
2978 if (!NT_SUCCESS(Status))
2979 {
2980 return(FALSE);
2981 }
2982
2983 if (lpNumberOfCharsWritten != NULL)
2984 {
2985 *lpNumberOfCharsWritten =
2986 Reply.Data.WriteConsoleReply.NrCharactersWritten;
2987 }
2988
2989 return(TRUE);
2990 #endif
2991 return(FALSE);
2992 }
2993
2994
2995 /*--------------------------------------------------------------
2996 * CreateConsoleScreenBuffer
2997 *
2998 * @implemented
2999 */
3000 HANDLE
3001 WINAPI
3002 CreateConsoleScreenBuffer(
3003 DWORD dwDesiredAccess,
3004 DWORD dwShareMode,
3005 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
3006 DWORD dwFlags,
3007 LPVOID lpScreenBufferData
3008 )
3009 {
3010 // FIXME: don't ignore access, share mode, and security
3011 CSRSS_API_REQUEST Request;
3012 CSRSS_API_REPLY Reply;
3013 NTSTATUS Status;
3014
3015 Request.Type = CSRSS_CREATE_SCREEN_BUFFER;
3016 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3017 if( !NT_SUCCESS( Status ) || !NT_SUCCESS( Status = Reply.Status ) )
3018 {
3019 SetLastErrorByStatus ( Status );
3020 return FALSE;
3021 }
3022 return Reply.Data.CreateScreenBufferReply.OutputHandle;
3023 }
3024
3025
3026 /*--------------------------------------------------------------
3027 * GetConsoleCP
3028 *
3029 * @unimplemented
3030 */
3031 UINT
3032 WINAPI
3033 GetConsoleCP( VOID )
3034 {
3035 /* --- TO DO --- */
3036 return CP_OEMCP; /* FIXME */
3037 }
3038
3039
3040 /*--------------------------------------------------------------
3041 * SetConsoleCP
3042 *
3043 * @unimplemented
3044 */
3045 BOOL
3046 WINAPI
3047 SetConsoleCP(
3048 UINT wCodePageID
3049 )
3050 {
3051 /* --- TO DO --- */
3052 return FALSE;
3053 }
3054
3055
3056 /*--------------------------------------------------------------
3057 * GetConsoleOutputCP
3058 *
3059 * @unimplemented
3060 */
3061 UINT
3062 WINAPI
3063 GetConsoleOutputCP( VOID )
3064 {
3065 /* --- TO DO --- */
3066 return 0; /* FIXME */
3067 }
3068
3069
3070 /*--------------------------------------------------------------
3071 * SetConsoleOutputCP
3072 *
3073 * @unimplemented
3074 */
3075 BOOL
3076 WINAPI
3077 SetConsoleOutputCP(
3078 UINT wCodePageID
3079 )
3080 {
3081 /* --- TO DO --- */
3082 return FALSE;
3083 }
3084
3085
3086 /*--------------------------------------------------------------
3087 * GetConsoleProcessList
3088 *
3089 * @unimplemented
3090 */
3091 DWORD STDCALL
3092 GetConsoleProcessList(LPDWORD lpdwProcessList,
3093 DWORD dwProcessCount)
3094 {
3095 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3096 return 0;
3097 }
3098
3099
3100
3101 /*--------------------------------------------------------------
3102 * GetConsoleSelectionInfo
3103 *
3104 * @unimplemented
3105 */
3106 BOOL STDCALL
3107 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
3108 {
3109 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3110 return FALSE;
3111 }
3112
3113
3114
3115 /*--------------------------------------------------------------
3116 * AttachConsole
3117 *
3118 * @unimplemented
3119 */
3120 BOOL STDCALL
3121 AttachConsole(DWORD dwProcessId)
3122 {
3123 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3124 return FALSE;
3125 }
3126
3127 /*--------------------------------------------------------------
3128 * GetConsoleWindow
3129 *
3130 * @implemented
3131 */
3132 HWND STDCALL
3133 GetConsoleWindow (VOID)
3134 {
3135 CSRSS_API_REQUEST Request;
3136 CSRSS_API_REPLY Reply;
3137 NTSTATUS Status;
3138
3139 Request.Data.ConsoleWindowRequest.ConsoleHandle =
3140 OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
3141 if (INVALID_HANDLE_VALUE == Request.Data.ConsoleWindowRequest.ConsoleHandle)
3142 {
3143 return (HWND) NULL;
3144 }
3145 Request.Type = CSRSS_GET_CONSOLE_WINDOW;
3146 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3147 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = Reply.Status))
3148 {
3149 SetLastErrorByStatus (Status);
3150 return (HWND) NULL;
3151 }
3152 return Reply.Data.ConsoleWindowReply.WindowHandle;
3153 }
3154
3155
3156 /*--------------------------------------------------------------
3157 * GetConsoleWindow
3158 * @implemented
3159 */
3160 BOOL STDCALL SetConsoleIcon(HICON hicon)
3161 {
3162 CSRSS_API_REQUEST Request;
3163 CSRSS_API_REPLY Reply;
3164 NTSTATUS Status;
3165
3166 Request.Data.ConsoleSetWindowIconRequest.ConsoleHandle =
3167 OpenConsoleW (L"CONOUT$", (GENERIC_READ|GENERIC_WRITE), FALSE, OPEN_EXISTING);
3168 if (INVALID_HANDLE_VALUE == Request.Data.ConsoleSetWindowIconRequest.ConsoleHandle)
3169 {
3170 return FALSE;
3171 }
3172 Request.Type = CSRSS_SET_CONSOLE_ICON;
3173 Request.Data.ConsoleSetWindowIconRequest.WindowIcon = hicon;
3174 Status = CsrClientCallServer( &Request, &Reply, sizeof( CSRSS_API_REQUEST ), sizeof( CSRSS_API_REPLY ) );
3175 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Reply.Status))
3176 {
3177 SetLastErrorByStatus (Status);
3178 return FALSE;
3179 }
3180 return NT_SUCCESS(Status);
3181 }
3182
3183 /* EOF */