ddb7bdf6eb32231d8279bdfa9c7415bc61b05dca
[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 * 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(HANDLE hConsoleOutput,
350 BOOL bMaximumWindow,
351 DWORD nFontCount,
352 PCONSOLE_FONT_INFO lpConsoleFontInfo)
353 {
354 DPRINT1("GetConsoleFontInfo(0x%x, %d, %d, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, nFontCount, lpConsoleFontInfo);
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 BOOL
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(HANDLE hConsoleOutput,
614 DWORD nFont)
615 {
616 DPRINT1("SetConsoleFont(0x%x, %d) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
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
941 if (Parameters->ConsoleHandle)
942 {
943 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
944 SetLastError(ERROR_ACCESS_DENIED);
945 return FALSE;
946 }
947
948 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
949 if (CaptureBuffer == NULL)
950 {
951 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
952 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
953 return FALSE;
954 }
955
956 CsrAllocateMessagePointer(CaptureBuffer,
957 sizeof(CONSOLE_START_INFO),
958 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
959
960 InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo,
961 &Parameters->ImagePathName);
962
963 AllocConsoleRequest->ConsoleHandle = NULL;
964 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
965 AllocConsoleRequest->PropDispatcher = PropDialogHandler;
966
967 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
968 CaptureBuffer,
969 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
970 sizeof(CONSOLE_ALLOCCONSOLE));
971
972 CsrFreeCaptureBuffer(CaptureBuffer);
973
974 if (!NT_SUCCESS(Status))
975 {
976 BaseSetLastNTError(Status);
977 return FALSE;
978 }
979
980 Parameters->ConsoleHandle = AllocConsoleRequest->ConsoleHandle;
981 SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
982 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
983 SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
984
985 /* Initialize Console Ctrl Handler */
986 InitConsoleCtrlHandling();
987
988 InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
989
990 return TRUE;
991 }
992
993
994 /*--------------------------------------------------------------
995 * FreeConsole
996 *
997 * @implemented
998 */
999 BOOL
1000 WINAPI
1001 FreeConsole(VOID)
1002 {
1003 // AG: I'm not sure if this is correct (what happens to std handles?)
1004 // but I just tried to reverse what AllocConsole() does...
1005
1006 NTSTATUS Status;
1007 CONSOLE_API_MESSAGE ApiMessage;
1008
1009 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1010 NULL,
1011 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
1012 sizeof(CONSOLE_FREECONSOLE));
1013 if (!NT_SUCCESS(Status))
1014 {
1015 BaseSetLastNTError(Status);
1016 return FALSE;
1017 }
1018
1019 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1020
1021 CloseHandle(InputWaitHandle);
1022 InputWaitHandle = INVALID_HANDLE_VALUE;
1023
1024 return TRUE;
1025 }
1026
1027
1028 /*--------------------------------------------------------------
1029 * GetConsoleScreenBufferInfo
1030 *
1031 * @implemented
1032 */
1033 BOOL
1034 WINAPI
1035 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1036 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1037 {
1038 NTSTATUS Status;
1039 CONSOLE_API_MESSAGE ApiMessage;
1040
1041 if (lpConsoleScreenBufferInfo == NULL)
1042 {
1043 SetLastError(ERROR_INVALID_PARAMETER);
1044 return FALSE;
1045 }
1046
1047 ApiMessage.Data.ScreenBufferInfoRequest.OutputHandle = hConsoleOutput;
1048
1049 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1050 NULL,
1051 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1052 sizeof(CONSOLE_GETSCREENBUFFERINFO));
1053 if (!NT_SUCCESS(Status))
1054 {
1055 BaseSetLastNTError(Status);
1056 return FALSE;
1057 }
1058
1059 *lpConsoleScreenBufferInfo = ApiMessage.Data.ScreenBufferInfoRequest.Info;
1060
1061 return TRUE;
1062 }
1063
1064
1065 /*--------------------------------------------------------------
1066 * SetConsoleCursorPosition
1067 *
1068 * @implemented
1069 */
1070 BOOL
1071 WINAPI
1072 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1073 COORD dwCursorPosition)
1074 {
1075 NTSTATUS Status;
1076 CONSOLE_API_MESSAGE ApiMessage;
1077
1078 ApiMessage.Data.SetCursorPositionRequest.OutputHandle = hConsoleOutput;
1079 ApiMessage.Data.SetCursorPositionRequest.Position = dwCursorPosition;
1080
1081 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1082 NULL,
1083 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1084 sizeof(CONSOLE_SETCURSORPOSITION));
1085 if (!NT_SUCCESS(Status))
1086 {
1087 BaseSetLastNTError(Status);
1088 return FALSE;
1089 }
1090
1091 return TRUE;
1092 }
1093
1094
1095 /*--------------------------------------------------------------
1096 * GetConsoleMode
1097 *
1098 * @implemented
1099 */
1100 BOOL
1101 WINAPI
1102 GetConsoleMode(HANDLE hConsoleHandle,
1103 LPDWORD lpMode)
1104 {
1105 NTSTATUS Status;
1106 CONSOLE_API_MESSAGE ApiMessage;
1107 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1108
1109 if (lpMode == NULL)
1110 {
1111 SetLastError(ERROR_INVALID_PARAMETER);
1112 return FALSE;
1113 }
1114
1115 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1116
1117 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1118 NULL,
1119 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1120 sizeof(CONSOLE_GETSETCONSOLEMODE));
1121 if (!NT_SUCCESS(Status))
1122 {
1123 BaseSetLastNTError(Status);
1124 return FALSE;
1125 }
1126
1127 *lpMode = ConsoleModeRequest->ConsoleMode;
1128
1129 return TRUE;
1130 }
1131
1132
1133 /*--------------------------------------------------------------
1134 * GetNumberOfConsoleInputEvents
1135 *
1136 * @implemented
1137 */
1138 BOOL
1139 WINAPI
1140 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1141 LPDWORD lpNumberOfEvents)
1142 {
1143 NTSTATUS Status;
1144 CONSOLE_API_MESSAGE ApiMessage;
1145 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1146
1147 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1148 GetNumInputEventsRequest->NumInputEvents = 0;
1149
1150 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1151 NULL,
1152 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1153 sizeof(CONSOLE_GETNUMINPUTEVENTS));
1154 if (!NT_SUCCESS(Status))
1155 {
1156 BaseSetLastNTError(Status);
1157 return FALSE;
1158 }
1159
1160 if (lpNumberOfEvents == NULL)
1161 {
1162 SetLastError(ERROR_INVALID_ACCESS);
1163 return FALSE;
1164 }
1165
1166 *lpNumberOfEvents = GetNumInputEventsRequest->NumInputEvents;
1167
1168 return TRUE;
1169 }
1170
1171
1172 /*--------------------------------------------------------------
1173 * GetLargestConsoleWindowSize
1174 *
1175 * @implemented
1176 */
1177 COORD
1178 WINAPI
1179 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1180 {
1181 NTSTATUS Status;
1182 CONSOLE_API_MESSAGE ApiMessage;
1183 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1184
1185 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1186 GetLargestWindowSizeRequest->Size.X = 0;
1187 GetLargestWindowSizeRequest->Size.Y = 0;
1188
1189 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1190 NULL,
1191 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1192 sizeof(CONSOLE_GETLARGESTWINDOWSIZE));
1193 if (!NT_SUCCESS(Status))
1194 {
1195 BaseSetLastNTError(Status);
1196 }
1197
1198 DPRINT1("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1199 return GetLargestWindowSizeRequest->Size;
1200 }
1201
1202
1203 /*--------------------------------------------------------------
1204 * GetConsoleCursorInfo
1205 *
1206 * @implemented
1207 */
1208 BOOL
1209 WINAPI
1210 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1211 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1212 {
1213 NTSTATUS Status;
1214 CONSOLE_API_MESSAGE ApiMessage;
1215
1216 if (!lpConsoleCursorInfo)
1217 {
1218 if (!hConsoleOutput)
1219 SetLastError(ERROR_INVALID_HANDLE);
1220 else
1221 SetLastError(ERROR_INVALID_ACCESS);
1222
1223 return FALSE;
1224 }
1225
1226 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1227
1228 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1229 NULL,
1230 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1231 sizeof(CONSOLE_GETSETCURSORINFO));
1232 if (!NT_SUCCESS(Status))
1233 {
1234 BaseSetLastNTError(Status);
1235 return FALSE;
1236 }
1237
1238 *lpConsoleCursorInfo = ApiMessage.Data.CursorInfoRequest.Info;
1239
1240 return TRUE;
1241 }
1242
1243
1244 /*--------------------------------------------------------------
1245 * GetNumberOfConsoleMouseButtons
1246 *
1247 * @unimplemented
1248 */
1249 BOOL
1250 WINAPI
1251 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1252 {
1253 DPRINT1("GetNumberOfConsoleMouseButtons(0x%x) UNIMPLEMENTED!\n", lpNumberOfMouseButtons);
1254 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1255 return FALSE;
1256 }
1257
1258
1259 /*--------------------------------------------------------------
1260 * SetConsoleMode
1261 *
1262 * @implemented
1263 */
1264 BOOL
1265 WINAPI
1266 SetConsoleMode(HANDLE hConsoleHandle,
1267 DWORD dwMode)
1268 {
1269 NTSTATUS Status;
1270 CONSOLE_API_MESSAGE ApiMessage;
1271 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1272
1273 ConsoleModeRequest->ConsoleHandle = hConsoleHandle;
1274 ConsoleModeRequest->ConsoleMode = dwMode;
1275
1276 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1277 NULL,
1278 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1279 sizeof(CONSOLE_GETSETCONSOLEMODE));
1280 if (!NT_SUCCESS(Status))
1281 {
1282 BaseSetLastNTError(Status);
1283 return FALSE;
1284 }
1285
1286 return TRUE;
1287 }
1288
1289
1290 /*--------------------------------------------------------------
1291 * SetConsoleActiveScreenBuffer
1292 *
1293 * @implemented
1294 */
1295 BOOL
1296 WINAPI
1297 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1298 {
1299 NTSTATUS Status;
1300 CONSOLE_API_MESSAGE ApiMessage;
1301
1302 ApiMessage.Data.SetScreenBufferRequest.OutputHandle = hConsoleOutput;
1303
1304 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1305 NULL,
1306 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1307 sizeof(CONSOLE_SETACTIVESCREENBUFFER));
1308 if (!NT_SUCCESS(Status))
1309 {
1310 BaseSetLastNTError(Status);
1311 return FALSE;
1312 }
1313
1314 return TRUE;
1315 }
1316
1317
1318 /*--------------------------------------------------------------
1319 * FlushConsoleInputBuffer
1320 *
1321 * @implemented
1322 */
1323 BOOL
1324 WINAPI
1325 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1326 {
1327 NTSTATUS Status;
1328 CONSOLE_API_MESSAGE ApiMessage;
1329
1330 ApiMessage.Data.FlushInputBufferRequest.InputHandle = hConsoleInput;
1331
1332 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1333 NULL,
1334 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1335 sizeof(CONSOLE_FLUSHINPUTBUFFER));
1336 if (!NT_SUCCESS(Status))
1337 {
1338 BaseSetLastNTError(Status);
1339 return FALSE;
1340 }
1341
1342 return TRUE;
1343 }
1344
1345
1346 /*--------------------------------------------------------------
1347 * SetConsoleScreenBufferSize
1348 *
1349 * @implemented
1350 */
1351 BOOL
1352 WINAPI
1353 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1354 COORD dwSize)
1355 {
1356 NTSTATUS Status;
1357 CONSOLE_API_MESSAGE ApiMessage;
1358
1359 ApiMessage.Data.SetScreenBufferSizeRequest.OutputHandle = hConsoleOutput;
1360 ApiMessage.Data.SetScreenBufferSizeRequest.Size = dwSize;
1361
1362 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1363 NULL,
1364 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1365 sizeof(CONSOLE_SETSCREENBUFFERSIZE));
1366 if (!NT_SUCCESS(Status))
1367 {
1368 BaseSetLastNTError(Status);
1369 return FALSE;
1370 }
1371
1372 return TRUE;
1373 }
1374
1375
1376 /*--------------------------------------------------------------
1377 * SetConsoleCursorInfo
1378 *
1379 * @implemented
1380 */
1381 BOOL
1382 WINAPI
1383 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1384 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1385 {
1386 NTSTATUS Status;
1387 CONSOLE_API_MESSAGE ApiMessage;
1388
1389 ApiMessage.Data.CursorInfoRequest.OutputHandle = hConsoleOutput;
1390 ApiMessage.Data.CursorInfoRequest.Info = *lpConsoleCursorInfo;
1391
1392 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1393 NULL,
1394 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1395 sizeof(CONSOLE_GETSETCURSORINFO));
1396 if (!NT_SUCCESS(Status))
1397 {
1398 BaseSetLastNTError(Status);
1399 return FALSE;
1400 }
1401
1402 return TRUE;
1403 }
1404
1405
1406 static
1407 BOOL
1408 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1409 const SMALL_RECT *lpScrollRectangle,
1410 const SMALL_RECT *lpClipRectangle,
1411 COORD dwDestinationOrigin,
1412 const CHAR_INFO *lpFill,
1413 BOOL bUnicode)
1414 {
1415 NTSTATUS Status;
1416 CONSOLE_API_MESSAGE ApiMessage;
1417 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1418
1419 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1420 ScrollScreenBufferRequest->Unicode = bUnicode;
1421 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1422
1423 if (lpClipRectangle != NULL)
1424 {
1425 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1426 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1427 }
1428 else
1429 {
1430 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1431 }
1432
1433 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1434 ScrollScreenBufferRequest->Fill = *lpFill;
1435
1436 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1437 NULL,
1438 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1439 sizeof(CONSOLE_SCROLLSCREENBUFFER));
1440
1441 if (!NT_SUCCESS(Status))
1442 {
1443 BaseSetLastNTError(Status);
1444 return FALSE;
1445 }
1446
1447 return TRUE;
1448 }
1449
1450
1451 /*--------------------------------------------------------------
1452 * ScrollConsoleScreenBufferA
1453 *
1454 * @implemented
1455 */
1456 BOOL
1457 WINAPI
1458 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1459 CONST SMALL_RECT *lpScrollRectangle,
1460 CONST SMALL_RECT *lpClipRectangle,
1461 COORD dwDestinationOrigin,
1462 CONST CHAR_INFO *lpFill)
1463 {
1464 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1465 (PSMALL_RECT)lpScrollRectangle,
1466 (PSMALL_RECT)lpClipRectangle,
1467 dwDestinationOrigin,
1468 (PCHAR_INFO)lpFill,
1469 FALSE);
1470 }
1471
1472
1473 /*--------------------------------------------------------------
1474 * ScrollConsoleScreenBufferW
1475 *
1476 * @implemented
1477 */
1478 BOOL
1479 WINAPI
1480 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1481 CONST SMALL_RECT *lpScrollRectangle,
1482 CONST SMALL_RECT *lpClipRectangle,
1483 COORD dwDestinationOrigin,
1484 CONST CHAR_INFO *lpFill)
1485 {
1486 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1487 lpScrollRectangle,
1488 lpClipRectangle,
1489 dwDestinationOrigin,
1490 lpFill,
1491 TRUE);
1492 }
1493
1494
1495 /*--------------------------------------------------------------
1496 * SetConsoleWindowInfo
1497 *
1498 * @implemented
1499 */
1500 BOOL
1501 WINAPI
1502 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1503 BOOL bAbsolute,
1504 CONST SMALL_RECT *lpConsoleWindow)
1505 {
1506 NTSTATUS Status;
1507 CONSOLE_API_MESSAGE ApiMessage;
1508 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1509
1510 if (lpConsoleWindow == NULL)
1511 {
1512 SetLastError(ERROR_INVALID_PARAMETER);
1513 return FALSE;
1514 }
1515
1516 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1517 SetWindowInfoRequest->Absolute = bAbsolute;
1518 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1519
1520 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1521 NULL,
1522 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1523 sizeof(CONSOLE_SETWINDOWINFO));
1524 if (!NT_SUCCESS(Status))
1525 {
1526 BaseSetLastNTError(Status);
1527 return FALSE;
1528 }
1529
1530 return TRUE;
1531 }
1532
1533
1534 /*--------------------------------------------------------------
1535 * SetConsoleTextAttribute
1536 *
1537 * @implemented
1538 */
1539 BOOL
1540 WINAPI
1541 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1542 WORD wAttributes)
1543 {
1544 NTSTATUS Status;
1545 CONSOLE_API_MESSAGE ApiMessage;
1546
1547 ApiMessage.Data.SetTextAttribRequest.OutputHandle = hConsoleOutput;
1548 ApiMessage.Data.SetTextAttribRequest.Attrib = wAttributes;
1549
1550 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1551 NULL,
1552 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1553 sizeof(CONSOLE_SETTEXTATTRIB));
1554 if (!NT_SUCCESS(Status))
1555 {
1556 BaseSetLastNTError(Status);
1557 return FALSE;
1558 }
1559
1560 return TRUE;
1561 }
1562
1563
1564 static
1565 BOOL
1566 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1567 {
1568 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1569
1570 if (HandlerRoutine == NULL)
1571 {
1572 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1573 return TRUE;
1574 }
1575
1576 if (NrCtrlHandlers == NrAllocatedHandlers)
1577 {
1578 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1579 0,
1580 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1581 if (NewCtrlHandlers == NULL)
1582 {
1583 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1584 return FALSE;
1585 }
1586
1587 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1588
1589 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1590
1591 CtrlHandlers = NewCtrlHandlers;
1592 NrAllocatedHandlers += 4;
1593 }
1594
1595 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1596
1597 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1598 return TRUE;
1599 }
1600
1601
1602 static
1603 BOOL
1604 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1605 {
1606 ULONG i;
1607
1608 if (HandlerRoutine == NULL)
1609 {
1610 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1611 return TRUE;
1612 }
1613
1614 for (i = 0; i < NrCtrlHandlers; i++)
1615 {
1616 if (CtrlHandlers[i] == HandlerRoutine)
1617 {
1618 if (i < (NrCtrlHandlers - 1))
1619 {
1620 memmove(&CtrlHandlers[i],
1621 &CtrlHandlers[i+1],
1622 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1623 }
1624
1625 NrCtrlHandlers--;
1626 return TRUE;
1627 }
1628 }
1629
1630 SetLastError(ERROR_INVALID_PARAMETER);
1631 return FALSE;
1632 }
1633
1634
1635 /*
1636 * @implemented
1637 */
1638 BOOL
1639 WINAPI
1640 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1641 BOOL Add)
1642 {
1643 BOOL Ret;
1644
1645 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1646 if (Add)
1647 {
1648 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1649 }
1650 else
1651 {
1652 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1653 }
1654
1655 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1656 return(Ret);
1657 }
1658
1659
1660 /*--------------------------------------------------------------
1661 * GenerateConsoleCtrlEvent
1662 *
1663 * @implemented
1664 */
1665 BOOL
1666 WINAPI
1667 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1668 DWORD dwProcessGroupId)
1669 {
1670 NTSTATUS Status;
1671 CONSOLE_API_MESSAGE ApiMessage;
1672
1673 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1674 {
1675 SetLastError(ERROR_INVALID_PARAMETER);
1676 return FALSE;
1677 }
1678
1679 ApiMessage.Data.GenerateCtrlEventRequest.Event = dwCtrlEvent;
1680 ApiMessage.Data.GenerateCtrlEventRequest.ProcessGroup = dwProcessGroupId;
1681
1682 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1683 NULL,
1684 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1685 sizeof(CONSOLE_GENERATECTRLEVENT));
1686 if (!NT_SUCCESS(Status))
1687 {
1688 BaseSetLastNTError(Status);
1689 return FALSE;
1690 }
1691
1692 return TRUE;
1693 }
1694
1695
1696 static DWORD
1697 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD nSize, BOOL bUnicode)
1698 {
1699 NTSTATUS Status;
1700 CONSOLE_API_MESSAGE ApiMessage;
1701 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1702 PCSR_CAPTURE_BUFFER CaptureBuffer;
1703
1704 if (nSize == 0) return 0;
1705
1706 TitleRequest->Length = nSize * (bUnicode ? 1 : sizeof(WCHAR));
1707 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1708 if (CaptureBuffer == NULL)
1709 {
1710 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1711 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1712 return 0;
1713 }
1714
1715 CsrAllocateMessagePointer(CaptureBuffer,
1716 TitleRequest->Length,
1717 (PVOID*)&TitleRequest->Title);
1718
1719 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1720 CaptureBuffer,
1721 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1722 sizeof(CONSOLE_GETSETCONSOLETITLE));
1723 if (!NT_SUCCESS(Status))
1724 {
1725 CsrFreeCaptureBuffer(CaptureBuffer);
1726 BaseSetLastNTError(Status);
1727 return 0;
1728 }
1729
1730 if (bUnicode)
1731 {
1732 if (nSize >= sizeof(WCHAR))
1733 wcscpy((LPWSTR)lpConsoleTitle, TitleRequest->Title);
1734 }
1735 else
1736 {
1737 if (nSize < TitleRequest->Length / sizeof(WCHAR) ||
1738 !WideCharToMultiByte(CP_ACP, // ANSI code page
1739 0, // performance and mapping flags
1740 TitleRequest->Title, // address of wide-character string
1741 -1, // number of characters in string
1742 (LPSTR)lpConsoleTitle, // address of buffer for new string
1743 nSize, // size of buffer
1744 NULL, // FAST
1745 NULL))
1746 {
1747 /* Yes, if the buffer isn't big enough, it returns 0... Bad API */
1748 *(LPSTR)lpConsoleTitle = '\0';
1749 TitleRequest->Length = 0;
1750 }
1751 }
1752 CsrFreeCaptureBuffer(CaptureBuffer);
1753
1754 return TitleRequest->Length / sizeof(WCHAR);
1755 }
1756
1757
1758 /*--------------------------------------------------------------
1759 * GetConsoleTitleW
1760 *
1761 * @implemented
1762 */
1763 DWORD
1764 WINAPI
1765 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1766 DWORD nSize)
1767 {
1768 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1769 }
1770
1771
1772 /*--------------------------------------------------------------
1773 * GetConsoleTitleA
1774 *
1775 * @implemented
1776 */
1777 DWORD
1778 WINAPI
1779 GetConsoleTitleA(LPSTR lpConsoleTitle,
1780 DWORD nSize)
1781 {
1782 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1783 }
1784
1785
1786 /*--------------------------------------------------------------
1787 * SetConsoleTitleW
1788 *
1789 * @implemented
1790 */
1791 BOOL
1792 WINAPI
1793 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1794 {
1795 NTSTATUS Status;
1796 CONSOLE_API_MESSAGE ApiMessage;
1797 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1798 PCSR_CAPTURE_BUFFER CaptureBuffer;
1799
1800 TitleRequest->Length = wcslen(lpConsoleTitle) * sizeof(WCHAR);
1801
1802 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1803 if (CaptureBuffer == NULL)
1804 {
1805 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1806 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1807 return FALSE;
1808 }
1809
1810 CsrCaptureMessageBuffer(CaptureBuffer,
1811 (PVOID)lpConsoleTitle,
1812 TitleRequest->Length,
1813 (PVOID*)&TitleRequest->Title);
1814
1815 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1816 CaptureBuffer,
1817 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1818 sizeof(CONSOLE_GETSETCONSOLETITLE));
1819
1820 CsrFreeCaptureBuffer(CaptureBuffer);
1821
1822 if (!NT_SUCCESS(Status))
1823 {
1824 BaseSetLastNTError(Status);
1825 return FALSE;
1826 }
1827
1828 return TRUE;
1829 }
1830
1831
1832 /*--------------------------------------------------------------
1833 * SetConsoleTitleA
1834 *
1835 * @implemented
1836 */
1837 BOOL
1838 WINAPI
1839 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1840 {
1841 BOOL Ret;
1842 ULONG Length = strlen(lpConsoleTitle) + 1;
1843 LPWSTR WideTitle = HeapAlloc(GetProcessHeap(), 0, Length * sizeof(WCHAR));
1844
1845 if (!WideTitle)
1846 {
1847 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1848 return FALSE;
1849 }
1850
1851 MultiByteToWideChar(CP_ACP, 0, lpConsoleTitle, -1, WideTitle, Length);
1852
1853 Ret = SetConsoleTitleW(WideTitle);
1854
1855 HeapFree(GetProcessHeap(), 0, WideTitle);
1856 return Ret;
1857 }
1858
1859
1860 /*--------------------------------------------------------------
1861 * CreateConsoleScreenBuffer
1862 *
1863 * @implemented
1864 */
1865 HANDLE
1866 WINAPI
1867 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1868 DWORD dwShareMode,
1869 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1870 DWORD dwFlags,
1871 LPVOID lpScreenBufferData)
1872 {
1873 NTSTATUS Status;
1874 CONSOLE_API_MESSAGE ApiMessage;
1875 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1876 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1877 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = /*(PCONSOLE_GRAPHICS_BUFFER_INFO)*/lpScreenBufferData;
1878
1879 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1880 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1881 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1882 {
1883 SetLastError(ERROR_INVALID_PARAMETER);
1884 return INVALID_HANDLE_VALUE;
1885 }
1886
1887 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1888 CreateScreenBufferRequest->Access = dwDesiredAccess;
1889 CreateScreenBufferRequest->ShareMode = dwShareMode;
1890 CreateScreenBufferRequest->Inheritable =
1891 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1892
1893 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1894 {
1895 if (CreateScreenBufferRequest->Inheritable || GraphicsBufferInfo == NULL)
1896 {
1897 SetLastError(ERROR_INVALID_PARAMETER);
1898 return INVALID_HANDLE_VALUE;
1899 }
1900
1901 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
1902
1903 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
1904 if (CaptureBuffer == NULL)
1905 {
1906 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1907 return FALSE;
1908 }
1909
1910 CsrCaptureMessageBuffer(CaptureBuffer,
1911 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
1912 GraphicsBufferInfo->dwBitMapInfoLength,
1913 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
1914 }
1915
1916 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1917 CaptureBuffer,
1918 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
1919 sizeof(CONSOLE_CREATESCREENBUFFER));
1920
1921 if (CaptureBuffer)
1922 CsrFreeCaptureBuffer(CaptureBuffer);
1923
1924 if (!NT_SUCCESS(Status))
1925 {
1926 BaseSetLastNTError(Status);
1927 return INVALID_HANDLE_VALUE;
1928 }
1929
1930 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
1931 {
1932 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
1933 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
1934 }
1935
1936 return CreateScreenBufferRequest->OutputHandle;
1937 }
1938
1939
1940 /*--------------------------------------------------------------
1941 * GetConsoleCP
1942 *
1943 * @implemented
1944 */
1945 UINT
1946 WINAPI
1947 GetConsoleCP(VOID)
1948 {
1949 NTSTATUS Status;
1950 CONSOLE_API_MESSAGE ApiMessage;
1951
1952 /* Get the Input Code Page */
1953 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1954 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
1955
1956 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1957 NULL,
1958 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
1959 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1960
1961 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1962
1963 return ApiMessage.Data.ConsoleCPRequest.CodePage;
1964 }
1965
1966
1967 /*--------------------------------------------------------------
1968 * SetConsoleCP
1969 *
1970 * @implemented
1971 */
1972 BOOL
1973 WINAPI
1974 SetConsoleCP(UINT wCodePageID)
1975 {
1976 NTSTATUS Status;
1977 CONSOLE_API_MESSAGE ApiMessage;
1978
1979 /* Set the Input Code Page */
1980 ApiMessage.Data.ConsoleCPRequest.InputCP = TRUE;
1981 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
1982
1983 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1984 NULL,
1985 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
1986 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
1987
1988 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
1989
1990 return NT_SUCCESS(Status);
1991 }
1992
1993
1994 /*--------------------------------------------------------------
1995 * GetConsoleOutputCP
1996 *
1997 * @implemented
1998 */
1999 UINT
2000 WINAPI
2001 GetConsoleOutputCP(VOID)
2002 {
2003 NTSTATUS Status;
2004 CONSOLE_API_MESSAGE ApiMessage;
2005
2006 /* Get the Output Code Page */
2007 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
2008 ApiMessage.Data.ConsoleCPRequest.CodePage = 0;
2009
2010 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2011 NULL,
2012 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2013 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2014
2015 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2016
2017 return ApiMessage.Data.ConsoleCPRequest.CodePage;
2018 }
2019
2020
2021 /*--------------------------------------------------------------
2022 * SetConsoleOutputCP
2023 *
2024 * @implemented
2025 */
2026 BOOL
2027 WINAPI
2028 SetConsoleOutputCP(UINT wCodePageID)
2029 {
2030 NTSTATUS Status;
2031 CONSOLE_API_MESSAGE ApiMessage;
2032
2033 /* Set the Output Code Page */
2034 ApiMessage.Data.ConsoleCPRequest.InputCP = FALSE;
2035 ApiMessage.Data.ConsoleCPRequest.CodePage = wCodePageID;
2036
2037 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2038 NULL,
2039 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2040 sizeof(CONSOLE_GETSETINPUTOUTPUTCP));
2041
2042 if (!NT_SUCCESS(Status)) BaseSetLastNTError(Status);
2043
2044 return NT_SUCCESS(Status);
2045 }
2046
2047
2048 /*--------------------------------------------------------------
2049 * GetConsoleProcessList
2050 *
2051 * @implemented
2052 */
2053 DWORD
2054 WINAPI
2055 GetConsoleProcessList(LPDWORD lpdwProcessList,
2056 DWORD dwProcessCount)
2057 {
2058 NTSTATUS Status;
2059 CONSOLE_API_MESSAGE ApiMessage;
2060 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2061 PCSR_CAPTURE_BUFFER CaptureBuffer;
2062 ULONG nProcesses;
2063
2064 if (lpdwProcessList == NULL || dwProcessCount == 0)
2065 {
2066 SetLastError(ERROR_INVALID_PARAMETER);
2067 return 0;
2068 }
2069
2070 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2071 if (CaptureBuffer == NULL)
2072 {
2073 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2074 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2075 return FALSE;
2076 }
2077
2078 GetProcessListRequest->nMaxIds = dwProcessCount;
2079
2080 CsrAllocateMessagePointer(CaptureBuffer,
2081 dwProcessCount * sizeof(DWORD),
2082 (PVOID*)&GetProcessListRequest->pProcessIds);
2083
2084 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2085 CaptureBuffer,
2086 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2087 sizeof(CONSOLE_GETPROCESSLIST));
2088 if (!NT_SUCCESS(Status))
2089 {
2090 BaseSetLastNTError (Status);
2091 nProcesses = 0;
2092 }
2093 else
2094 {
2095 nProcesses = GetProcessListRequest->nProcessIdsTotal;
2096 if (dwProcessCount >= nProcesses)
2097 {
2098 memcpy(lpdwProcessList, GetProcessListRequest->pProcessIds, nProcesses * sizeof(DWORD));
2099 }
2100 }
2101
2102 CsrFreeCaptureBuffer(CaptureBuffer);
2103 return nProcesses;
2104 }
2105
2106
2107 /*--------------------------------------------------------------
2108 * GetConsoleSelectionInfo
2109 *
2110 * @implemented
2111 */
2112 BOOL
2113 WINAPI
2114 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2115 {
2116 NTSTATUS Status;
2117 CONSOLE_API_MESSAGE ApiMessage;
2118
2119 if (lpConsoleSelectionInfo == NULL)
2120 {
2121 SetLastError(ERROR_INVALID_PARAMETER);
2122 return FALSE;
2123 }
2124
2125 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2126 NULL,
2127 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2128 sizeof(CONSOLE_GETSELECTIONINFO));
2129 if (!NT_SUCCESS(Status))
2130 {
2131 BaseSetLastNTError(Status);
2132 return FALSE;
2133 }
2134
2135 *lpConsoleSelectionInfo = ApiMessage.Data.GetSelectionInfoRequest.Info;
2136 return TRUE;
2137 }
2138
2139
2140 /*--------------------------------------------------------------
2141 * AttachConsole
2142 *
2143 * @implemented
2144 *
2145 * @note Strongly inspired by AllocConsole.
2146 */
2147 BOOL
2148 WINAPI
2149 AttachConsole(DWORD dwProcessId)
2150 {
2151 NTSTATUS Status;
2152 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2153 CONSOLE_API_MESSAGE ApiMessage;
2154 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2155
2156 if (Parameters->ConsoleHandle)
2157 {
2158 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2159 SetLastError(ERROR_ACCESS_DENIED);
2160 return FALSE;
2161 }
2162
2163 AttachConsoleRequest->ProcessId = dwProcessId;
2164 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2165 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2166
2167 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2168 NULL,
2169 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2170 sizeof(CONSOLE_ATTACHCONSOLE));
2171 if (!NT_SUCCESS(Status))
2172 {
2173 BaseSetLastNTError(Status);
2174 return FALSE;
2175 }
2176
2177 Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle;
2178 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2179 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2180 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2181
2182 /* Initialize Console Ctrl Handler */
2183 InitConsoleCtrlHandling();
2184
2185 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2186
2187 return TRUE;
2188 }
2189
2190
2191 /*--------------------------------------------------------------
2192 * GetConsoleWindow
2193 *
2194 * @implemented
2195 */
2196 HWND
2197 WINAPI
2198 GetConsoleWindow(VOID)
2199 {
2200 NTSTATUS Status;
2201 CONSOLE_API_MESSAGE ApiMessage;
2202
2203 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2204 NULL,
2205 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2206 sizeof(CONSOLE_GETWINDOW));
2207 if (!NT_SUCCESS(Status))
2208 {
2209 BaseSetLastNTError(Status);
2210 return (HWND)NULL;
2211 }
2212
2213 return ApiMessage.Data.GetWindowRequest.WindowHandle;
2214 }
2215
2216
2217 /*--------------------------------------------------------------
2218 * SetConsoleIcon
2219 *
2220 * @implemented
2221 */
2222 BOOL
2223 WINAPI
2224 SetConsoleIcon(HICON hicon)
2225 {
2226 NTSTATUS Status;
2227 CONSOLE_API_MESSAGE ApiMessage;
2228
2229 ApiMessage.Data.SetIconRequest.WindowIcon = hicon;
2230
2231 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2232 NULL,
2233 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2234 sizeof(CONSOLE_SETICON));
2235 if (!NT_SUCCESS(Status))
2236 {
2237 BaseSetLastNTError(Status);
2238 return FALSE;
2239 }
2240
2241 return NT_SUCCESS(Status);
2242 }
2243
2244
2245 /******************************************************************************
2246 * \name SetConsoleInputExeNameW
2247 * \brief Sets the console input file name from a unicode string.
2248 * \param lpInputExeName Pointer to a unicode string with the name.
2249 * \return TRUE if successful, FALSE if unsuccsedful.
2250 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2251 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2252 */
2253 BOOL
2254 WINAPI
2255 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2256 {
2257 int lenName;
2258
2259 if ( !lpInputExeName ||
2260 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2261 lenName > INPUTEXENAME_BUFLEN - 1 )
2262 {
2263 /* Fail if string is empty or too long */
2264 SetLastError(ERROR_INVALID_PARAMETER);
2265 return FALSE;
2266 }
2267
2268 RtlEnterCriticalSection(&ConsoleLock);
2269 _SEH2_TRY
2270 {
2271 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2272 InputExeName[lenName] = L'\0';
2273 }
2274 _SEH2_FINALLY
2275 {
2276 RtlLeaveCriticalSection(&ConsoleLock);
2277 }
2278 _SEH2_END;
2279
2280 return TRUE;
2281 }
2282
2283
2284 /******************************************************************************
2285 * \name SetConsoleInputExeNameA
2286 * \brief Sets the console input file name from an ansi string.
2287 * \param lpInputExeName Pointer to an ansi string with the name.
2288 * \return TRUE if successful, FALSE if unsuccsedful.
2289 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2290 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2291 */
2292 BOOL
2293 WINAPI
2294 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2295 {
2296 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2297 ANSI_STRING InputExeNameA;
2298 UNICODE_STRING InputExeNameU;
2299 NTSTATUS Status;
2300
2301 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2302
2303 if ( InputExeNameA.Length == 0 ||
2304 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2305 {
2306 /* Fail if string is empty or too long */
2307 SetLastError(ERROR_INVALID_PARAMETER);
2308 return FALSE;
2309 }
2310
2311 InputExeNameU.Buffer = Buffer;
2312 InputExeNameU.MaximumLength = sizeof(Buffer);
2313 InputExeNameU.Length = 0;
2314
2315 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2316 if (!NT_SUCCESS(Status))
2317 {
2318 BaseSetLastNTError(Status);
2319 return FALSE;
2320 }
2321
2322 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2323 }
2324
2325
2326 /******************************************************************************
2327 * \name GetConsoleInputExeNameW
2328 * \brief Retrieves the console input file name as unicode string.
2329 * \param nBufferLength Length of the buffer in WCHARs.
2330 * Specify 0 to receive the needed buffer length.
2331 * \param lpBuffer Pointer to a buffer that receives the string.
2332 * \return Needed buffer size if \p nBufferLength is 0.
2333 * Otherwise 1 if successful, 2 if buffer is too small.
2334 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2335 * is not big enough.
2336 */
2337 DWORD
2338 WINAPI
2339 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2340 {
2341 ULONG lenName = lstrlenW(InputExeName);
2342
2343 if (nBufferLength == 0)
2344 {
2345 /* Buffer size is requested, return it */
2346 return lenName + 1;
2347 }
2348
2349 if (lenName + 1 > nBufferLength)
2350 {
2351 /* Buffer is not large enough! */
2352 SetLastError(ERROR_BUFFER_OVERFLOW);
2353 return 2;
2354 }
2355
2356 RtlEnterCriticalSection(&ConsoleLock);
2357 _SEH2_TRY
2358 {
2359 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2360 lpBuffer[lenName] = '\0';
2361 }
2362 _SEH2_FINALLY
2363 {
2364 RtlLeaveCriticalSection(&ConsoleLock);
2365 }
2366 _SEH2_END;
2367
2368 /* Success, return 1 */
2369 return 1;
2370 }
2371
2372
2373 /******************************************************************************
2374 * \name GetConsoleInputExeNameA
2375 * \brief Retrieves the console input file name as ansi string.
2376 * \param nBufferLength Length of the buffer in CHARs.
2377 * \param lpBuffer Pointer to a buffer that receives the string.
2378 * \return 1 if successful, 2 if buffer is too small.
2379 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2380 * is not big enough. The buffer receives as much characters as fit.
2381 */
2382 DWORD
2383 WINAPI
2384 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2385 {
2386 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2387 DWORD Ret;
2388 UNICODE_STRING BufferU;
2389 ANSI_STRING BufferA;
2390
2391 /* Get the unicode name */
2392 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2393
2394 /* Initialize strings for conversion */
2395 RtlInitUnicodeString(&BufferU, Buffer);
2396 BufferA.Length = 0;
2397 BufferA.MaximumLength = (USHORT)nBufferLength;
2398 BufferA.Buffer = lpBuffer;
2399
2400 /* Convert unicode name to ansi, copying as much chars as fit */
2401 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2402
2403 /* Error handling */
2404 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2405 {
2406 SetLastError(ERROR_BUFFER_OVERFLOW);
2407 return 2;
2408 }
2409
2410 return Ret;
2411 }
2412
2413 BOOL
2414 WINAPI
2415 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2416 {
2417 STUB;
2418 return FALSE;
2419 }
2420
2421 BOOL
2422 WINAPI
2423 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2424 {
2425 STUB;
2426 return FALSE;
2427 }
2428
2429 BOOL
2430 WINAPI
2431 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2432 {
2433 STUB;
2434 return FALSE;
2435 }
2436
2437 BOOL
2438 WINAPI
2439 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2440 {
2441 STUB;
2442 return FALSE;
2443 }
2444
2445 BOOL
2446 WINAPI
2447 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2448 {
2449 STUB;
2450 return FALSE;
2451 }
2452
2453 BOOL
2454 WINAPI
2455 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2456 {
2457 STUB;
2458 return FALSE;
2459 }
2460
2461 BOOL
2462 WINAPI
2463 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2464 {
2465 STUB;
2466 return FALSE;
2467 }
2468
2469 BOOL
2470 WINAPI
2471 RegisterConsoleOS2(BOOL bUnknown)
2472 {
2473 STUB;
2474 return FALSE;
2475 }
2476
2477 BOOL
2478 WINAPI
2479 SetConsoleOS2OemFormat(BOOL bUnknown)
2480 {
2481 STUB;
2482 return FALSE;
2483 }
2484
2485 BOOL
2486 WINAPI
2487 UnregisterConsoleIME(VOID)
2488 {
2489 STUB;
2490 return FALSE;
2491 }
2492
2493
2494 /*
2495 * @unimplemented
2496 */
2497 BOOL WINAPI GetConsoleKeyboardLayoutNameA(LPSTR name)
2498 {
2499 STUB;
2500 return 0;
2501 }
2502
2503 /*
2504 * @unimplemented
2505 */
2506 BOOL WINAPI GetConsoleKeyboardLayoutNameW(LPWSTR name)
2507 {
2508 STUB;
2509 return 0;
2510 }
2511
2512 /*
2513 * @unimplemented
2514 */
2515 BOOL
2516 WINAPI
2517 SetLastConsoleEventActive(VOID)
2518 {
2519 STUB;
2520 return FALSE;
2521 }
2522
2523 /* EOF */