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