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