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