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