[KERNEL32]
[reactos.git] / dll / win32 / kernel32 / client / console / console.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/console/console.c
5 * PURPOSE: Win32 server console functions
6 * PROGRAMMER: James Tabor
7 * <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net>
8 * UPDATE HISTORY:
9 * 199901?? ?? Created
10 * 19990204 EA SetConsoleTitleA
11 * 19990306 EA Stubs
12 */
13
14 /* INCLUDES *******************************************************************/
15
16 #include <k32.h>
17
18 #define NDEBUG
19 #include <debug.h>
20
21 extern RTL_CRITICAL_SECTION ConsoleLock;
22 extern BOOL ConsoleInitialized;
23 extern BOOL WINAPI IsDebuggerPresent(VOID);
24
25 /* GLOBALS ********************************************************************/
26
27 PHANDLER_ROUTINE InitialHandler[1];
28 PHANDLER_ROUTINE* CtrlHandlers;
29 ULONG NrCtrlHandlers;
30 ULONG NrAllocatedHandlers;
31
32 #define INPUTEXENAME_BUFLEN 256
33 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
34
35 /* Default Console Control Handler ********************************************/
36
37 BOOL
38 WINAPI
39 DefaultConsoleCtrlHandler(DWORD Event)
40 {
41 DPRINT("Default handler called: %lx\n", Event);
42 switch(Event)
43 {
44 case CTRL_C_EVENT:
45 DPRINT("Ctrl-C Event\n");
46 break;
47
48 case CTRL_BREAK_EVENT:
49 DPRINT("Ctrl-Break Event\n");
50 break;
51
52 case CTRL_SHUTDOWN_EVENT:
53 DPRINT("Ctrl Shutdown Event\n");
54 break;
55
56 case CTRL_CLOSE_EVENT:
57 DPRINT("Ctrl Close Event\n");
58 break;
59
60 case CTRL_LOGOFF_EVENT:
61 DPRINT("Ctrl Logoff Event\n");
62 break;
63 }
64
65 ExitProcess(CONTROL_C_EXIT);
66 return TRUE;
67 }
68
69 DWORD
70 WINAPI
71 ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
72 {
73 DWORD nExitCode = 0;
74 DWORD CodeAndFlag = PtrToUlong(lpThreadParameter);
75 DWORD nCode = CodeAndFlag & MAXLONG;
76 UINT i;
77 EXCEPTION_RECORD erException;
78
79 DPRINT("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
80 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
81
82 switch(nCode)
83 {
84 case CTRL_C_EVENT:
85 case CTRL_BREAK_EVENT:
86 {
87 if (IsDebuggerPresent())
88 {
89 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
90 DBG_CONTROL_C : DBG_CONTROL_BREAK);
91 erException.ExceptionFlags = 0;
92 erException.ExceptionRecord = NULL;
93 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
94 erException.NumberParameters = 0;
95
96 _SEH2_TRY
97 {
98 RtlRaiseException(&erException);
99 }
100 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
101 {
102 RtlEnterCriticalSection(&ConsoleLock);
103
104 if ((nCode != CTRL_C_EVENT) ||
105 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
106 {
107 for (i = NrCtrlHandlers; i > 0; i--)
108 {
109 if (CtrlHandlers[i - 1](nCode)) break;
110 }
111 }
112
113 RtlLeaveCriticalSection(&ConsoleLock);
114 }
115 _SEH2_END;
116
117 ExitThread(0);
118 }
119 break;
120 }
121
122 case CTRL_CLOSE_EVENT:
123 case CTRL_LOGOFF_EVENT:
124 case CTRL_SHUTDOWN_EVENT:
125 break;
126
127 case 3:
128 ExitThread(0);
129 break;
130
131 case 4:
132 ExitProcess(CONTROL_C_EXIT);
133 break;
134
135 default:
136 ASSERT(FALSE);
137 break;
138 }
139
140 ASSERT(ConsoleInitialized);
141
142 RtlEnterCriticalSection(&ConsoleLock);
143 nExitCode = 0;
144 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
145 {
146 for (i = NrCtrlHandlers; i > 0; i--)
147 {
148 if ((i == 1) &&
149 (CodeAndFlag & MINLONG) &&
150 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
151 {
152 DPRINT("Skipping system/service apps\n");
153 break;
154 }
155
156 if (CtrlHandlers[i - 1](nCode))
157 {
158 switch(nCode)
159 {
160 case CTRL_CLOSE_EVENT:
161 case CTRL_LOGOFF_EVENT:
162 case CTRL_SHUTDOWN_EVENT:
163 case 3:
164 nExitCode = CodeAndFlag;
165 break;
166 }
167 break;
168 }
169 }
170 }
171
172 RtlLeaveCriticalSection(&ConsoleLock);
173 ExitThread(nExitCode);
174 return STATUS_SUCCESS;
175 }
176
177
178 /* FUNCTIONS ******************************************************************/
179
180 /*
181 * @unimplemented (Undocumented)
182 */
183 BOOL
184 WINAPI
185 ConsoleMenuControl(HANDLE hConsole,
186 DWORD Unknown1,
187 DWORD Unknown2)
188 {
189 DPRINT1("ConsoleMenuControl(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsole, Unknown1, Unknown2);
190 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
191 return FALSE;
192 }
193
194
195 /*
196 * @implemented
197 */
198 HANDLE
199 WINAPI
200 DuplicateConsoleHandle(HANDLE hConsole,
201 DWORD dwDesiredAccess,
202 BOOL bInheritHandle,
203 DWORD dwOptions)
204 {
205 NTSTATUS Status;
206 CONSOLE_API_MESSAGE ApiMessage;
207 PCSRSS_DUPLICATE_HANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest;
208
209 if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) ||
210 (!(dwOptions & DUPLICATE_SAME_ACCESS) &&
211 (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) )
212 {
213 SetLastError (ERROR_INVALID_PARAMETER);
214 return INVALID_HANDLE_VALUE;
215 }
216
217 DuplicateHandleRequest->Handle = hConsole;
218 DuplicateHandleRequest->Access = dwDesiredAccess;
219 DuplicateHandleRequest->Inheritable = bInheritHandle;
220 DuplicateHandleRequest->Options = dwOptions;
221
222 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
223 NULL,
224 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle),
225 sizeof(CSRSS_DUPLICATE_HANDLE));
226 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
227 {
228 BaseSetLastNTError(Status);
229 return INVALID_HANDLE_VALUE;
230 }
231
232 return DuplicateHandleRequest->Handle;
233 }
234
235
236 /*
237 * @unimplemented
238 */
239 INT
240 WINAPI
241 GetConsoleDisplayMode(LPDWORD lpdwMode)
242 /*
243 * FUNCTION: Get the console display mode
244 * ARGUMENTS:
245 * lpdwMode - Address of variable that receives the current value
246 * of display mode
247 * STATUS: Undocumented
248 */
249 {
250 DPRINT1("GetConsoleDisplayMode(0x%x) UNIMPLEMENTED!\n", lpdwMode);
251 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
252 return 0;
253 }
254
255
256 /*
257 * @unimplemented (Undocumented)
258 */
259 DWORD
260 WINAPI
261 GetConsoleFontInfo(DWORD Unknown0,
262 DWORD Unknown1,
263 DWORD Unknown2,
264 DWORD Unknown3)
265 {
266 DPRINT1("GetConsoleFontInfo(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 COORD
276 WINAPI
277 GetConsoleFontSize(HANDLE hConsoleOutput,
278 DWORD nFont)
279 {
280 COORD Empty = {0, 0};
281 DPRINT1("GetConsoleFontSize(0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
282 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
283 return Empty;
284 }
285
286
287 /*
288 * @implemented (Undocumented)
289 */
290 DWORD
291 WINAPI
292 GetConsoleHardwareState(HANDLE hConsole,
293 DWORD Flags,
294 PDWORD State)
295 {
296 NTSTATUS Status;
297 CONSOLE_API_MESSAGE ApiMessage;
298 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &ApiMessage.Data.ConsoleHardwareStateRequest;
299
300 ConsoleHardwareStateRequest->ConsoleHandle = hConsole;
301
302 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
303 NULL,
304 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState),
305 sizeof(CSRSS_CONSOLE_HW_STATE));
306 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
307 {
308 BaseSetLastNTError(Status);
309 return FALSE;
310 }
311
312 *State = ConsoleHardwareStateRequest->State;
313 return TRUE;
314 }
315
316
317 /*
318 * @implemented (Undocumented)
319 */
320 HANDLE
321 WINAPI
322 GetConsoleInputWaitHandle(VOID)
323 {
324 /// HACK !!!!!!!!!!!!!
325 ASSERT(FALSE);
326 return NULL;
327
328 #if 0
329 NTSTATUS Status;
330 CONSOLE_API_MESSAGE ApiMessage;
331
332 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
333 NULL,
334 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, GET_INPUT_WAIT_HANDLE),
335 sizeof(CSRSS_GET_INPUT_WAIT_HANDLE));
336 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
337 {
338 BaseSetLastNTError(Status);
339 return 0;
340 }
341
342 return ApiMessage.Data.GetConsoleInputWaitHandle.InputWaitHandle;
343 #endif
344 }
345
346
347 /*
348 * @unimplemented
349 */
350 INT
351 WINAPI
352 GetCurrentConsoleFont(HANDLE hConsoleOutput,
353 BOOL bMaximumWindow,
354 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
355 {
356 DPRINT1("GetCurrentConsoleFont(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
357 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
358 return 0;
359 }
360
361
362 /*
363 * @unimplemented (Undocumented)
364 */
365 ULONG
366 WINAPI
367 GetNumberOfConsoleFonts(VOID)
368 {
369 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
370 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
371 return 1;
372 }
373
374
375 /*
376 * @unimplemented (Undocumented)
377 */
378 DWORD
379 WINAPI
380 InvalidateConsoleDIBits(DWORD Unknown0,
381 DWORD Unknown1)
382 {
383 DPRINT1("InvalidateConsoleDIBits(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
384 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
385 return 0;
386 }
387
388
389 /*
390 * @unimplemented (Undocumented)
391 */
392 HANDLE
393 WINAPI
394 OpenConsoleW(LPCWSTR wsName,
395 DWORD dwDesiredAccess,
396 BOOL bInheritHandle,
397 DWORD dwShareMode)
398 {
399 NTSTATUS Status = STATUS_SUCCESS;
400 CONSOLE_API_MESSAGE ApiMessage;
401 PCSRSS_OPEN_CONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest;
402 HANDLE_TYPE HandleType;
403
404 if (wsName && 0 == _wcsicmp(wsName, L"CONIN$"))
405 {
406 HandleType = HANDLE_INPUT;
407 }
408 else if (wsName && 0 == _wcsicmp(wsName, L"CONOUT$"))
409 {
410 HandleType = HANDLE_OUTPUT;
411 }
412 else
413 {
414 SetLastError(ERROR_INVALID_PARAMETER);
415 return INVALID_HANDLE_VALUE;
416 }
417
418 if (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))
419 {
420 SetLastError(ERROR_INVALID_PARAMETER);
421 return INVALID_HANDLE_VALUE;
422 }
423
424 if (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE))
425 {
426 SetLastError(ERROR_INVALID_PARAMETER);
427 return INVALID_HANDLE_VALUE;
428 }
429
430 OpenConsoleRequest->HandleType = HandleType;
431 OpenConsoleRequest->Access = dwDesiredAccess;
432 OpenConsoleRequest->Inheritable = bInheritHandle;
433 OpenConsoleRequest->ShareMode = dwShareMode;
434
435 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
436 NULL,
437 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole),
438 sizeof(CSRSS_OPEN_CONSOLE));
439 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
440 {
441 BaseSetLastNTError(Status);
442 return INVALID_HANDLE_VALUE;
443 }
444
445 return OpenConsoleRequest->Handle;
446 }
447
448
449 /*
450 * @unimplemented (Undocumented)
451 */
452 BOOL
453 WINAPI
454 SetConsoleCursor(DWORD Unknown0,
455 DWORD Unknown1)
456 {
457 DPRINT1("SetConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
458 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
459 return FALSE;
460 }
461
462
463 /*
464 * @unimplemented
465 */
466 BOOL
467 WINAPI
468 SetConsoleDisplayMode(HANDLE hOut,
469 DWORD dwNewMode,
470 PCOORD lpdwOldMode)
471 /*
472 * FUNCTION: Set the console display mode.
473 * ARGUMENTS:
474 * hOut - Standard output handle.
475 * dwNewMode - New mode.
476 * lpdwOldMode - Address of a variable that receives the old mode.
477 */
478 {
479 DPRINT1("SetConsoleDisplayMode(0x%x, 0x%x, 0x%p) UNIMPLEMENTED!\n", hOut, dwNewMode, lpdwOldMode);
480 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
481 return FALSE;
482 }
483
484
485 /*
486 * @unimplemented (Undocumented)
487 */
488 BOOL
489 WINAPI
490 SetConsoleFont(DWORD Unknown0,
491 DWORD Unknown1)
492 {
493 DPRINT1("SetConsoleFont(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
494 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
495 return FALSE;
496 }
497
498
499 /*
500 * @implemented (Undocumented)
501 */
502 BOOL
503 WINAPI
504 SetConsoleHardwareState(HANDLE hConsole,
505 DWORD Flags,
506 DWORD State)
507 {
508 NTSTATUS Status;
509 CONSOLE_API_MESSAGE ApiMessage;
510 PCSRSS_CONSOLE_HW_STATE ConsoleHardwareStateRequest = &ApiMessage.Data.ConsoleHardwareStateRequest;
511
512 ConsoleHardwareStateRequest->ConsoleHandle = hConsole;
513 ConsoleHardwareStateRequest->State = State;
514
515 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
516 NULL,
517 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState),
518 sizeof(CSRSS_CONSOLE_HW_STATE));
519 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
520 {
521 BaseSetLastNTError(Status);
522 return FALSE;
523 }
524
525 return TRUE;
526 }
527
528
529 /*
530 * @unimplemented (Undocumented)
531 */
532 BOOL
533 WINAPI
534 SetConsoleKeyShortcuts(DWORD Unknown0,
535 DWORD Unknown1,
536 DWORD Unknown2,
537 DWORD Unknown3)
538 {
539 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
540 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
541 return FALSE;
542 }
543
544
545 /*
546 * @unimplemented (Undocumented)
547 */
548 BOOL
549 WINAPI
550 SetConsoleMaximumWindowSize(DWORD Unknown0,
551 DWORD Unknown1)
552 {
553 DPRINT1("SetConsoleMaximumWindowSize(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
554 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
555 return FALSE;
556 }
557
558
559 /*
560 * @unimplemented (Undocumented)
561 */
562 BOOL
563 WINAPI
564 SetConsoleMenuClose(DWORD Unknown0)
565 {
566 DPRINT1("SetConsoleMenuClose(0x%x) UNIMPLEMENTED!\n", Unknown0);
567 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
568 return FALSE;
569 }
570
571
572 /*
573 * @unimplemented (Undocumented)
574 */
575 BOOL
576 WINAPI
577 SetConsolePalette(DWORD Unknown0,
578 DWORD Unknown1,
579 DWORD Unknown2)
580 {
581 DPRINT1("SetConsolePalette(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2);
582 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
583 return FALSE;
584 }
585
586 /*
587 * @unimplemented (Undocumented)
588 */
589 DWORD
590 WINAPI
591 ShowConsoleCursor(DWORD Unknown0,
592 DWORD Unknown1)
593 {
594 DPRINT1("ShowConsoleCursor(0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1);
595 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
596 return 0;
597 }
598
599
600 /*
601 * FUNCTION: Checks whether the given handle is a valid console handle.
602 *
603 * ARGUMENTS:
604 * Handle - Handle to be checked
605 *
606 * RETURNS:
607 * TRUE: Handle is a valid console handle
608 * FALSE: Handle is not a valid console handle.
609 *
610 * STATUS: Officially undocumented
611 *
612 * @implemented
613 */
614 BOOL
615 WINAPI
616 VerifyConsoleIoHandle(HANDLE Handle)
617 {
618 NTSTATUS Status;
619 CONSOLE_API_MESSAGE ApiMessage;
620
621 ApiMessage.Data.VerifyHandleRequest.Handle = Handle;
622
623 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
624 NULL,
625 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle),
626 sizeof(CSRSS_VERIFY_HANDLE));
627 if (!NT_SUCCESS(Status))
628 {
629 BaseSetLastNTError(Status);
630 return FALSE;
631 }
632
633 return (BOOL)NT_SUCCESS(ApiMessage.Status);
634 }
635
636
637 /*
638 * @unimplemented
639 */
640 DWORD
641 WINAPI
642 WriteConsoleInputVDMA(DWORD Unknown0,
643 DWORD Unknown1,
644 DWORD Unknown2,
645 DWORD Unknown3)
646 {
647 DPRINT1("WriteConsoleInputVDMA(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
648 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
649 return 0;
650 }
651
652
653 /*
654 * @unimplemented
655 */
656 DWORD
657 WINAPI
658 WriteConsoleInputVDMW(DWORD Unknown0,
659 DWORD Unknown1,
660 DWORD Unknown2,
661 DWORD Unknown3)
662 {
663 DPRINT1("WriteConsoleInputVDMW(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
664 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
665 return 0;
666 }
667
668
669 /*
670 * @implemented (Undocumented)
671 */
672 BOOL
673 WINAPI
674 CloseConsoleHandle(HANDLE Handle)
675 {
676 NTSTATUS Status;
677 CONSOLE_API_MESSAGE ApiMessage;
678
679 ApiMessage.Data.CloseHandleRequest.Handle = Handle;
680
681 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
682 NULL,
683 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle),
684 sizeof(CSRSS_CLOSE_HANDLE));
685 if (!NT_SUCCESS(Status))
686 {
687 BaseSetLastNTError(Status);
688 return FALSE;
689 }
690
691 return TRUE;
692 }
693
694
695 /*
696 * @implemented
697 */
698 HANDLE
699 WINAPI
700 GetStdHandle(DWORD nStdHandle)
701 /*
702 * FUNCTION: Get a handle for the standard input, standard output
703 * and a standard error device.
704 *
705 * ARGUMENTS:
706 * nStdHandle - Specifies the device for which to return the handle.
707 *
708 * RETURNS: If the function succeeds, the return value is the handle
709 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
710 */
711 {
712 PRTL_USER_PROCESS_PARAMETERS Ppb;
713
714 Ppb = NtCurrentPeb()->ProcessParameters;
715 switch (nStdHandle)
716 {
717 case STD_INPUT_HANDLE:
718 return Ppb->StandardInput;
719
720 case STD_OUTPUT_HANDLE:
721 return Ppb->StandardOutput;
722
723 case STD_ERROR_HANDLE:
724 return Ppb->StandardError;
725 }
726
727 SetLastError(ERROR_INVALID_PARAMETER);
728 return INVALID_HANDLE_VALUE;
729 }
730
731
732 /*
733 * @implemented
734 */
735 BOOL
736 WINAPI
737 SetStdHandle(DWORD nStdHandle,
738 HANDLE hHandle)
739 /*
740 * FUNCTION: Set the handle for the standard input, standard output or
741 * the standard error device.
742 *
743 * ARGUMENTS:
744 * nStdHandle - Specifies the handle to be set.
745 * hHandle - The handle to set.
746 *
747 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
748 */
749 {
750 PRTL_USER_PROCESS_PARAMETERS Ppb;
751
752 /* no need to check if hHandle == INVALID_HANDLE_VALUE */
753
754 Ppb = NtCurrentPeb()->ProcessParameters;
755
756 switch (nStdHandle)
757 {
758 case STD_INPUT_HANDLE:
759 Ppb->StandardInput = hHandle;
760 return TRUE;
761
762 case STD_OUTPUT_HANDLE:
763 Ppb->StandardOutput = hHandle;
764 return TRUE;
765
766 case STD_ERROR_HANDLE:
767 Ppb->StandardError = hHandle;
768 return TRUE;
769 }
770
771 /* windows for whatever reason sets the last error to ERROR_INVALID_HANDLE here */
772 SetLastError(ERROR_INVALID_HANDLE);
773 return FALSE;
774 }
775
776
777 /*--------------------------------------------------------------
778 * AllocConsole
779 *
780 * @implemented
781 */
782 BOOL
783 WINAPI
784 AllocConsole(VOID)
785 {
786 NTSTATUS Status;
787 CONSOLE_API_MESSAGE ApiMessage;
788 PCSRSS_ALLOC_CONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
789 HANDLE hStdError;
790 STARTUPINFO si;
791
792 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
793 {
794 DPRINT("AllocConsole: Allocate duplicate console to the same Process\n");
795 BaseSetLastNTError (STATUS_OBJECT_NAME_EXISTS);
796 return FALSE;
797 }
798
799 GetStartupInfo(&si);
800
801 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
802 AllocConsoleRequest->ConsoleNeeded = TRUE;
803 AllocConsoleRequest->ShowCmd = si.wShowWindow;
804
805 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
806 NULL,
807 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
808 sizeof(CSRSS_ALLOC_CONSOLE));
809 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
810 {
811 BaseSetLastNTError(Status);
812 return FALSE;
813 }
814
815 NtCurrentPeb()->ProcessParameters->ConsoleHandle = AllocConsoleRequest->Console;
816
817 SetStdHandle(STD_INPUT_HANDLE, AllocConsoleRequest->InputHandle);
818 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
819
820 hStdError = DuplicateConsoleHandle(AllocConsoleRequest->OutputHandle,
821 0,
822 TRUE,
823 DUPLICATE_SAME_ACCESS);
824
825 SetStdHandle(STD_ERROR_HANDLE, hStdError);
826 return TRUE;
827 }
828
829
830 /*--------------------------------------------------------------
831 * FreeConsole
832 *
833 * @implemented
834 */
835 BOOL
836 WINAPI
837 FreeConsole(VOID)
838 {
839 // AG: I'm not sure if this is correct (what happens to std handles?)
840 // but I just tried to reverse what AllocConsole() does...
841
842 NTSTATUS Status;
843 CONSOLE_API_MESSAGE ApiMessage;
844
845 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
846 NULL,
847 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
848 sizeof(CSRSS_FREE_CONSOLE));
849 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
850 {
851 BaseSetLastNTError(Status);
852 return FALSE;
853 }
854
855 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
856 return TRUE;
857 }
858
859
860 /*--------------------------------------------------------------
861 * GetConsoleScreenBufferInfo
862 *
863 * @implemented
864 */
865 BOOL
866 WINAPI
867 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
868 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
869 {
870 NTSTATUS Status;
871 CONSOLE_API_MESSAGE ApiMessage;
872
873 if (lpConsoleScreenBufferInfo == NULL)
874 {
875 SetLastError(ERROR_INVALID_PARAMETER);
876 return FALSE;
877 }
878
879 ApiMessage.Data.ScreenBufferInfoRequest.ConsoleHandle = hConsoleOutput;
880
881 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
882 NULL,
883 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
884 sizeof(CSRSS_SCREEN_BUFFER_INFO));
885 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
886 {
887 BaseSetLastNTError(Status);
888 return FALSE;
889 }
890
891 *lpConsoleScreenBufferInfo = ApiMessage.Data.ScreenBufferInfoRequest.Info;
892
893 return TRUE;
894 }
895
896
897 /*--------------------------------------------------------------
898 * SetConsoleCursorPosition
899 *
900 * @implemented
901 */
902 BOOL
903 WINAPI
904 SetConsoleCursorPosition(HANDLE hConsoleOutput,
905 COORD dwCursorPosition)
906 {
907 NTSTATUS Status;
908 CONSOLE_API_MESSAGE ApiMessage;
909
910 ApiMessage.Data.SetCursorPositionRequest.ConsoleHandle = hConsoleOutput;
911 ApiMessage.Data.SetCursorPositionRequest.Position = dwCursorPosition;
912
913 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
914 NULL,
915 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
916 sizeof(CSRSS_SET_CURSOR_POSITION));
917 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
918 {
919 BaseSetLastNTError(Status);
920 return FALSE;
921 }
922
923 return TRUE;
924 }
925
926
927 /*--------------------------------------------------------------
928 * GetConsoleMode
929 *
930 * @implemented
931 */
932 BOOL
933 WINAPI
934 GetConsoleMode(HANDLE hConsoleHandle,
935 LPDWORD lpMode)
936 {
937 NTSTATUS Status;
938 CONSOLE_API_MESSAGE ApiMessage;
939 PCSRSS_CONSOLE_MODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
940
941 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
942
943 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
944 NULL,
945 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
946 sizeof(CSRSS_CONSOLE_MODE));
947 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
948 {
949 BaseSetLastNTError(Status);
950 return FALSE;
951 }
952
953 *lpMode = ConsoleModeRequest->ConsoleMode;
954
955 return TRUE;
956 }
957
958
959 /*--------------------------------------------------------------
960 * GetNumberOfConsoleInputEvents
961 *
962 * @implemented
963 */
964 BOOL
965 WINAPI
966 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
967 LPDWORD lpNumberOfEvents)
968 {
969 NTSTATUS Status;
970 CONSOLE_API_MESSAGE ApiMessage;
971
972 if (lpNumberOfEvents == NULL)
973 {
974 SetLastError(ERROR_INVALID_PARAMETER);
975 return FALSE;
976 }
977
978 ApiMessage.Data.GetNumInputEventsRequest.ConsoleHandle = hConsoleInput;
979
980 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
981 NULL,
982 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
983 sizeof(CSRSS_GET_NUM_INPUT_EVENTS));
984 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
985 {
986 BaseSetLastNTError(Status);
987 return FALSE;
988 }
989
990 *lpNumberOfEvents = ApiMessage.Data.GetNumInputEventsRequest.NumInputEvents;
991
992 return TRUE;
993 }
994
995
996 /*--------------------------------------------------------------
997 * GetLargestConsoleWindowSize
998 *
999 * @unimplemented
1000 */
1001 COORD
1002 WINAPI
1003 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1004 {
1005 COORD Coord = {80,25};
1006 DPRINT1("GetLargestConsoleWindowSize(0x%x) UNIMPLEMENTED!\n", hConsoleOutput);
1007 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1008 return Coord;
1009 }
1010
1011
1012 /*--------------------------------------------------------------
1013 * GetConsoleCursorInfo
1014 *
1015 * @implemented
1016 */
1017 BOOL
1018 WINAPI
1019 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1020 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1021 {
1022 NTSTATUS Status;
1023 CONSOLE_API_MESSAGE ApiMessage;
1024
1025 if (!lpConsoleCursorInfo)
1026 {
1027 if (!hConsoleOutput)
1028 SetLastError(ERROR_INVALID_HANDLE);
1029 else
1030 SetLastError(ERROR_INVALID_ACCESS);
1031
1032 return FALSE;
1033 }
1034
1035 ApiMessage.Data.CursorInfoRequest.ConsoleHandle = hConsoleOutput;
1036
1037 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1038 NULL,
1039 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1040 sizeof(CSRSS_CURSOR_INFO));
1041 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1042 {
1043 BaseSetLastNTError(Status);
1044 return FALSE;
1045 }
1046
1047 *lpConsoleCursorInfo = ApiMessage.Data.CursorInfoRequest.Info;
1048
1049 return TRUE;
1050 }
1051
1052
1053 /*--------------------------------------------------------------
1054 * GetNumberOfConsoleMouseButtons
1055 *
1056 * @unimplemented
1057 */
1058 BOOL
1059 WINAPI
1060 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1061 {
1062 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
1063 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1064 return FALSE;
1065 }
1066
1067
1068 /*--------------------------------------------------------------
1069 * SetConsoleMode
1070 *
1071 * @implemented
1072 */
1073 BOOL
1074 WINAPI
1075 SetConsoleMode(HANDLE hConsoleHandle,
1076 DWORD dwMode)
1077 {
1078 NTSTATUS Status;
1079 CONSOLE_API_MESSAGE ApiMessage;
1080 PCSRSS_CONSOLE_MODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1081
1082 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1083 ConsoleModeRequest->ConsoleMode = dwMode;
1084
1085 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1086 NULL,
1087 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1088 sizeof(CSRSS_CONSOLE_MODE));
1089 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1090 {
1091 BaseSetLastNTError(Status);
1092 return FALSE;
1093 }
1094
1095 return TRUE;
1096 }
1097
1098
1099 /*--------------------------------------------------------------
1100 * SetConsoleActiveScreenBuffer
1101 *
1102 * @implemented
1103 */
1104 BOOL
1105 WINAPI
1106 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1107 {
1108 NTSTATUS Status;
1109 CONSOLE_API_MESSAGE ApiMessage;
1110
1111 ApiMessage.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
1112
1113 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1114 NULL,
1115 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1116 sizeof(CSRSS_SET_SCREEN_BUFFER));
1117 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1118 {
1119 BaseSetLastNTError(Status);
1120 return FALSE;
1121 }
1122
1123 return TRUE;
1124 }
1125
1126
1127 /*--------------------------------------------------------------
1128 * FlushConsoleInputBuffer
1129 *
1130 * @implemented
1131 */
1132 BOOL
1133 WINAPI
1134 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1135 {
1136 NTSTATUS Status;
1137 CONSOLE_API_MESSAGE ApiMessage;
1138
1139 ApiMessage.Data.FlushInputBufferRequest.ConsoleInput = hConsoleInput;
1140
1141 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1142 NULL,
1143 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1144 sizeof(CSRSS_FLUSH_INPUT_BUFFER));
1145 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1146 {
1147 BaseSetLastNTError(Status);
1148 return FALSE;
1149 }
1150
1151 return TRUE;
1152 }
1153
1154
1155 /*--------------------------------------------------------------
1156 * SetConsoleScreenBufferSize
1157 *
1158 * @implemented
1159 */
1160 BOOL
1161 WINAPI
1162 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1163 COORD dwSize)
1164 {
1165 NTSTATUS Status;
1166 CONSOLE_API_MESSAGE ApiMessage;
1167
1168 ApiMessage.Data.SetScreenBufferSize.OutputHandle = hConsoleOutput;
1169 ApiMessage.Data.SetScreenBufferSize.Size = dwSize;
1170
1171 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1172 NULL,
1173 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1174 sizeof(CSRSS_SET_SCREEN_BUFFER_SIZE));
1175 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1176 {
1177 BaseSetLastNTError(Status);
1178 return FALSE;
1179 }
1180
1181 return TRUE;
1182 }
1183
1184
1185 /*--------------------------------------------------------------
1186 * SetConsoleCursorInfo
1187 *
1188 * @implemented
1189 */
1190 BOOL
1191 WINAPI
1192 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1193 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1194 {
1195 NTSTATUS Status;
1196 CONSOLE_API_MESSAGE ApiMessage;
1197
1198 ApiMessage.Data.CursorInfoRequest.ConsoleHandle = hConsoleOutput;
1199 ApiMessage.Data.CursorInfoRequest.Info = *lpConsoleCursorInfo;
1200
1201 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1202 NULL,
1203 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1204 sizeof(CSRSS_CURSOR_INFO));
1205 if(!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1206 {
1207 BaseSetLastNTError(Status);
1208 return FALSE;
1209 }
1210
1211 return TRUE;
1212 }
1213
1214
1215 static
1216 BOOL
1217 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1218 const SMALL_RECT *lpScrollRectangle,
1219 const SMALL_RECT *lpClipRectangle,
1220 COORD dwDestinationOrigin,
1221 const CHAR_INFO *lpFill,
1222 BOOL bUnicode)
1223 {
1224 NTSTATUS Status;
1225 CONSOLE_API_MESSAGE ApiMessage;
1226 PCSRSS_SCROLL_CONSOLE_SCREEN_BUFFER ScrollConsoleScreenBufferRequest = &ApiMessage.Data.ScrollConsoleScreenBufferRequest;
1227
1228 ScrollConsoleScreenBufferRequest->ConsoleHandle = hConsoleOutput;
1229 ScrollConsoleScreenBufferRequest->Unicode = bUnicode;
1230 ScrollConsoleScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1231
1232 if (lpClipRectangle != NULL)
1233 {
1234 ScrollConsoleScreenBufferRequest->UseClipRectangle = TRUE;
1235 ScrollConsoleScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1236 }
1237 else
1238 {
1239 ScrollConsoleScreenBufferRequest->UseClipRectangle = FALSE;
1240 }
1241
1242 ScrollConsoleScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1243 ScrollConsoleScreenBufferRequest->Fill = *lpFill;
1244
1245 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1246 NULL,
1247 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1248 sizeof(CSRSS_SCROLL_CONSOLE_SCREEN_BUFFER));
1249
1250 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1251 {
1252 BaseSetLastNTError(Status);
1253 return FALSE;
1254 }
1255
1256 return TRUE;
1257 }
1258
1259
1260 /*--------------------------------------------------------------
1261 * ScrollConsoleScreenBufferA
1262 *
1263 * @implemented
1264 */
1265 BOOL
1266 WINAPI
1267 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1268 CONST SMALL_RECT *lpScrollRectangle,
1269 CONST SMALL_RECT *lpClipRectangle,
1270 COORD dwDestinationOrigin,
1271 CONST CHAR_INFO *lpFill)
1272 {
1273 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1274 (PSMALL_RECT)lpScrollRectangle,
1275 (PSMALL_RECT)lpClipRectangle,
1276 dwDestinationOrigin,
1277 (PCHAR_INFO)lpFill,
1278 FALSE);
1279 }
1280
1281
1282 /*--------------------------------------------------------------
1283 * ScrollConsoleScreenBufferW
1284 *
1285 * @implemented
1286 */
1287 BOOL
1288 WINAPI
1289 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1290 CONST SMALL_RECT *lpScrollRectangle,
1291 CONST SMALL_RECT *lpClipRectangle,
1292 COORD dwDestinationOrigin,
1293 CONST CHAR_INFO *lpFill)
1294 {
1295 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1296 lpScrollRectangle,
1297 lpClipRectangle,
1298 dwDestinationOrigin,
1299 lpFill,
1300 TRUE);
1301 }
1302
1303
1304 /*--------------------------------------------------------------
1305 * SetConsoleWindowInfo
1306 *
1307 * @unimplemented
1308 */
1309 BOOL
1310 WINAPI
1311 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1312 BOOL bAbsolute,
1313 CONST SMALL_RECT *lpConsoleWindow)
1314 {
1315 DPRINT1("SetConsoleWindowInfo(0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bAbsolute, lpConsoleWindow);
1316 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1317 return FALSE;
1318 }
1319
1320
1321 /*--------------------------------------------------------------
1322 * SetConsoleTextAttribute
1323 *
1324 * @implemented
1325 */
1326 BOOL
1327 WINAPI
1328 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1329 WORD wAttributes)
1330 {
1331 NTSTATUS Status;
1332 CONSOLE_API_MESSAGE ApiMessage;
1333
1334 ApiMessage.Data.SetAttribRequest.ConsoleHandle = hConsoleOutput;
1335 ApiMessage.Data.SetAttribRequest.Attrib = wAttributes;
1336
1337 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1338 NULL,
1339 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1340 sizeof(CSRSS_SET_ATTRIB));
1341 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1342 {
1343 BaseSetLastNTError(Status);
1344 return FALSE;
1345 }
1346
1347 return TRUE;
1348 }
1349
1350
1351 static
1352 BOOL
1353 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1354 {
1355 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1356
1357 if (HandlerRoutine == NULL)
1358 {
1359 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1360 return TRUE;
1361 }
1362
1363 if (NrCtrlHandlers == NrAllocatedHandlers)
1364 {
1365 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1366 0,
1367 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1368 if (NewCtrlHandlers == NULL)
1369 {
1370 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1371 return FALSE;
1372 }
1373
1374 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1375
1376 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1377
1378 CtrlHandlers = NewCtrlHandlers;
1379 NrAllocatedHandlers += 4;
1380 }
1381
1382 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1383
1384 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1385 return TRUE;
1386 }
1387
1388
1389 static
1390 BOOL
1391 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1392 {
1393 ULONG i;
1394
1395 if (HandlerRoutine == NULL)
1396 {
1397 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1398 return TRUE;
1399 }
1400
1401 for (i = 0; i < NrCtrlHandlers; i++)
1402 {
1403 if (CtrlHandlers[i] == HandlerRoutine)
1404 {
1405 if (i < (NrCtrlHandlers - 1))
1406 {
1407 memmove(&CtrlHandlers[i],
1408 &CtrlHandlers[i+1],
1409 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1410 }
1411
1412 NrCtrlHandlers--;
1413 return TRUE;
1414 }
1415 }
1416
1417 SetLastError(ERROR_INVALID_PARAMETER);
1418 return FALSE;
1419 }
1420
1421
1422 /*
1423 * @implemented
1424 */
1425 BOOL
1426 WINAPI
1427 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1428 BOOL Add)
1429 {
1430 BOOL Ret;
1431
1432 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1433 if (Add)
1434 {
1435 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1436 }
1437 else
1438 {
1439 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1440 }
1441
1442 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1443 return(Ret);
1444 }
1445
1446
1447 /*--------------------------------------------------------------
1448 * GenerateConsoleCtrlEvent
1449 *
1450 * @implemented
1451 */
1452 BOOL
1453 WINAPI
1454 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1455 DWORD dwProcessGroupId)
1456 {
1457 NTSTATUS Status;
1458 CONSOLE_API_MESSAGE ApiMessage;
1459
1460 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1461 {
1462 SetLastError(ERROR_INVALID_PARAMETER);
1463 return FALSE;
1464 }
1465
1466 ApiMessage.Data.GenerateCtrlEvent.Event = dwCtrlEvent;
1467 ApiMessage.Data.GenerateCtrlEvent.ProcessGroup = dwProcessGroupId;
1468
1469 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1470 NULL,
1471 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1472 sizeof(CSRSS_GENERATE_CTRL_EVENT));
1473 if(!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = ApiMessage.Status)))
1474 {
1475 BaseSetLastNTError(Status);
1476 return FALSE;
1477 }
1478
1479 return TRUE;
1480 }
1481
1482
1483 static DWORD
1484 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
1485 {
1486 NTSTATUS Status;
1487 CONSOLE_API_MESSAGE ApiMessage;
1488 PCSRSS_CONSOLE_TITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1489 PCSR_CAPTURE_BUFFER CaptureBuffer;
1490
1491 if (nSize == 0)
1492 return 0;
1493
1494 TitleRequest->Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
1495 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1496 if (CaptureBuffer == NULL)
1497 {
1498 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1499 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1500 return 0;
1501 }
1502
1503 CsrAllocateMessagePointer(CaptureBuffer,
1504 TitleRequest->Length,
1505 (PVOID*)&TitleRequest->Title);
1506
1507 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1508 CaptureBuffer,
1509 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1510 sizeof(CSRSS_CONSOLE_TITLE));
1511 if (!NT_SUCCESS(Status) || !(NT_SUCCESS(Status = ApiMessage.Status)))
1512 {
1513 CsrFreeCaptureBuffer(CaptureBuffer);
1514 BaseSetLastNTError(Status);
1515 return 0;
1516 }
1517
1518 if (bUnicode)
1519 {
1520 if (nSize >= sizeof(WCHAR))
1521 wcscpy((LPWSTR)lpConsoleTitle, TitleRequest->Title);
1522 }
1523 else
1524 {
1525 if (nSize < TitleRequest->Length / sizeof(WCHAR) ||
1526 !WideCharToMultiByte(CP_ACP, // ANSI code page
1527 0, // performance and mapping flags
1528 TitleRequest->Title, // address of wide-character string
1529 -1, // number of characters in string
1530 (LPSTR)lpConsoleTitle, // address of buffer for new string
1531 nSize, // size of buffer
1532 NULL, // FAST
1533 NULL))
1534 {
1535 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1536 *(LPSTR)lpConsoleTitle = '\0';
1537 TitleRequest->Length = 0;
1538 }
1539 }
1540 CsrFreeCaptureBuffer(CaptureBuffer);
1541
1542 return TitleRequest->Length / sizeof(WCHAR);
1543 }
1544
1545
1546 /*--------------------------------------------------------------
1547 * GetConsoleTitleW
1548 *
1549 * @implemented
1550 */
1551 DWORD
1552 WINAPI
1553 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1554 DWORD nSize)
1555 {
1556 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1557 }
1558
1559
1560 /*--------------------------------------------------------------
1561 * GetConsoleTitleA
1562 *
1563 * @implemented
1564 */
1565 DWORD
1566 WINAPI
1567 GetConsoleTitleA(LPSTR lpConsoleTitle,
1568 DWORD nSize)
1569 {
1570 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1571 }
1572
1573
1574 /*--------------------------------------------------------------
1575 * SetConsoleTitleW
1576 *
1577 * @implemented
1578 */
1579 BOOL
1580 WINAPI
1581 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1582 {
1583 NTSTATUS Status;
1584 CONSOLE_API_MESSAGE ApiMessage;
1585 PCSRSS_CONSOLE_TITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1586 PCSR_CAPTURE_BUFFER CaptureBuffer;
1587
1588 TitleRequest->Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
1589
1590 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1591 if (CaptureBuffer == NULL)
1592 {
1593 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1594 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1595 return FALSE;
1596 }
1597
1598 CsrCaptureMessageBuffer(CaptureBuffer,
1599 (PVOID)lpConsoleTitle,
1600 TitleRequest->Length,
1601 (PVOID*)&TitleRequest->Title);
1602
1603 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1604 CaptureBuffer,
1605 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1606 sizeof(CSRSS_CONSOLE_TITLE));
1607
1608 CsrFreeCaptureBuffer(CaptureBuffer);
1609
1610 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1611 {
1612 BaseSetLastNTError(Status);
1613 return FALSE;
1614 }
1615
1616 return TRUE;
1617 }
1618
1619
1620 /*--------------------------------------------------------------
1621 * SetConsoleTitleA
1622 *
1623 * @implemented
1624 */
1625 BOOL
1626 WINAPI
1627 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1628 {
1629 ULONG Length = strlen(lpConsoleTitle) + 1;
1630 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1631 BOOL Ret;
1632 if (!WideTitle)
1633 {
1634 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1635 return FALSE;
1636 }
1637 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
1638 Ret = SetConsoleTitleW(WideTitle);
1639 HeapFree(GetProcessHeap(), 0, WideTitle);
1640 return Ret;
1641 }
1642
1643
1644 /*--------------------------------------------------------------
1645 * CreateConsoleScreenBuffer
1646 *
1647 * @implemented
1648 */
1649 HANDLE
1650 WINAPI
1651 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1652 DWORD dwShareMode,
1653 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1654 DWORD dwFlags,
1655 LPVOID lpScreenBufferData)
1656 {
1657 NTSTATUS Status;
1658 CONSOLE_API_MESSAGE ApiMessage;
1659
1660 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1661 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1662 (dwFlags != CONSOLE_TEXTMODE_BUFFER) )
1663 {
1664 SetLastError(ERROR_INVALID_PARAMETER);
1665 return INVALID_HANDLE_VALUE;
1666 }
1667
1668 ApiMessage.Data.CreateScreenBufferRequest.Access = dwDesiredAccess;
1669 ApiMessage.Data.CreateScreenBufferRequest.ShareMode = dwShareMode;
1670 ApiMessage.Data.CreateScreenBufferRequest.Inheritable =
1671 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1672
1673 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1674 NULL,
1675 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1676 sizeof(CSRSS_CREATE_SCREEN_BUFFER));
1677 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1678 {
1679 BaseSetLastNTError(Status);
1680 return INVALID_HANDLE_VALUE;
1681 }
1682
1683 return ApiMessage.Data.CreateScreenBufferRequest.OutputHandle;
1684 }
1685
1686
1687 /*--------------------------------------------------------------
1688 * GetConsoleCP
1689 *
1690 * @implemented
1691 */
1692 UINT
1693 WINAPI
1694 GetConsoleCP(VOID)
1695 {
1696 NTSTATUS Status;
1697 CONSOLE_API_MESSAGE ApiMessage;
1698
1699 /* Get the Input Code Page */
1700 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1701
1702 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1703 NULL,
1704 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1705 sizeof(CSRSS_CONSOLE_CP));
1706 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1707 {
1708 BaseSetLastNTError(Status);
1709 return 0;
1710 }
1711
1712 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1713 }
1714
1715
1716 /*--------------------------------------------------------------
1717 * SetConsoleCP
1718 *
1719 * @implemented
1720 */
1721 BOOL
1722 WINAPI
1723 SetConsoleCP(UINT wCodePageID)
1724 {
1725 NTSTATUS Status;
1726 CONSOLE_API_MESSAGE ApiMessage;
1727
1728 /* Set the Input Code Page */
1729 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1730 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1731
1732 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1733 NULL,
1734 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1735 sizeof(CSRSS_CONSOLE_CP));
1736 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1737 {
1738 BaseSetLastNTError(Status);
1739 }
1740
1741 return NT_SUCCESS(Status);
1742 }
1743
1744
1745 /*--------------------------------------------------------------
1746 * GetConsoleOutputCP
1747 *
1748 * @implemented
1749 */
1750 UINT
1751 WINAPI
1752 GetConsoleOutputCP(VOID)
1753 {
1754 NTSTATUS Status;
1755 CONSOLE_API_MESSAGE ApiMessage;
1756
1757 /* Get the Output Code Page */
1758 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1759
1760 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1761 NULL,
1762 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1763 sizeof(CSRSS_CONSOLE_CP));
1764 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1765 {
1766 BaseSetLastNTError (Status);
1767 return 0;
1768 }
1769
1770 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1771 }
1772
1773
1774 /*--------------------------------------------------------------
1775 * SetConsoleOutputCP
1776 *
1777 * @implemented
1778 */
1779 BOOL
1780 WINAPI
1781 SetConsoleOutputCP(UINT wCodePageID)
1782 {
1783 NTSTATUS Status;
1784 CONSOLE_API_MESSAGE ApiMessage;
1785
1786 /* Set the Output Code Page */
1787 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
1788 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1789
1790 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1791 NULL,
1792 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1793 sizeof(CSRSS_CONSOLE_CP));
1794 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1795 {
1796 BaseSetLastNTError(Status);
1797 }
1798
1799 return NT_SUCCESS(Status);
1800 }
1801
1802
1803 /*--------------------------------------------------------------
1804 * GetConsoleProcessList
1805 *
1806 * @implemented
1807 */
1808 DWORD
1809 WINAPI
1810 GetConsoleProcessList(LPDWORD lpdwProcessList,
1811 DWORD dwProcessCount)
1812 {
1813 NTSTATUS Status;
1814 CONSOLE_API_MESSAGE ApiMessage;
1815 PCSRSS_GET_PROCESS_LIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
1816 PCSR_CAPTURE_BUFFER CaptureBuffer;
1817 ULONG nProcesses;
1818
1819 if (lpdwProcessList == NULL || dwProcessCount == 0)
1820 {
1821 SetLastError(ERROR_INVALID_PARAMETER);
1822 return 0;
1823 }
1824
1825 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
1826 if (CaptureBuffer == NULL)
1827 {
1828 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1829 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1830 return FALSE;
1831 }
1832
1833 GetProcessListRequest->nMaxIds = dwProcessCount;
1834
1835 CsrAllocateMessagePointer(CaptureBuffer,
1836 dwProcessCount * sizeof(DWORD),
1837 (PVOID*)&GetProcessListRequest->pProcessIds);
1838
1839 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1840 CaptureBuffer,
1841 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
1842 sizeof(CSRSS_GET_PROCESS_LIST));
1843 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1844 {
1845 BaseSetLastNTError (Status);
1846 nProcesses = 0;
1847 }
1848 else
1849 {
1850 nProcesses = GetProcessListRequest->nProcessIdsTotal;
1851 if (dwProcessCount >= nProcesses)
1852 {
1853 memcpy(lpdwProcessList, GetProcessListRequest->pProcessIds, nProcesses * sizeof(DWORD));
1854 }
1855 }
1856
1857 CsrFreeCaptureBuffer(CaptureBuffer);
1858 return nProcesses;
1859 }
1860
1861
1862 /*--------------------------------------------------------------
1863 * GetConsoleSelectionInfo
1864 *
1865 * @implemented
1866 */
1867 BOOL
1868 WINAPI
1869 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
1870 {
1871 NTSTATUS Status;
1872 CONSOLE_API_MESSAGE ApiMessage;
1873
1874 if (lpConsoleSelectionInfo == NULL)
1875 {
1876 SetLastError(ERROR_INVALID_PARAMETER);
1877 return FALSE;
1878 }
1879
1880 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1881 NULL,
1882 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
1883 sizeof(CSRSS_GET_CONSOLE_SELECTION_INFO));
1884 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1885 {
1886 BaseSetLastNTError(Status);
1887 return FALSE;
1888 }
1889
1890 *lpConsoleSelectionInfo = ApiMessage.Data.GetConsoleSelectionInfo.Info;
1891 return TRUE;
1892 }
1893
1894
1895 /*--------------------------------------------------------------
1896 * AttachConsole
1897 *
1898 * @unimplemented
1899 */
1900 BOOL
1901 WINAPI
1902 AttachConsole(DWORD dwProcessId)
1903 {
1904 DPRINT1("AttachConsole(0x%x) UNIMPLEMENTED!\n", dwProcessId);
1905 return TRUE;
1906 }
1907
1908
1909 /*--------------------------------------------------------------
1910 * GetConsoleWindow
1911 *
1912 * @implemented
1913 */
1914 HWND
1915 WINAPI
1916 GetConsoleWindow(VOID)
1917 {
1918 NTSTATUS Status;
1919 CONSOLE_API_MESSAGE ApiMessage;
1920
1921 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1922 NULL,
1923 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
1924 sizeof(CSRSS_GET_CONSOLE_WINDOW));
1925 if (!NT_SUCCESS(Status ) || !NT_SUCCESS(Status = ApiMessage.Status))
1926 {
1927 BaseSetLastNTError(Status);
1928 return (HWND) NULL;
1929 }
1930
1931 return ApiMessage.Data.GetConsoleWindowRequest.WindowHandle;
1932 }
1933
1934
1935 /*--------------------------------------------------------------
1936 * SetConsoleIcon
1937 *
1938 * @implemented
1939 */
1940 BOOL
1941 WINAPI
1942 SetConsoleIcon(HICON hicon)
1943 {
1944 NTSTATUS Status;
1945 CONSOLE_API_MESSAGE ApiMessage;
1946
1947 ApiMessage.Data.SetConsoleIconRequest.WindowIcon = hicon;
1948
1949 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1950 NULL,
1951 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
1952 sizeof(CSRSS_SET_CONSOLE_ICON));
1953 if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = ApiMessage.Status))
1954 {
1955 BaseSetLastNTError(Status);
1956 return FALSE;
1957 }
1958
1959 return NT_SUCCESS(Status);
1960 }
1961
1962
1963 /******************************************************************************
1964 * \name SetConsoleInputExeNameW
1965 * \brief Sets the console input file name from a unicode string.
1966 * \param lpInputExeName Pointer to a unicode string with the name.
1967 * \return TRUE if successful, FALSE if unsuccsedful.
1968 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
1969 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
1970 */
1971 BOOL
1972 WINAPI
1973 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
1974 {
1975 int lenName;
1976
1977 if (!lpInputExeName
1978 || (lenName = lstrlenW(lpInputExeName)) == 0
1979 || lenName > INPUTEXENAME_BUFLEN - 1)
1980 {
1981 /* Fail if string is empty or too long */
1982 SetLastError(ERROR_INVALID_PARAMETER);
1983 return FALSE;
1984 }
1985
1986 RtlEnterCriticalSection(&ConsoleLock);
1987 _SEH2_TRY
1988 {
1989 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
1990 InputExeName[lenName] = L'\0';
1991 }
1992 _SEH2_FINALLY
1993 {
1994 RtlLeaveCriticalSection(&ConsoleLock);
1995 }
1996 _SEH2_END;
1997
1998 return TRUE;
1999 }
2000
2001
2002 /******************************************************************************
2003 * \name SetConsoleInputExeNameA
2004 * \brief Sets the console input file name from an ansi string.
2005 * \param lpInputExeName Pointer to an ansi string with the name.
2006 * \return TRUE if successful, FALSE if unsuccsedful.
2007 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2008 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2009 */
2010 BOOL
2011 WINAPI
2012 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2013 {
2014 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2015 ANSI_STRING InputExeNameA;
2016 UNICODE_STRING InputExeNameU;
2017 NTSTATUS Status;
2018 BOOL Ret;
2019
2020 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2021
2022 if(InputExeNameA.Length == 0 ||
2023 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1)
2024 {
2025 /* Fail if string is empty or too long */
2026 SetLastError(ERROR_INVALID_PARAMETER);
2027 return FALSE;
2028 }
2029
2030 InputExeNameU.Buffer = Buffer;
2031 InputExeNameU.MaximumLength = sizeof(Buffer);
2032 InputExeNameU.Length = 0;
2033 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2034 if(NT_SUCCESS(Status))
2035 {
2036 Ret = SetConsoleInputExeNameW(InputExeNameU.Buffer);
2037 }
2038 else
2039 {
2040 BaseSetLastNTError(Status);
2041 Ret = FALSE;
2042 }
2043
2044 return Ret;
2045 }
2046
2047
2048 /******************************************************************************
2049 * \name GetConsoleInputExeNameW
2050 * \brief Retrieves the console input file name as unicode string.
2051 * \param nBufferLength Length of the buffer in WCHARs.
2052 * Specify 0 to recieve the needed buffer length.
2053 * \param lpBuffer Pointer to a buffer that recieves the string.
2054 * \return Needed buffer size if \p nBufferLength is 0.
2055 * Otherwise 1 if successful, 2 if buffer is too small.
2056 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2057 * is not big enough.
2058 */
2059 DWORD
2060 WINAPI
2061 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2062 {
2063 int lenName = lstrlenW(InputExeName);
2064
2065 if (nBufferLength == 0)
2066 {
2067 /* Buffer size is requested, return it */
2068 return lenName + 1;
2069 }
2070
2071 if(lenName + 1 > nBufferLength)
2072 {
2073 /* Buffer is not large enough! */
2074 SetLastError(ERROR_BUFFER_OVERFLOW);
2075 return 2;
2076 }
2077
2078 RtlEnterCriticalSection(&ConsoleLock);
2079 _SEH2_TRY
2080 {
2081 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2082 lpBuffer[lenName] = '\0';
2083 }
2084 _SEH2_FINALLY
2085 {
2086 RtlLeaveCriticalSection(&ConsoleLock);
2087 }
2088 _SEH2_END;
2089
2090 /* Success, return 1 */
2091 return 1;
2092 }
2093
2094
2095 /******************************************************************************
2096 * \name GetConsoleInputExeNameA
2097 * \brief Retrieves the console input file name as ansi string.
2098 * \param nBufferLength Length of the buffer in CHARs.
2099 * \param lpBuffer Pointer to a buffer that recieves the string.
2100 * \return 1 if successful, 2 if buffer is too small.
2101 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2102 * is not big enough. The buffer recieves as much characters as fit.
2103 */
2104 DWORD
2105 WINAPI
2106 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2107 {
2108 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2109 DWORD Ret;
2110 UNICODE_STRING BufferU;
2111 ANSI_STRING BufferA;
2112
2113 /* Get the unicode name */
2114 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2115
2116 /* Initialize strings for conversion */
2117 RtlInitUnicodeString(&BufferU, Buffer);
2118 BufferA.Length = 0;
2119 BufferA.MaximumLength = nBufferLength;
2120 BufferA.Buffer = lpBuffer;
2121
2122 /* Convert unicode name to ansi, copying as much chars as fit */
2123 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2124
2125 /* Error handling */
2126 if(nBufferLength <= BufferU.Length / sizeof(WCHAR))
2127 {
2128 SetLastError(ERROR_BUFFER_OVERFLOW);
2129 return 2;
2130 }
2131
2132 return Ret;
2133 }
2134
2135 BOOL
2136 WINAPI
2137 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2138 {
2139 STUB;
2140 return FALSE;
2141 }
2142
2143 BOOL
2144 WINAPI
2145 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2146 {
2147 STUB;
2148 return FALSE;
2149 }
2150
2151 BOOL
2152 WINAPI
2153 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2154 {
2155 STUB;
2156 return FALSE;
2157 }
2158
2159 BOOL
2160 WINAPI
2161 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2162 {
2163 STUB;
2164 return FALSE;
2165 }
2166
2167 BOOL
2168 WINAPI
2169 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2170 {
2171 STUB;
2172 return FALSE;
2173 }
2174
2175 BOOL
2176 WINAPI
2177 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2178 {
2179 STUB;
2180 return FALSE;
2181 }
2182
2183 BOOL
2184 WINAPI
2185 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2186 {
2187 STUB;
2188 return FALSE;
2189 }
2190
2191 BOOL
2192 WINAPI
2193 RegisterConsoleOS2(BOOL bUnknown)
2194 {
2195 STUB;
2196 return FALSE;
2197 }
2198
2199 BOOL
2200 WINAPI
2201 SetConsoleOS2OemFormat(BOOL bUnknown)
2202 {
2203 STUB;
2204 return FALSE;
2205 }
2206
2207 BOOL
2208 WINAPI
2209 UnregisterConsoleIME(VOID)
2210 {
2211 STUB;
2212 return FALSE;
2213 }
2214
2215
2216 /*
2217 * @unimplemented
2218 */
2219 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2220 {
2221 STUB;
2222 return 0;
2223 }
2224
2225 /*
2226 * @unimplemented
2227 */
2228 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2229 {
2230 STUB;
2231 return 0;
2232 }
2233
2234 /*
2235 * @unimplemented
2236 */
2237 BOOL
2238 WINAPI
2239 SetLastConsoleEventActive(VOID)
2240 {
2241 STUB;
2242 return FALSE;
2243 }
2244
2245 /* EOF */