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