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