Sync with trunk r63887.
[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 BOOL LastCloseNotify = FALSE;
34
35 HANDLE InputWaitHandle = INVALID_HANDLE_VALUE;
36
37 #define INPUTEXENAME_BUFLEN 256
38 static WCHAR InputExeName[INPUTEXENAME_BUFLEN];
39
40
41 /* Default Console Control Handler ********************************************/
42
43 BOOL
44 WINAPI
45 DefaultConsoleCtrlHandler(DWORD Event)
46 {
47 DPRINT("Default handler called: %lx\n", Event);
48 switch(Event)
49 {
50 case CTRL_C_EVENT:
51 DPRINT("Ctrl-C Event\n");
52 break;
53
54 case CTRL_BREAK_EVENT:
55 DPRINT("Ctrl-Break Event\n");
56 break;
57
58 case CTRL_CLOSE_EVENT:
59 DPRINT("Ctrl Close Event\n");
60 break;
61
62 case CTRL_LAST_CLOSE_EVENT:
63 DPRINT("Ctrl Last Close Event\n");
64 break;
65
66 case CTRL_LOGOFF_EVENT:
67 DPRINT("Ctrl Logoff Event\n");
68 break;
69
70 case CTRL_SHUTDOWN_EVENT:
71 DPRINT("Ctrl Shutdown Event\n");
72 break;
73 }
74
75 ExitProcess(CONTROL_C_EXIT);
76 return TRUE;
77 }
78
79 DWORD
80 WINAPI
81 ConsoleControlDispatcher(IN LPVOID lpThreadParameter)
82 {
83 DWORD nExitCode = 0;
84 DWORD CodeAndFlag = PtrToUlong(lpThreadParameter);
85 DWORD nCode = CodeAndFlag & MAXLONG;
86 UINT i;
87 EXCEPTION_RECORD erException;
88
89 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode);
90 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
91
92 switch(nCode)
93 {
94 case CTRL_C_EVENT:
95 case CTRL_BREAK_EVENT:
96 {
97 if (IsDebuggerPresent())
98 {
99 erException.ExceptionCode = (nCode == CTRL_C_EVENT ?
100 DBG_CONTROL_C : DBG_CONTROL_BREAK);
101 erException.ExceptionFlags = 0;
102 erException.ExceptionRecord = NULL;
103 erException.ExceptionAddress = DefaultConsoleCtrlHandler;
104 erException.NumberParameters = 0;
105
106 _SEH2_TRY
107 {
108 RtlRaiseException(&erException);
109 }
110 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
111 {
112 RtlEnterCriticalSection(&ConsoleLock);
113
114 if ((nCode != CTRL_C_EVENT) ||
115 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
116 {
117 for (i = NrCtrlHandlers; i > 0; i--)
118 {
119 if (CtrlHandlers[i - 1](nCode)) break;
120 }
121 }
122
123 RtlLeaveCriticalSection(&ConsoleLock);
124 }
125 _SEH2_END;
126
127 ExitThread(0);
128 }
129 break;
130 }
131
132 case CTRL_CLOSE_EVENT:
133 case CTRL_LOGOFF_EVENT:
134 case CTRL_SHUTDOWN_EVENT:
135 break;
136
137 case CTRL_LAST_CLOSE_EVENT:
138 /*
139 * In case the console app hasn't register for last close notification,
140 * just kill this console handler thread. We don't want that such apps
141 * get killed for unexpected reasons. On the contrary apps that registered
142 * can be killed because they expect to be.
143 */
144 if (!LastCloseNotify) ExitThread(0);
145 break;
146
147 case 4:
148 ExitProcess(CONTROL_C_EXIT);
149 break;
150
151 default:
152 ASSERT(FALSE);
153 break;
154 }
155
156 ASSERT(ConsoleInitialized);
157
158 RtlEnterCriticalSection(&ConsoleLock);
159
160 nExitCode = 0;
161 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1))
162 {
163 for (i = NrCtrlHandlers; i > 0; i--)
164 {
165 if ((i == 1) &&
166 (CodeAndFlag & MINLONG) &&
167 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT)))
168 {
169 DPRINT("Skipping system/service apps\n");
170 break;
171 }
172
173 if (CtrlHandlers[i - 1](nCode))
174 {
175 switch(nCode)
176 {
177 case CTRL_CLOSE_EVENT:
178 case CTRL_LAST_CLOSE_EVENT:
179 case CTRL_LOGOFF_EVENT:
180 case CTRL_SHUTDOWN_EVENT:
181 nExitCode = CodeAndFlag;
182 break;
183 }
184 break;
185 }
186 }
187 }
188
189 RtlLeaveCriticalSection(&ConsoleLock);
190
191 ExitThread(nExitCode);
192 return STATUS_SUCCESS;
193 }
194
195 VOID
196 WINAPI
197 InitConsoleCtrlHandling(VOID)
198 {
199 /* Initialize Console Ctrl Handler */
200 NrAllocatedHandlers = NrCtrlHandlers = 1;
201 CtrlHandlers = InitialHandler;
202 CtrlHandlers[0] = DefaultConsoleCtrlHandler;
203 }
204
205
206 /* FUNCTIONS ******************************************************************/
207
208 LPCWSTR
209 IntCheckForConsoleFileName(IN LPCWSTR pszName,
210 IN DWORD dwDesiredAccess)
211 {
212 LPCWSTR ConsoleName = pszName;
213 ULONG DeviceNameInfo;
214
215 /*
216 * Check whether we deal with a DOS device, and if so,
217 * strip the path till the file name.
218 * Therefore, things like \\.\CON or C:\some_path\CONIN$
219 * are transformed into CON or CONIN$, for example.
220 */
221 DeviceNameInfo = RtlIsDosDeviceName_U(pszName);
222 if (DeviceNameInfo != 0)
223 {
224 ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF));
225 }
226
227 /* Return a standard console "file" name according to what we passed in parameters */
228 if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0)
229 {
230 return BaseConInputFileName;
231 }
232 else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0)
233 {
234 return BaseConOutputFileName;
235 }
236 else if (_wcsicmp(ConsoleName, BaseConFileName) == 0)
237 {
238 if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ)
239 {
240 return BaseConInputFileName;
241 }
242 else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE)
243 {
244 return BaseConOutputFileName;
245 }
246 }
247
248 /* If we are there, that means that either the file name or the desired access are wrong */
249 return NULL;
250 }
251
252
253 /*
254 * @implemented (Undocumented)
255 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php
256 */
257 HMENU
258 WINAPI
259 ConsoleMenuControl(HANDLE hConsoleOutput,
260 DWORD dwCmdIdLow,
261 DWORD dwCmdIdHigh)
262 {
263 CONSOLE_API_MESSAGE ApiMessage;
264 PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest;
265
266 MenuControlRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
267 MenuControlRequest->OutputHandle = hConsoleOutput;
268 MenuControlRequest->CmdIdLow = dwCmdIdLow;
269 MenuControlRequest->CmdIdHigh = dwCmdIdHigh;
270 MenuControlRequest->MenuHandle = NULL;
271
272 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
273 NULL,
274 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepMenuControl),
275 sizeof(*MenuControlRequest));
276
277 return MenuControlRequest->MenuHandle;
278 }
279
280
281 /*
282 * @implemented
283 */
284 HANDLE
285 WINAPI
286 DuplicateConsoleHandle(HANDLE hConsole,
287 DWORD dwDesiredAccess,
288 BOOL bInheritHandle,
289 DWORD dwOptions)
290 {
291 CONSOLE_API_MESSAGE ApiMessage;
292 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest;
293
294 if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) ||
295 (!(dwOptions & DUPLICATE_SAME_ACCESS) &&
296 (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) )
297 {
298 SetLastError(ERROR_INVALID_PARAMETER);
299 return INVALID_HANDLE_VALUE;
300 }
301
302 DuplicateHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
303 DuplicateHandleRequest->SourceHandle = hConsole;
304 DuplicateHandleRequest->DesiredAccess = dwDesiredAccess;
305 DuplicateHandleRequest->InheritHandle = bInheritHandle;
306 DuplicateHandleRequest->Options = dwOptions;
307
308 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
309 NULL,
310 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle),
311 sizeof(*DuplicateHandleRequest));
312 if (!NT_SUCCESS(ApiMessage.Status))
313 {
314 BaseSetLastNTError(ApiMessage.Status);
315 return INVALID_HANDLE_VALUE;
316 }
317
318 return DuplicateHandleRequest->TargetHandle;
319 }
320
321
322 /*
323 * @implemented
324 */
325 BOOL
326 WINAPI
327 GetConsoleHandleInformation(IN HANDLE hHandle,
328 OUT LPDWORD lpdwFlags)
329 {
330 CONSOLE_API_MESSAGE ApiMessage;
331 PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &ApiMessage.Data.GetHandleInfoRequest;
332
333 GetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
334 GetHandleInfoRequest->Handle = hHandle;
335
336 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
337 NULL,
338 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHandleInformation),
339 sizeof(*GetHandleInfoRequest));
340 if (!NT_SUCCESS(ApiMessage.Status))
341 {
342 BaseSetLastNTError(ApiMessage.Status);
343 return FALSE;
344 }
345
346 *lpdwFlags = GetHandleInfoRequest->Flags;
347
348 return TRUE;
349 }
350
351
352 /*
353 * @implemented
354 */
355 BOOL
356 WINAPI
357 SetConsoleHandleInformation(IN HANDLE hHandle,
358 IN DWORD dwMask,
359 IN DWORD dwFlags)
360 {
361 CONSOLE_API_MESSAGE ApiMessage;
362 PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &ApiMessage.Data.SetHandleInfoRequest;
363
364 SetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
365 SetHandleInfoRequest->Handle = hHandle;
366 SetHandleInfoRequest->Mask = dwMask;
367 SetHandleInfoRequest->Flags = dwFlags;
368
369 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
370 NULL,
371 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHandleInformation),
372 sizeof(*SetHandleInfoRequest));
373 if (!NT_SUCCESS(ApiMessage.Status))
374 {
375 BaseSetLastNTError(ApiMessage.Status);
376 return FALSE;
377 }
378
379 return TRUE;
380 }
381
382
383 /*
384 * @implemented
385 */
386 BOOL
387 WINAPI
388 GetConsoleDisplayMode(LPDWORD lpModeFlags)
389 {
390 CONSOLE_API_MESSAGE ApiMessage;
391 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest;
392
393 if (lpModeFlags == NULL)
394 {
395 SetLastError(ERROR_INVALID_PARAMETER);
396 return FALSE;
397 }
398
399 GetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
400
401 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
402 NULL,
403 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode),
404 sizeof(*GetDisplayModeRequest));
405 if (!NT_SUCCESS(ApiMessage.Status))
406 {
407 BaseSetLastNTError(ApiMessage.Status);
408 return FALSE;
409 }
410
411 *lpModeFlags = GetDisplayModeRequest->DisplayMode; // ModeFlags
412
413 return TRUE;
414 }
415
416
417 /*
418 * @unimplemented (Undocumented)
419 */
420 DWORD
421 WINAPI
422 GetConsoleFontInfo(HANDLE hConsoleOutput,
423 BOOL bMaximumWindow,
424 DWORD nFontCount,
425 PCONSOLE_FONT_INFO lpConsoleFontInfo)
426 {
427 DPRINT1("GetConsoleFontInfo(0x%p, %d, %lu, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, nFontCount, lpConsoleFontInfo);
428 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
429 return 0;
430 }
431
432
433 /*
434 * @unimplemented
435 */
436 COORD
437 WINAPI
438 GetConsoleFontSize(HANDLE hConsoleOutput,
439 DWORD nFont)
440 {
441 COORD Empty = {0, 0};
442 DPRINT1("GetConsoleFontSize(0x%p, 0x%x) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
443 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
444 return Empty;
445 }
446
447
448 /*
449 * @implemented (Undocumented)
450 */
451 BOOL
452 WINAPI
453 GetConsoleHardwareState(HANDLE hConsoleOutput,
454 PDWORD Flags,
455 PDWORD State)
456 {
457 CONSOLE_API_MESSAGE ApiMessage;
458 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
459
460 DPRINT1("GetConsoleHardwareState(%lu, 0x%p) UNIMPLEMENTED!\n", Flags, State);
461
462 if (Flags == NULL || State == NULL)
463 {
464 SetLastError(ERROR_INVALID_PARAMETER);
465 return FALSE;
466 }
467
468 HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
469 HardwareStateRequest->OutputHandle = hConsoleOutput;
470
471 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
472 NULL,
473 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState),
474 sizeof(*HardwareStateRequest));
475 if (!NT_SUCCESS(ApiMessage.Status))
476 {
477 BaseSetLastNTError(ApiMessage.Status);
478 return FALSE;
479 }
480
481 *Flags = HardwareStateRequest->Flags;
482 *State = HardwareStateRequest->State;
483
484 return TRUE;
485 }
486
487
488 /*
489 * @implemented (Undocumented)
490 */
491 HANDLE
492 WINAPI
493 GetConsoleInputWaitHandle(VOID)
494 {
495 return InputWaitHandle;
496 }
497
498
499 /*
500 * @unimplemented
501 */
502 BOOL
503 WINAPI
504 GetCurrentConsoleFont(HANDLE hConsoleOutput,
505 BOOL bMaximumWindow,
506 PCONSOLE_FONT_INFO lpConsoleCurrentFont)
507 {
508 DPRINT1("GetCurrentConsoleFont(0x%p, 0x%x, 0x%p) UNIMPLEMENTED!\n", hConsoleOutput, bMaximumWindow, lpConsoleCurrentFont);
509 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
510 return 0;
511 }
512
513
514 /*
515 * @unimplemented (Undocumented)
516 */
517 ULONG
518 WINAPI
519 GetNumberOfConsoleFonts(VOID)
520 {
521 DPRINT1("GetNumberOfConsoleFonts() UNIMPLEMENTED!\n");
522 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
523 return 1;
524 }
525
526
527 /*
528 * @implemented (Undocumented)
529 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/
530 */
531 BOOL
532 WINAPI
533 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,
534 IN PSMALL_RECT lpRect)
535 {
536 CONSOLE_API_MESSAGE ApiMessage;
537 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest;
538
539 if (lpRect == NULL)
540 {
541 SetLastError(ERROR_INVALID_PARAMETER);
542 return FALSE;
543 }
544
545 InvalidateDIBitsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
546 InvalidateDIBitsRequest->OutputHandle = hConsoleOutput;
547 InvalidateDIBitsRequest->Region = *lpRect;
548
549 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
550 NULL,
551 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect),
552 sizeof(*InvalidateDIBitsRequest));
553 if (!NT_SUCCESS(ApiMessage.Status))
554 {
555 BaseSetLastNTError(ApiMessage.Status);
556 return FALSE;
557 }
558
559 return TRUE;
560 }
561
562
563 /*
564 * @implemented (Undocumented)
565 */
566 HANDLE
567 WINAPI
568 OpenConsoleW(LPCWSTR wsName,
569 DWORD dwDesiredAccess,
570 BOOL bInheritHandle,
571 DWORD dwShareMode)
572 {
573 CONSOLE_API_MESSAGE ApiMessage;
574 PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest;
575 CONSOLE_HANDLE_TYPE HandleType;
576
577 if (wsName && (_wcsicmp(wsName, BaseConInputFileName) == 0))
578 {
579 HandleType = HANDLE_INPUT;
580 }
581 else if (wsName && (_wcsicmp(wsName, BaseConOutputFileName) == 0))
582 {
583 HandleType = HANDLE_OUTPUT;
584 }
585 else
586 {
587 SetLastError(ERROR_INVALID_PARAMETER);
588 return INVALID_HANDLE_VALUE;
589 }
590
591 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
592 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) )
593 {
594 SetLastError(ERROR_INVALID_PARAMETER);
595 return INVALID_HANDLE_VALUE;
596 }
597
598 OpenConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
599 OpenConsoleRequest->HandleType = HandleType;
600 OpenConsoleRequest->DesiredAccess = dwDesiredAccess;
601 OpenConsoleRequest->InheritHandle = bInheritHandle;
602 OpenConsoleRequest->ShareMode = dwShareMode;
603
604 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
605 NULL,
606 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole),
607 sizeof(*OpenConsoleRequest));
608 if (!NT_SUCCESS(ApiMessage.Status))
609 {
610 BaseSetLastNTError(ApiMessage.Status);
611 return INVALID_HANDLE_VALUE;
612 }
613
614 return OpenConsoleRequest->Handle;
615 }
616
617
618 /*
619 * @implemented (Undocumented)
620 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleCursor.php
621 */
622 BOOL
623 WINAPI
624 SetConsoleCursor(HANDLE hConsoleOutput,
625 HCURSOR hCursor)
626 {
627 CONSOLE_API_MESSAGE ApiMessage;
628 PCONSOLE_SETCURSOR SetCursorRequest = &ApiMessage.Data.SetCursorRequest;
629
630 SetCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
631 SetCursorRequest->OutputHandle = hConsoleOutput;
632 SetCursorRequest->CursorHandle = hCursor;
633
634 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
635 NULL,
636 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursor),
637 sizeof(*SetCursorRequest));
638 if (!NT_SUCCESS(ApiMessage.Status))
639 {
640 BaseSetLastNTError(ApiMessage.Status);
641 return FALSE;
642 }
643
644 return TRUE;
645 }
646
647
648 /*
649 * @implemented
650 */
651 BOOL
652 WINAPI
653 SetConsoleDisplayMode(HANDLE hConsoleOutput,
654 DWORD dwFlags, // dwModeFlags
655 PCOORD lpNewScreenBufferDimensions)
656 {
657 CONSOLE_API_MESSAGE ApiMessage;
658 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest;
659
660 SetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
661 SetDisplayModeRequest->OutputHandle = hConsoleOutput;
662 SetDisplayModeRequest->DisplayMode = dwFlags; // ModeFlags ; dwModeFlags
663 SetDisplayModeRequest->NewSBDim.X = 0;
664 SetDisplayModeRequest->NewSBDim.Y = 0;
665 /* SetDisplayModeRequest->EventHandle; */
666
667 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
668 NULL,
669 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode),
670 sizeof(*SetDisplayModeRequest));
671 if (!NT_SUCCESS(ApiMessage.Status))
672 {
673 BaseSetLastNTError(ApiMessage.Status);
674 return FALSE;
675 }
676
677 if (lpNewScreenBufferDimensions)
678 *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim;
679
680 return TRUE;
681 }
682
683
684 /*
685 * @unimplemented (Undocumented)
686 */
687 BOOL
688 WINAPI
689 SetConsoleFont(HANDLE hConsoleOutput,
690 DWORD nFont)
691 {
692 DPRINT1("SetConsoleFont(0x%p, %lu) UNIMPLEMENTED!\n", hConsoleOutput, nFont);
693 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
694 return FALSE;
695 }
696
697
698 /*
699 * @implemented (Undocumented)
700 */
701 BOOL
702 WINAPI
703 SetConsoleHardwareState(HANDLE hConsoleOutput,
704 DWORD Flags,
705 DWORD State)
706 {
707 CONSOLE_API_MESSAGE ApiMessage;
708 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest;
709
710 DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags, State);
711
712 HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
713 HardwareStateRequest->OutputHandle = hConsoleOutput;
714 HardwareStateRequest->Flags = Flags;
715 HardwareStateRequest->State = State;
716
717 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
718 NULL,
719 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState),
720 sizeof(*HardwareStateRequest));
721 if (!NT_SUCCESS(ApiMessage.Status))
722 {
723 BaseSetLastNTError(ApiMessage.Status);
724 return FALSE;
725 }
726
727 return TRUE;
728 }
729
730
731 /*
732 * @unimplemented (Undocumented)
733 */
734 BOOL
735 WINAPI
736 SetConsoleKeyShortcuts(DWORD Unknown0,
737 DWORD Unknown1,
738 DWORD Unknown2,
739 DWORD Unknown3)
740 {
741 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3);
742 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
743 return FALSE;
744 }
745
746
747 /*
748 * @implemented (Undocumented)
749 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php
750 * Does nothing, returns TRUE only. Checked on Windows Server 2003.
751 */
752 BOOL
753 WINAPI
754 SetConsoleMaximumWindowSize(HANDLE hConsoleOutput,
755 COORD dwMaximumSize)
756 {
757 DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n",
758 hConsoleOutput, dwMaximumSize.X, dwMaximumSize.Y);
759 return TRUE;
760 }
761
762
763 /*
764 * @implemented (Undocumented)
765 */
766 BOOL
767 WINAPI
768 SetConsoleMenuClose(BOOL bEnable)
769 {
770 CONSOLE_API_MESSAGE ApiMessage;
771 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest;
772
773 SetMenuCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
774 SetMenuCloseRequest->Enable = bEnable;
775
776 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
777 NULL,
778 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose),
779 sizeof(*SetMenuCloseRequest));
780 if (!NT_SUCCESS(ApiMessage.Status))
781 {
782 BaseSetLastNTError(ApiMessage.Status);
783 return FALSE;
784 }
785
786 return TRUE;
787 }
788
789
790 /*
791 * @implemented (Undocumented)
792 * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844
793 * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52
794 */
795 BOOL
796 WINAPI
797 SetConsolePalette(HANDLE hConsoleOutput,
798 HPALETTE hPalette,
799 UINT dwUsage)
800 {
801 CONSOLE_API_MESSAGE ApiMessage;
802 PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest;
803
804 SetPaletteRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
805 SetPaletteRequest->OutputHandle = hConsoleOutput;
806 SetPaletteRequest->PaletteHandle = hPalette;
807 SetPaletteRequest->Usage = dwUsage;
808
809 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
810 NULL,
811 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetPalette),
812 sizeof(*SetPaletteRequest));
813 if (!NT_SUCCESS(ApiMessage.Status))
814 {
815 BaseSetLastNTError(ApiMessage.Status);
816 return FALSE;
817 }
818
819 return TRUE;
820 }
821
822 /*
823 * @implemented (Undocumented)
824 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php
825 */
826 INT
827 WINAPI
828 ShowConsoleCursor(HANDLE hConsoleOutput,
829 BOOL bShow)
830 {
831 CONSOLE_API_MESSAGE ApiMessage;
832 PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest;
833
834 ShowCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
835 ShowCursorRequest->OutputHandle = hConsoleOutput;
836 ShowCursorRequest->Show = bShow;
837 ShowCursorRequest->RefCount = 0;
838
839 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
840 NULL,
841 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepShowCursor),
842 sizeof(*ShowCursorRequest));
843
844 return ShowCursorRequest->RefCount;
845 }
846
847
848 /*
849 * FUNCTION: Checks whether the given handle is a valid console handle.
850 *
851 * ARGUMENTS:
852 * hIoHandle - Handle to be checked.
853 *
854 * RETURNS:
855 * TRUE : Handle is a valid console handle.
856 * FALSE: Handle is not a valid console handle.
857 *
858 * STATUS: Officially undocumented
859 *
860 * @implemented
861 */
862 BOOL
863 WINAPI
864 VerifyConsoleIoHandle(HANDLE hIoHandle)
865 {
866 CONSOLE_API_MESSAGE ApiMessage;
867 PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &ApiMessage.Data.VerifyHandleRequest;
868
869 VerifyHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
870 VerifyHandleRequest->Handle = hIoHandle;
871 VerifyHandleRequest->IsValid = FALSE;
872
873 /* If the process is not attached to a console, return invalid handle */
874 if (VerifyHandleRequest->ConsoleHandle == NULL) return FALSE;
875
876 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
877 NULL,
878 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle),
879 sizeof(*VerifyHandleRequest));
880 if (!NT_SUCCESS(ApiMessage.Status))
881 {
882 BaseSetLastNTError(ApiMessage.Status);
883 return FALSE;
884 }
885
886 return VerifyHandleRequest->IsValid;
887 }
888
889
890 /*
891 * @implemented (Undocumented)
892 */
893 BOOL
894 WINAPI
895 CloseConsoleHandle(HANDLE hHandle)
896 {
897 CONSOLE_API_MESSAGE ApiMessage;
898 PCONSOLE_CLOSEHANDLE CloseHandleRequest = &ApiMessage.Data.CloseHandleRequest;
899
900 CloseHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
901 CloseHandleRequest->Handle = hHandle;
902
903 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
904 NULL,
905 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle),
906 sizeof(*CloseHandleRequest));
907 if (!NT_SUCCESS(ApiMessage.Status))
908 {
909 BaseSetLastNTError(ApiMessage.Status);
910 return FALSE;
911 }
912
913 return TRUE;
914 }
915
916
917 /*
918 * @implemented
919 */
920 HANDLE
921 WINAPI
922 GetStdHandle(DWORD nStdHandle)
923 /*
924 * FUNCTION: Get a handle for the standard input, standard output
925 * and a standard error device.
926 *
927 * ARGUMENTS:
928 * nStdHandle - Specifies the device for which to return the handle.
929 *
930 * RETURNS: If the function succeeds, the return value is the handle
931 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE.
932 */
933 {
934 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
935 HANDLE Handle = INVALID_HANDLE_VALUE;
936
937 switch (nStdHandle)
938 {
939 case STD_INPUT_HANDLE:
940 Handle = Ppb->StandardInput;
941 break;
942
943 case STD_OUTPUT_HANDLE:
944 Handle = Ppb->StandardOutput;
945 break;
946
947 case STD_ERROR_HANDLE:
948 Handle = Ppb->StandardError;
949 break;
950 }
951
952 /* If the returned handle is invalid, set last error */
953 if (Handle == INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE);
954
955 return Handle;
956 }
957
958
959 /*
960 * @implemented
961 */
962 BOOL
963 WINAPI
964 SetStdHandle(DWORD nStdHandle,
965 HANDLE hHandle)
966 /*
967 * FUNCTION: Set the handle for the standard input, standard output or
968 * the standard error device.
969 *
970 * ARGUMENTS:
971 * nStdHandle - Specifies the handle to be set.
972 * hHandle - The handle to set.
973 *
974 * RETURNS: TRUE if the function succeeds, FALSE otherwise.
975 */
976 {
977 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters;
978
979 /* No need to check if hHandle == INVALID_HANDLE_VALUE */
980
981 switch (nStdHandle)
982 {
983 case STD_INPUT_HANDLE:
984 Ppb->StandardInput = hHandle;
985 return TRUE;
986
987 case STD_OUTPUT_HANDLE:
988 Ppb->StandardOutput = hHandle;
989 return TRUE;
990
991 case STD_ERROR_HANDLE:
992 Ppb->StandardError = hHandle;
993 return TRUE;
994 }
995
996 /* nStdHandle was invalid, bail out */
997 SetLastError(ERROR_INVALID_HANDLE);
998 return FALSE;
999 }
1000
1001
1002 /*--------------------------------------------------------------
1003 * AllocConsole
1004 *
1005 * @implemented
1006 */
1007 BOOL
1008 WINAPI
1009 AllocConsole(VOID)
1010 {
1011 NTSTATUS Status;
1012 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
1013 CONSOLE_API_MESSAGE ApiMessage;
1014 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest;
1015 PCSR_CAPTURE_BUFFER CaptureBuffer;
1016
1017 if (Parameters->ConsoleHandle)
1018 {
1019 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
1020 SetLastError(ERROR_ACCESS_DENIED);
1021 return FALSE;
1022 }
1023
1024 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
1025 if (CaptureBuffer == NULL)
1026 {
1027 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1028 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1029 return FALSE;
1030 }
1031
1032 CsrAllocateMessagePointer(CaptureBuffer,
1033 sizeof(CONSOLE_START_INFO),
1034 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo);
1035
1036 InitConsoleInfo(AllocConsoleRequest->ConsoleStartInfo,
1037 &Parameters->ImagePathName);
1038
1039 AllocConsoleRequest->ConsoleHandle = NULL;
1040 AllocConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
1041 AllocConsoleRequest->PropDispatcher = PropDialogHandler;
1042
1043 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1044 CaptureBuffer,
1045 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc),
1046 sizeof(CONSOLE_ALLOCCONSOLE));
1047
1048 CsrFreeCaptureBuffer(CaptureBuffer);
1049
1050 if (!NT_SUCCESS(Status))
1051 {
1052 BaseSetLastNTError(Status);
1053 return FALSE;
1054 }
1055
1056 Parameters->ConsoleHandle = AllocConsoleRequest->ConsoleHandle;
1057 SetStdHandle(STD_INPUT_HANDLE , AllocConsoleRequest->InputHandle );
1058 SetStdHandle(STD_OUTPUT_HANDLE, AllocConsoleRequest->OutputHandle);
1059 SetStdHandle(STD_ERROR_HANDLE , AllocConsoleRequest->ErrorHandle );
1060
1061 /* Initialize Console Ctrl Handler */
1062 InitConsoleCtrlHandling();
1063
1064 InputWaitHandle = AllocConsoleRequest->InputWaitHandle;
1065
1066 return TRUE;
1067 }
1068
1069
1070 /*--------------------------------------------------------------
1071 * FreeConsole
1072 *
1073 * @implemented
1074 */
1075 BOOL
1076 WINAPI
1077 FreeConsole(VOID)
1078 {
1079 CONSOLE_API_MESSAGE ApiMessage;
1080 PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest;
1081 HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1082
1083 /* We must have a non-trivial handle to close */
1084 if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle)
1085 {
1086 SetLastError(ERROR_INVALID_PARAMETER);
1087 return FALSE;
1088 }
1089
1090 /* Set up the data to send to the Console Server */
1091 FreeConsoleRequest->ConsoleHandle = ConsoleHandle;
1092
1093 /* Call the server */
1094 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1095 NULL,
1096 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
1097 sizeof(*FreeConsoleRequest));
1098
1099 /* Check for success */
1100 if (!NT_SUCCESS(ApiMessage.Status))
1101 {
1102 BaseSetLastNTError(ApiMessage.Status);
1103 return FALSE;
1104 }
1105
1106 /* Reset the console handle */
1107 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1108
1109 /* Close the associated input handle */
1110 CloseHandle(InputWaitHandle);
1111 InputWaitHandle = INVALID_HANDLE_VALUE;
1112
1113 return TRUE;
1114 }
1115
1116
1117 /*--------------------------------------------------------------
1118 * GetConsoleScreenBufferInfo
1119 *
1120 * @implemented
1121 */
1122 BOOL
1123 WINAPI
1124 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1125 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1126 {
1127 CONSOLE_API_MESSAGE ApiMessage;
1128 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &ApiMessage.Data.ScreenBufferInfoRequest;
1129
1130 if (lpConsoleScreenBufferInfo == NULL)
1131 {
1132 SetLastError(ERROR_INVALID_PARAMETER);
1133 return FALSE;
1134 }
1135
1136 ScreenBufferInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1137 ScreenBufferInfoRequest->OutputHandle = hConsoleOutput;
1138
1139 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1140 NULL,
1141 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1142 sizeof(*ScreenBufferInfoRequest));
1143 if (!NT_SUCCESS(ApiMessage.Status))
1144 {
1145 BaseSetLastNTError(ApiMessage.Status);
1146 return FALSE;
1147 }
1148
1149 lpConsoleScreenBufferInfo->dwSize = ScreenBufferInfoRequest->ScreenBufferSize;
1150 lpConsoleScreenBufferInfo->dwCursorPosition = ScreenBufferInfoRequest->CursorPosition;
1151 lpConsoleScreenBufferInfo->wAttributes = ScreenBufferInfoRequest->Attributes;
1152 lpConsoleScreenBufferInfo->srWindow.Left = ScreenBufferInfoRequest->ViewOrigin.X;
1153 lpConsoleScreenBufferInfo->srWindow.Top = ScreenBufferInfoRequest->ViewOrigin.Y;
1154 lpConsoleScreenBufferInfo->srWindow.Right = ScreenBufferInfoRequest->ViewOrigin.X + ScreenBufferInfoRequest->ViewSize.X - 1;
1155 lpConsoleScreenBufferInfo->srWindow.Bottom = ScreenBufferInfoRequest->ViewOrigin.Y + ScreenBufferInfoRequest->ViewSize.Y - 1;
1156 lpConsoleScreenBufferInfo->dwMaximumWindowSize = ScreenBufferInfoRequest->MaximumViewSize;
1157
1158 return TRUE;
1159 }
1160
1161
1162 /*--------------------------------------------------------------
1163 * SetConsoleCursorPosition
1164 *
1165 * @implemented
1166 */
1167 BOOL
1168 WINAPI
1169 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1170 COORD dwCursorPosition)
1171 {
1172 CONSOLE_API_MESSAGE ApiMessage;
1173 PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &ApiMessage.Data.SetCursorPositionRequest;
1174
1175 SetCursorPositionRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1176 SetCursorPositionRequest->OutputHandle = hConsoleOutput;
1177 SetCursorPositionRequest->Position = dwCursorPosition;
1178
1179 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1180 NULL,
1181 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1182 sizeof(*SetCursorPositionRequest));
1183 if (!NT_SUCCESS(ApiMessage.Status))
1184 {
1185 BaseSetLastNTError(ApiMessage.Status);
1186 return FALSE;
1187 }
1188
1189 return TRUE;
1190 }
1191
1192
1193 /*--------------------------------------------------------------
1194 * GetConsoleMode
1195 *
1196 * @implemented
1197 */
1198 BOOL
1199 WINAPI
1200 GetConsoleMode(HANDLE hConsoleHandle,
1201 LPDWORD lpMode)
1202 {
1203 CONSOLE_API_MESSAGE ApiMessage;
1204 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1205
1206 if (lpMode == NULL)
1207 {
1208 SetLastError(ERROR_INVALID_PARAMETER);
1209 return FALSE;
1210 }
1211
1212 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1213 ConsoleModeRequest->Handle = hConsoleHandle;
1214
1215 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1216 NULL,
1217 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1218 sizeof(*ConsoleModeRequest));
1219 if (!NT_SUCCESS(ApiMessage.Status))
1220 {
1221 BaseSetLastNTError(ApiMessage.Status);
1222 return FALSE;
1223 }
1224
1225 *lpMode = ConsoleModeRequest->Mode;
1226
1227 return TRUE;
1228 }
1229
1230
1231 /*--------------------------------------------------------------
1232 * SetConsoleMode
1233 *
1234 * @implemented
1235 */
1236 BOOL
1237 WINAPI
1238 SetConsoleMode(HANDLE hConsoleHandle,
1239 DWORD dwMode)
1240 {
1241 CONSOLE_API_MESSAGE ApiMessage;
1242 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1243
1244 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1245 ConsoleModeRequest->Handle = hConsoleHandle;
1246 ConsoleModeRequest->Mode = dwMode;
1247
1248 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1249 NULL,
1250 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1251 sizeof(*ConsoleModeRequest));
1252 if (!NT_SUCCESS(ApiMessage.Status))
1253 {
1254 BaseSetLastNTError(ApiMessage.Status);
1255 return FALSE;
1256 }
1257
1258 return TRUE;
1259 }
1260
1261
1262 /*--------------------------------------------------------------
1263 * GetNumberOfConsoleInputEvents
1264 *
1265 * @implemented
1266 */
1267 BOOL
1268 WINAPI
1269 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1270 LPDWORD lpNumberOfEvents)
1271 {
1272 CONSOLE_API_MESSAGE ApiMessage;
1273 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1274
1275 GetNumInputEventsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1276 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1277 GetNumInputEventsRequest->NumberOfEvents = 0;
1278
1279 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1280 NULL,
1281 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1282 sizeof(*GetNumInputEventsRequest));
1283 if (!NT_SUCCESS(ApiMessage.Status))
1284 {
1285 BaseSetLastNTError(ApiMessage.Status);
1286 return FALSE;
1287 }
1288
1289 if (lpNumberOfEvents == NULL)
1290 {
1291 SetLastError(ERROR_INVALID_ACCESS);
1292 return FALSE;
1293 }
1294
1295 *lpNumberOfEvents = GetNumInputEventsRequest->NumberOfEvents;
1296
1297 return TRUE;
1298 }
1299
1300
1301 /*--------------------------------------------------------------
1302 * GetLargestConsoleWindowSize
1303 *
1304 * @implemented
1305 */
1306 COORD
1307 WINAPI
1308 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1309 {
1310 CONSOLE_API_MESSAGE ApiMessage;
1311 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1312
1313 GetLargestWindowSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1314 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1315 GetLargestWindowSizeRequest->Size.X = 0;
1316 GetLargestWindowSizeRequest->Size.Y = 0;
1317
1318 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1319 NULL,
1320 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1321 sizeof(*GetLargestWindowSizeRequest));
1322 if (!NT_SUCCESS(ApiMessage.Status))
1323 {
1324 BaseSetLastNTError(ApiMessage.Status);
1325 }
1326
1327 DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1328 return GetLargestWindowSizeRequest->Size;
1329 }
1330
1331
1332 /*--------------------------------------------------------------
1333 * GetConsoleCursorInfo
1334 *
1335 * @implemented
1336 */
1337 BOOL
1338 WINAPI
1339 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1340 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1341 {
1342 CONSOLE_API_MESSAGE ApiMessage;
1343 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
1344
1345 if (!lpConsoleCursorInfo)
1346 {
1347 if (!hConsoleOutput)
1348 SetLastError(ERROR_INVALID_HANDLE);
1349 else
1350 SetLastError(ERROR_INVALID_ACCESS);
1351
1352 return FALSE;
1353 }
1354
1355 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1356 CursorInfoRequest->OutputHandle = hConsoleOutput;
1357
1358 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1359 NULL,
1360 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1361 sizeof(*CursorInfoRequest));
1362 if (!NT_SUCCESS(ApiMessage.Status))
1363 {
1364 BaseSetLastNTError(ApiMessage.Status);
1365 return FALSE;
1366 }
1367
1368 *lpConsoleCursorInfo = CursorInfoRequest->Info;
1369
1370 return TRUE;
1371 }
1372
1373
1374 /*--------------------------------------------------------------
1375 * SetConsoleCursorInfo
1376 *
1377 * @implemented
1378 */
1379 BOOL
1380 WINAPI
1381 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1382 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1383 {
1384 CONSOLE_API_MESSAGE ApiMessage;
1385 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
1386
1387 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1388 CursorInfoRequest->OutputHandle = hConsoleOutput;
1389 CursorInfoRequest->Info = *lpConsoleCursorInfo;
1390
1391 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1392 NULL,
1393 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1394 sizeof(*CursorInfoRequest));
1395 if (!NT_SUCCESS(ApiMessage.Status))
1396 {
1397 BaseSetLastNTError(ApiMessage.Status);
1398 return FALSE;
1399 }
1400
1401 return TRUE;
1402 }
1403
1404
1405 /*--------------------------------------------------------------
1406 * GetNumberOfConsoleMouseButtons
1407 *
1408 * @implemented
1409 */
1410 BOOL
1411 WINAPI
1412 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1413 {
1414 CONSOLE_API_MESSAGE ApiMessage;
1415 PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest;
1416
1417 GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1418
1419 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1420 NULL,
1421 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMouseInfo),
1422 sizeof(*GetMouseInfoRequest));
1423 if (!NT_SUCCESS(ApiMessage.Status))
1424 {
1425 BaseSetLastNTError(ApiMessage.Status);
1426 return FALSE;
1427 }
1428
1429 *lpNumberOfMouseButtons = GetMouseInfoRequest->NumButtons;
1430 return TRUE;
1431 }
1432
1433
1434 /*--------------------------------------------------------------
1435 * SetConsoleActiveScreenBuffer
1436 *
1437 * @implemented
1438 */
1439 BOOL
1440 WINAPI
1441 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1442 {
1443 CONSOLE_API_MESSAGE ApiMessage;
1444 PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &ApiMessage.Data.SetScreenBufferRequest;
1445
1446 SetScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1447 SetScreenBufferRequest->OutputHandle = hConsoleOutput;
1448
1449 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1450 NULL,
1451 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1452 sizeof(*SetScreenBufferRequest));
1453 if (!NT_SUCCESS(ApiMessage.Status))
1454 {
1455 BaseSetLastNTError(ApiMessage.Status);
1456 return FALSE;
1457 }
1458
1459 return TRUE;
1460 }
1461
1462
1463 /*--------------------------------------------------------------
1464 * FlushConsoleInputBuffer
1465 *
1466 * @implemented
1467 */
1468 BOOL
1469 WINAPI
1470 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1471 {
1472 CONSOLE_API_MESSAGE ApiMessage;
1473 PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &ApiMessage.Data.FlushInputBufferRequest;
1474
1475 FlushInputBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1476 FlushInputBufferRequest->InputHandle = hConsoleInput;
1477
1478 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1479 NULL,
1480 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1481 sizeof(*FlushInputBufferRequest));
1482 if (!NT_SUCCESS(ApiMessage.Status))
1483 {
1484 BaseSetLastNTError(ApiMessage.Status);
1485 return FALSE;
1486 }
1487
1488 return TRUE;
1489 }
1490
1491
1492 /*--------------------------------------------------------------
1493 * SetConsoleScreenBufferSize
1494 *
1495 * @implemented
1496 */
1497 BOOL
1498 WINAPI
1499 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1500 COORD dwSize)
1501 {
1502 CONSOLE_API_MESSAGE ApiMessage;
1503 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &ApiMessage.Data.SetScreenBufferSizeRequest;
1504
1505 SetScreenBufferSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1506 SetScreenBufferSizeRequest->OutputHandle = hConsoleOutput;
1507 SetScreenBufferSizeRequest->Size = dwSize;
1508
1509 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1510 NULL,
1511 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1512 sizeof(*SetScreenBufferSizeRequest));
1513 if (!NT_SUCCESS(ApiMessage.Status))
1514 {
1515 BaseSetLastNTError(ApiMessage.Status);
1516 return FALSE;
1517 }
1518
1519 return TRUE;
1520 }
1521
1522
1523 static
1524 BOOL
1525 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1526 CONST SMALL_RECT* lpScrollRectangle,
1527 CONST SMALL_RECT* lpClipRectangle,
1528 COORD dwDestinationOrigin,
1529 CONST CHAR_INFO* lpFill,
1530 BOOL bUnicode)
1531 {
1532 CONSOLE_API_MESSAGE ApiMessage;
1533 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1534
1535 ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1536 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1537 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1538
1539 if (lpClipRectangle != NULL)
1540 {
1541 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1542 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1543 }
1544 else
1545 {
1546 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1547 }
1548
1549 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1550 ScrollScreenBufferRequest->Fill = *lpFill;
1551 ScrollScreenBufferRequest->Unicode = bUnicode;
1552
1553 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1554 NULL,
1555 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1556 sizeof(*ScrollScreenBufferRequest));
1557 if (!NT_SUCCESS(ApiMessage.Status))
1558 {
1559 BaseSetLastNTError(ApiMessage.Status);
1560 return FALSE;
1561 }
1562
1563 return TRUE;
1564 }
1565
1566
1567 /*--------------------------------------------------------------
1568 * ScrollConsoleScreenBufferA
1569 *
1570 * @implemented
1571 */
1572 BOOL
1573 WINAPI
1574 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1575 CONST SMALL_RECT* lpScrollRectangle,
1576 CONST SMALL_RECT* lpClipRectangle,
1577 COORD dwDestinationOrigin,
1578 CONST CHAR_INFO* lpFill)
1579 {
1580 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1581 lpScrollRectangle,
1582 lpClipRectangle,
1583 dwDestinationOrigin,
1584 lpFill,
1585 FALSE);
1586 }
1587
1588
1589 /*--------------------------------------------------------------
1590 * ScrollConsoleScreenBufferW
1591 *
1592 * @implemented
1593 */
1594 BOOL
1595 WINAPI
1596 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1597 CONST SMALL_RECT *lpScrollRectangle,
1598 CONST SMALL_RECT *lpClipRectangle,
1599 COORD dwDestinationOrigin,
1600 CONST CHAR_INFO *lpFill)
1601 {
1602 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1603 lpScrollRectangle,
1604 lpClipRectangle,
1605 dwDestinationOrigin,
1606 lpFill,
1607 TRUE);
1608 }
1609
1610
1611 /*--------------------------------------------------------------
1612 * SetConsoleWindowInfo
1613 *
1614 * @implemented
1615 */
1616 BOOL
1617 WINAPI
1618 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1619 BOOL bAbsolute,
1620 CONST SMALL_RECT *lpConsoleWindow)
1621 {
1622 CONSOLE_API_MESSAGE ApiMessage;
1623 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1624
1625 if (lpConsoleWindow == NULL)
1626 {
1627 SetLastError(ERROR_INVALID_PARAMETER);
1628 return FALSE;
1629 }
1630
1631 SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1632 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1633 SetWindowInfoRequest->Absolute = bAbsolute;
1634 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1635
1636 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1637 NULL,
1638 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1639 sizeof(*SetWindowInfoRequest));
1640 if (!NT_SUCCESS(ApiMessage.Status))
1641 {
1642 BaseSetLastNTError(ApiMessage.Status);
1643 return FALSE;
1644 }
1645
1646 return TRUE;
1647 }
1648
1649
1650 /*--------------------------------------------------------------
1651 * SetConsoleTextAttribute
1652 *
1653 * @implemented
1654 */
1655 BOOL
1656 WINAPI
1657 SetConsoleTextAttribute(HANDLE hConsoleOutput,
1658 WORD wAttributes)
1659 {
1660 CONSOLE_API_MESSAGE ApiMessage;
1661 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest;
1662
1663 SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1664 SetTextAttribRequest->OutputHandle = hConsoleOutput;
1665 SetTextAttribRequest->Attributes = wAttributes;
1666
1667 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1668 NULL,
1669 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
1670 sizeof(*SetTextAttribRequest));
1671 if (!NT_SUCCESS(ApiMessage.Status))
1672 {
1673 BaseSetLastNTError(ApiMessage.Status);
1674 return FALSE;
1675 }
1676
1677 return TRUE;
1678 }
1679
1680
1681 static
1682 BOOL
1683 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1684 {
1685 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
1686
1687 if (HandlerRoutine == NULL)
1688 {
1689 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
1690 return TRUE;
1691 }
1692
1693 if (NrCtrlHandlers == NrAllocatedHandlers)
1694 {
1695 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
1696 0,
1697 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
1698 if (NewCtrlHandlers == NULL)
1699 {
1700 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1701 return FALSE;
1702 }
1703
1704 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
1705
1706 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
1707
1708 CtrlHandlers = NewCtrlHandlers;
1709 NrAllocatedHandlers += 4;
1710 }
1711
1712 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
1713
1714 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
1715 return TRUE;
1716 }
1717
1718
1719 static
1720 BOOL
1721 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
1722 {
1723 ULONG i;
1724
1725 if (HandlerRoutine == NULL)
1726 {
1727 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
1728 return TRUE;
1729 }
1730
1731 for (i = 0; i < NrCtrlHandlers; i++)
1732 {
1733 if (CtrlHandlers[i] == HandlerRoutine)
1734 {
1735 if (i < (NrCtrlHandlers - 1))
1736 {
1737 memmove(&CtrlHandlers[i],
1738 &CtrlHandlers[i+1],
1739 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
1740 }
1741
1742 NrCtrlHandlers--;
1743 return TRUE;
1744 }
1745 }
1746
1747 SetLastError(ERROR_INVALID_PARAMETER);
1748 return FALSE;
1749 }
1750
1751
1752 /*
1753 * @implemented
1754 */
1755 BOOL
1756 WINAPI
1757 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
1758 BOOL Add)
1759 {
1760 BOOL Ret;
1761
1762 RtlEnterCriticalSection(&BaseDllDirectoryLock);
1763 if (Add)
1764 {
1765 Ret = AddConsoleCtrlHandler(HandlerRoutine);
1766 }
1767 else
1768 {
1769 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
1770 }
1771
1772 RtlLeaveCriticalSection(&BaseDllDirectoryLock);
1773 return(Ret);
1774 }
1775
1776
1777 /*--------------------------------------------------------------
1778 * GenerateConsoleCtrlEvent
1779 *
1780 * @implemented
1781 */
1782 BOOL
1783 WINAPI
1784 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
1785 DWORD dwProcessGroupId)
1786 {
1787 CONSOLE_API_MESSAGE ApiMessage;
1788 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &ApiMessage.Data.GenerateCtrlEventRequest;
1789
1790 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
1791 {
1792 SetLastError(ERROR_INVALID_PARAMETER);
1793 return FALSE;
1794 }
1795
1796 GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1797 GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent;
1798 GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId;
1799
1800 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1801 NULL,
1802 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
1803 sizeof(*GenerateCtrlEventRequest));
1804 if (!NT_SUCCESS(ApiMessage.Status))
1805 {
1806 BaseSetLastNTError(ApiMessage.Status);
1807 return FALSE;
1808 }
1809
1810 return TRUE;
1811 }
1812
1813
1814 static DWORD
1815 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode)
1816 {
1817 CONSOLE_API_MESSAGE ApiMessage;
1818 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1819 PCSR_CAPTURE_BUFFER CaptureBuffer;
1820
1821 if (dwNumChars == 0) return 0;
1822
1823 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1824 TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1825 TitleRequest->Unicode = bUnicode;
1826
1827 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1828 if (CaptureBuffer == NULL)
1829 {
1830 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1831 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1832 return 0;
1833 }
1834
1835 CsrAllocateMessagePointer(CaptureBuffer,
1836 TitleRequest->Length,
1837 (PVOID*)&TitleRequest->Title);
1838
1839 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1840 CaptureBuffer,
1841 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
1842 sizeof(*TitleRequest));
1843 if (!NT_SUCCESS(ApiMessage.Status))
1844 {
1845 CsrFreeCaptureBuffer(CaptureBuffer);
1846 BaseSetLastNTError(ApiMessage.Status);
1847 return 0;
1848 }
1849
1850 dwNumChars = TitleRequest->Length / (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1851
1852 if (dwNumChars > 0)
1853 {
1854 memcpy(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length);
1855
1856 if (bUnicode)
1857 ((LPWSTR)lpConsoleTitle)[dwNumChars] = L'\0';
1858 else
1859 ((LPSTR)lpConsoleTitle)[dwNumChars] = '\0';
1860 }
1861
1862 CsrFreeCaptureBuffer(CaptureBuffer);
1863
1864 return dwNumChars;
1865 }
1866
1867
1868 /*--------------------------------------------------------------
1869 * GetConsoleTitleW
1870 *
1871 * @implemented
1872 */
1873 DWORD
1874 WINAPI
1875 GetConsoleTitleW(LPWSTR lpConsoleTitle,
1876 DWORD nSize)
1877 {
1878 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
1879 }
1880
1881
1882 /*--------------------------------------------------------------
1883 * GetConsoleTitleA
1884 *
1885 * @implemented
1886 */
1887 DWORD
1888 WINAPI
1889 GetConsoleTitleA(LPSTR lpConsoleTitle,
1890 DWORD nSize)
1891 {
1892 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
1893 }
1894
1895
1896 static BOOL
1897 IntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode)
1898 {
1899 CONSOLE_API_MESSAGE ApiMessage;
1900 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
1901 PCSR_CAPTURE_BUFFER CaptureBuffer;
1902
1903 ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0);
1904
1905 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1906 TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
1907 TitleRequest->Unicode = bUnicode;
1908
1909 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
1910 if (CaptureBuffer == NULL)
1911 {
1912 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1913 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
1914 return FALSE;
1915 }
1916
1917 CsrCaptureMessageBuffer(CaptureBuffer,
1918 (PVOID)lpConsoleTitle,
1919 TitleRequest->Length,
1920 (PVOID*)&TitleRequest->Title);
1921
1922 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1923 CaptureBuffer,
1924 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
1925 sizeof(*TitleRequest));
1926
1927 CsrFreeCaptureBuffer(CaptureBuffer);
1928
1929 if (!NT_SUCCESS(ApiMessage.Status))
1930 {
1931 BaseSetLastNTError(ApiMessage.Status);
1932 return FALSE;
1933 }
1934
1935 return TRUE;
1936 }
1937
1938 /*--------------------------------------------------------------
1939 * SetConsoleTitleW
1940 *
1941 * @implemented
1942 */
1943 BOOL
1944 WINAPI
1945 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
1946 {
1947 return IntSetConsoleTitle(lpConsoleTitle, TRUE);
1948 }
1949
1950
1951 /*--------------------------------------------------------------
1952 * SetConsoleTitleA
1953 *
1954 * @implemented
1955 */
1956 BOOL
1957 WINAPI
1958 SetConsoleTitleA(LPCSTR lpConsoleTitle)
1959 {
1960 return IntSetConsoleTitle(lpConsoleTitle, FALSE);
1961 }
1962
1963
1964 /*--------------------------------------------------------------
1965 * CreateConsoleScreenBuffer
1966 *
1967 * @implemented
1968 */
1969 HANDLE
1970 WINAPI
1971 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
1972 DWORD dwShareMode,
1973 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
1974 DWORD dwFlags,
1975 LPVOID lpScreenBufferData)
1976 {
1977 CONSOLE_API_MESSAGE ApiMessage;
1978 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
1979 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1980 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = lpScreenBufferData;
1981
1982 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
1983 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
1984 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
1985 {
1986 SetLastError(ERROR_INVALID_PARAMETER);
1987 return INVALID_HANDLE_VALUE;
1988 }
1989
1990 CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1991 CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess;
1992 CreateScreenBufferRequest->InheritHandle =
1993 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
1994 CreateScreenBufferRequest->ShareMode = dwShareMode;
1995 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
1996
1997 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
1998 {
1999 if (CreateScreenBufferRequest->InheritHandle || GraphicsBufferInfo == NULL)
2000 {
2001 SetLastError(ERROR_INVALID_PARAMETER);
2002 return INVALID_HANDLE_VALUE;
2003 }
2004
2005 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
2006
2007 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
2008 if (CaptureBuffer == NULL)
2009 {
2010 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2011 return INVALID_HANDLE_VALUE;
2012 }
2013
2014 CsrCaptureMessageBuffer(CaptureBuffer,
2015 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
2016 GraphicsBufferInfo->dwBitMapInfoLength,
2017 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
2018 }
2019
2020 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2021 CaptureBuffer,
2022 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
2023 sizeof(*CreateScreenBufferRequest));
2024
2025 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
2026
2027 if (!NT_SUCCESS(ApiMessage.Status))
2028 {
2029 BaseSetLastNTError(ApiMessage.Status);
2030 return INVALID_HANDLE_VALUE;
2031 }
2032
2033 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
2034 {
2035 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
2036 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
2037 }
2038
2039 return CreateScreenBufferRequest->OutputHandle;
2040 }
2041
2042
2043 /*--------------------------------------------------------------
2044 * GetConsoleCP
2045 *
2046 * @implemented
2047 */
2048 UINT
2049 WINAPI
2050 GetConsoleCP(VOID)
2051 {
2052 CONSOLE_API_MESSAGE ApiMessage;
2053 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2054
2055 /* Get the Input Code Page */
2056 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2057 GetConsoleCPRequest->OutputCP = FALSE;
2058
2059 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2060 NULL,
2061 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2062 sizeof(*GetConsoleCPRequest));
2063 if (!NT_SUCCESS(ApiMessage.Status))
2064 {
2065 BaseSetLastNTError(ApiMessage.Status);
2066 return 0;
2067 }
2068
2069 return GetConsoleCPRequest->CodePage;
2070 }
2071
2072
2073 /*--------------------------------------------------------------
2074 * SetConsoleCP
2075 *
2076 * @implemented
2077 */
2078 BOOL
2079 WINAPI
2080 SetConsoleCP(UINT wCodePageID)
2081 {
2082 CONSOLE_API_MESSAGE ApiMessage;
2083 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2084
2085 /* Set the Input Code Page */
2086 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2087 SetConsoleCPRequest->CodePage = wCodePageID;
2088 SetConsoleCPRequest->OutputCP = FALSE;
2089 /* SetConsoleCPRequest->EventHandle; */
2090
2091 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2092 NULL,
2093 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2094 sizeof(*SetConsoleCPRequest));
2095 if (!NT_SUCCESS(ApiMessage.Status))
2096 {
2097 BaseSetLastNTError(ApiMessage.Status);
2098 return FALSE;
2099 }
2100
2101 return TRUE;
2102 }
2103
2104
2105 /*--------------------------------------------------------------
2106 * GetConsoleOutputCP
2107 *
2108 * @implemented
2109 */
2110 UINT
2111 WINAPI
2112 GetConsoleOutputCP(VOID)
2113 {
2114 CONSOLE_API_MESSAGE ApiMessage;
2115 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2116
2117 /* Get the Output Code Page */
2118 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2119 GetConsoleCPRequest->OutputCP = TRUE;
2120
2121 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2122 NULL,
2123 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2124 sizeof(*GetConsoleCPRequest));
2125 if (!NT_SUCCESS(ApiMessage.Status))
2126 {
2127 BaseSetLastNTError(ApiMessage.Status);
2128 return 0;
2129 }
2130
2131 return GetConsoleCPRequest->CodePage;
2132 }
2133
2134
2135 /*--------------------------------------------------------------
2136 * SetConsoleOutputCP
2137 *
2138 * @implemented
2139 */
2140 BOOL
2141 WINAPI
2142 SetConsoleOutputCP(UINT wCodePageID)
2143 {
2144 CONSOLE_API_MESSAGE ApiMessage;
2145 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2146
2147 /* Set the Output Code Page */
2148 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2149 SetConsoleCPRequest->CodePage = wCodePageID;
2150 SetConsoleCPRequest->OutputCP = TRUE;
2151 /* SetConsoleCPRequest->EventHandle; */
2152
2153 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2154 NULL,
2155 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2156 sizeof(*SetConsoleCPRequest));
2157 if (!NT_SUCCESS(ApiMessage.Status))
2158 {
2159 BaseSetLastNTError(ApiMessage.Status);
2160 return FALSE;
2161 }
2162
2163 return TRUE;
2164 }
2165
2166
2167 /*--------------------------------------------------------------
2168 * GetConsoleProcessList
2169 *
2170 * @implemented
2171 */
2172 DWORD
2173 WINAPI
2174 GetConsoleProcessList(LPDWORD lpdwProcessList,
2175 DWORD dwProcessCount)
2176 {
2177 CONSOLE_API_MESSAGE ApiMessage;
2178 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2179 PCSR_CAPTURE_BUFFER CaptureBuffer;
2180 ULONG nProcesses = 0;
2181
2182 if (lpdwProcessList == NULL || dwProcessCount == 0)
2183 {
2184 SetLastError(ERROR_INVALID_PARAMETER);
2185 return 0;
2186 }
2187
2188 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2189 if (CaptureBuffer == NULL)
2190 {
2191 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2192 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2193 return 0;
2194 }
2195
2196 GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2197 GetProcessListRequest->ProcessCount = dwProcessCount;
2198
2199 CsrAllocateMessagePointer(CaptureBuffer,
2200 dwProcessCount * sizeof(DWORD),
2201 (PVOID*)&GetProcessListRequest->ProcessIdsList);
2202
2203 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2204 CaptureBuffer,
2205 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2206 sizeof(*GetProcessListRequest));
2207 if (!NT_SUCCESS(ApiMessage.Status))
2208 {
2209 BaseSetLastNTError(ApiMessage.Status);
2210 }
2211 else
2212 {
2213 nProcesses = GetProcessListRequest->ProcessCount;
2214 if (dwProcessCount >= nProcesses)
2215 {
2216 memcpy(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD));
2217 }
2218 }
2219
2220 CsrFreeCaptureBuffer(CaptureBuffer);
2221 return nProcesses;
2222 }
2223
2224
2225 /*--------------------------------------------------------------
2226 * GetConsoleSelectionInfo
2227 *
2228 * @implemented
2229 */
2230 BOOL
2231 WINAPI
2232 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2233 {
2234 CONSOLE_API_MESSAGE ApiMessage;
2235 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &ApiMessage.Data.GetSelectionInfoRequest;
2236
2237 if (lpConsoleSelectionInfo == NULL)
2238 {
2239 SetLastError(ERROR_INVALID_PARAMETER);
2240 return FALSE;
2241 }
2242
2243 GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2244
2245 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2246 NULL,
2247 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2248 sizeof(*GetSelectionInfoRequest));
2249 if (!NT_SUCCESS(ApiMessage.Status))
2250 {
2251 BaseSetLastNTError(ApiMessage.Status);
2252 return FALSE;
2253 }
2254
2255 *lpConsoleSelectionInfo = GetSelectionInfoRequest->Info;
2256
2257 return TRUE;
2258 }
2259
2260
2261 /*--------------------------------------------------------------
2262 * AttachConsole
2263 *
2264 * @implemented
2265 *
2266 * @note Strongly inspired by AllocConsole.
2267 */
2268 BOOL
2269 WINAPI
2270 AttachConsole(DWORD dwProcessId)
2271 {
2272 NTSTATUS Status;
2273 PRTL_USER_PROCESS_PARAMETERS Parameters = NtCurrentPeb()->ProcessParameters;
2274 CONSOLE_API_MESSAGE ApiMessage;
2275 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2276
2277 if (Parameters->ConsoleHandle)
2278 {
2279 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2280 SetLastError(ERROR_ACCESS_DENIED);
2281 return FALSE;
2282 }
2283
2284 AttachConsoleRequest->ProcessId = dwProcessId;
2285 AttachConsoleRequest->CtrlDispatcher = ConsoleControlDispatcher;
2286 AttachConsoleRequest->PropDispatcher = PropDialogHandler;
2287
2288 Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2289 NULL,
2290 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2291 sizeof(CONSOLE_ATTACHCONSOLE));
2292 if (!NT_SUCCESS(Status))
2293 {
2294 BaseSetLastNTError(Status);
2295 return FALSE;
2296 }
2297
2298 Parameters->ConsoleHandle = AttachConsoleRequest->ConsoleHandle;
2299 SetStdHandle(STD_INPUT_HANDLE , AttachConsoleRequest->InputHandle );
2300 SetStdHandle(STD_OUTPUT_HANDLE, AttachConsoleRequest->OutputHandle);
2301 SetStdHandle(STD_ERROR_HANDLE , AttachConsoleRequest->ErrorHandle );
2302
2303 /* Initialize Console Ctrl Handler */
2304 InitConsoleCtrlHandling();
2305
2306 InputWaitHandle = AttachConsoleRequest->InputWaitHandle;
2307
2308 return TRUE;
2309 }
2310
2311
2312 /*--------------------------------------------------------------
2313 * GetConsoleWindow
2314 *
2315 * @implemented
2316 */
2317 HWND
2318 WINAPI
2319 GetConsoleWindow(VOID)
2320 {
2321 CONSOLE_API_MESSAGE ApiMessage;
2322 PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest;
2323
2324 GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2325
2326 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2327 NULL,
2328 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2329 sizeof(*GetWindowRequest));
2330 if (!NT_SUCCESS(ApiMessage.Status))
2331 {
2332 BaseSetLastNTError(ApiMessage.Status);
2333 return (HWND)NULL;
2334 }
2335
2336 return GetWindowRequest->WindowHandle;
2337 }
2338
2339
2340 /*--------------------------------------------------------------
2341 * SetConsoleIcon
2342 *
2343 * @implemented
2344 */
2345 BOOL
2346 WINAPI
2347 SetConsoleIcon(HICON hIcon)
2348 {
2349 CONSOLE_API_MESSAGE ApiMessage;
2350 PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest;
2351
2352 SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2353 SetIconRequest->IconHandle = hIcon;
2354
2355 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2356 NULL,
2357 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2358 sizeof(*SetIconRequest));
2359 if (!NT_SUCCESS(ApiMessage.Status))
2360 {
2361 BaseSetLastNTError(ApiMessage.Status);
2362 return FALSE;
2363 }
2364
2365 return TRUE;
2366 }
2367
2368
2369 /******************************************************************************
2370 * \name SetConsoleInputExeNameW
2371 * \brief Sets the console input file name from a unicode string.
2372 * \param lpInputExeName Pointer to a unicode string with the name.
2373 * \return TRUE if successful, FALSE if unsuccsedful.
2374 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2375 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2376 */
2377 BOOL
2378 WINAPI
2379 SetConsoleInputExeNameW(LPCWSTR lpInputExeName)
2380 {
2381 int lenName;
2382
2383 if ( !lpInputExeName ||
2384 (lenName = lstrlenW(lpInputExeName)) == 0 ||
2385 lenName > INPUTEXENAME_BUFLEN - 1 )
2386 {
2387 /* Fail if string is empty or too long */
2388 SetLastError(ERROR_INVALID_PARAMETER);
2389 return FALSE;
2390 }
2391
2392 RtlEnterCriticalSection(&ConsoleLock);
2393 _SEH2_TRY
2394 {
2395 RtlCopyMemory(InputExeName, lpInputExeName, lenName * sizeof(WCHAR));
2396 InputExeName[lenName] = L'\0';
2397 }
2398 _SEH2_FINALLY
2399 {
2400 RtlLeaveCriticalSection(&ConsoleLock);
2401 }
2402 _SEH2_END;
2403
2404 return TRUE;
2405 }
2406
2407
2408 /******************************************************************************
2409 * \name SetConsoleInputExeNameA
2410 * \brief Sets the console input file name from an ansi string.
2411 * \param lpInputExeName Pointer to an ansi string with the name.
2412 * \return TRUE if successful, FALSE if unsuccsedful.
2413 * \remarks If lpInputExeName is 0 or the string length is 0 or greater than 255,
2414 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2415 */
2416 BOOL
2417 WINAPI
2418 SetConsoleInputExeNameA(LPCSTR lpInputExeName)
2419 {
2420 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2421 ANSI_STRING InputExeNameA;
2422 UNICODE_STRING InputExeNameU;
2423 NTSTATUS Status;
2424
2425 RtlInitAnsiString(&InputExeNameA, lpInputExeName);
2426
2427 if ( InputExeNameA.Length == 0 ||
2428 InputExeNameA.Length > INPUTEXENAME_BUFLEN - 1 )
2429 {
2430 /* Fail if string is empty or too long */
2431 SetLastError(ERROR_INVALID_PARAMETER);
2432 return FALSE;
2433 }
2434
2435 InputExeNameU.Buffer = Buffer;
2436 InputExeNameU.MaximumLength = sizeof(Buffer);
2437 InputExeNameU.Length = 0;
2438
2439 Status = RtlAnsiStringToUnicodeString(&InputExeNameU, &InputExeNameA, FALSE);
2440 if (!NT_SUCCESS(Status))
2441 {
2442 BaseSetLastNTError(Status);
2443 return FALSE;
2444 }
2445
2446 return SetConsoleInputExeNameW(InputExeNameU.Buffer);
2447 }
2448
2449
2450 /******************************************************************************
2451 * \name GetConsoleInputExeNameW
2452 * \brief Retrieves the console input file name as unicode string.
2453 * \param nBufferLength Length of the buffer in WCHARs.
2454 * Specify 0 to receive the needed buffer length.
2455 * \param lpBuffer Pointer to a buffer that receives the string.
2456 * \return Needed buffer size if \p nBufferLength is 0.
2457 * Otherwise 1 if successful, 2 if buffer is too small.
2458 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2459 * is not big enough.
2460 */
2461 DWORD
2462 WINAPI
2463 GetConsoleInputExeNameW(DWORD nBufferLength, LPWSTR lpBuffer)
2464 {
2465 ULONG lenName = lstrlenW(InputExeName);
2466
2467 if (nBufferLength == 0)
2468 {
2469 /* Buffer size is requested, return it */
2470 return lenName + 1;
2471 }
2472
2473 if (lenName + 1 > nBufferLength)
2474 {
2475 /* Buffer is not large enough! */
2476 SetLastError(ERROR_BUFFER_OVERFLOW);
2477 return 2;
2478 }
2479
2480 RtlEnterCriticalSection(&ConsoleLock);
2481 _SEH2_TRY
2482 {
2483 RtlCopyMemory(lpBuffer, InputExeName, lenName * sizeof(WCHAR));
2484 lpBuffer[lenName] = '\0';
2485 }
2486 _SEH2_FINALLY
2487 {
2488 RtlLeaveCriticalSection(&ConsoleLock);
2489 }
2490 _SEH2_END;
2491
2492 /* Success, return 1 */
2493 return 1;
2494 }
2495
2496
2497 /******************************************************************************
2498 * \name GetConsoleInputExeNameA
2499 * \brief Retrieves the console input file name as ansi string.
2500 * \param nBufferLength Length of the buffer in CHARs.
2501 * \param lpBuffer Pointer to a buffer that receives the string.
2502 * \return 1 if successful, 2 if buffer is too small.
2503 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2504 * is not big enough. The buffer receives as much characters as fit.
2505 */
2506 DWORD
2507 WINAPI
2508 GetConsoleInputExeNameA(DWORD nBufferLength, LPSTR lpBuffer)
2509 {
2510 WCHAR Buffer[INPUTEXENAME_BUFLEN];
2511 DWORD Ret;
2512 UNICODE_STRING BufferU;
2513 ANSI_STRING BufferA;
2514
2515 /* Get the unicode name */
2516 Ret = GetConsoleInputExeNameW(sizeof(Buffer) / sizeof(Buffer[0]), Buffer);
2517
2518 /* Initialize strings for conversion */
2519 RtlInitUnicodeString(&BufferU, Buffer);
2520 BufferA.Length = 0;
2521 BufferA.MaximumLength = (USHORT)nBufferLength;
2522 BufferA.Buffer = lpBuffer;
2523
2524 /* Convert unicode name to ansi, copying as much chars as fit */
2525 RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2526
2527 /* Error handling */
2528 if (nBufferLength <= BufferU.Length / sizeof(WCHAR))
2529 {
2530 SetLastError(ERROR_BUFFER_OVERFLOW);
2531 return 2;
2532 }
2533
2534 return Ret;
2535 }
2536
2537 BOOL
2538 WINAPI
2539 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2540 {
2541 STUB;
2542 return FALSE;
2543 }
2544
2545 BOOL
2546 WINAPI
2547 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2548 {
2549 STUB;
2550 return FALSE;
2551 }
2552
2553 BOOL
2554 WINAPI
2555 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
2556 {
2557 STUB;
2558 return FALSE;
2559 }
2560
2561 BOOL
2562 WINAPI
2563 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
2564 {
2565 STUB;
2566 return FALSE;
2567 }
2568
2569 BOOL
2570 WINAPI
2571 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
2572 {
2573 STUB;
2574 return FALSE;
2575 }
2576
2577 BOOL
2578 WINAPI
2579 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
2580 {
2581 STUB;
2582 return FALSE;
2583 }
2584
2585 BOOL
2586 WINAPI
2587 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId)
2588 {
2589 STUB;
2590 return FALSE;
2591 }
2592
2593 BOOL
2594 WINAPI
2595 RegisterConsoleOS2(BOOL bUnknown)
2596 {
2597 STUB;
2598 return FALSE;
2599 }
2600
2601 BOOL
2602 WINAPI
2603 SetConsoleOS2OemFormat(BOOL bUnknown)
2604 {
2605 STUB;
2606 return FALSE;
2607 }
2608
2609 BOOL
2610 WINAPI
2611 UnregisterConsoleIME(VOID)
2612 {
2613 STUB;
2614 return FALSE;
2615 }
2616
2617
2618 BOOL
2619 IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName,
2620 IN BOOL bAnsi)
2621 {
2622 CONSOLE_API_MESSAGE ApiMessage;
2623 PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest;
2624
2625 /* Set up the data to send to the Console Server */
2626 GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2627 GetKbdLayoutNameRequest->Ansi = bAnsi;
2628
2629 /* Call the server */
2630 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2631 NULL,
2632 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName),
2633 sizeof(*GetKbdLayoutNameRequest));
2634
2635 /* Check for success */
2636 if (!NT_SUCCESS(ApiMessage.Status))
2637 {
2638 BaseSetLastNTError(ApiMessage.Status);
2639 return FALSE;
2640 }
2641
2642 /* Retrieve the results */
2643 _SEH2_TRY
2644 {
2645 /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */
2646 if (bAnsi)
2647 strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
2648 else
2649 wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
2650 }
2651 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
2652 {
2653 SetLastError(ERROR_INVALID_ACCESS);
2654 _SEH2_YIELD(return FALSE);
2655 }
2656 _SEH2_END;
2657
2658 return TRUE;
2659 }
2660
2661 /*
2662 * @implemented (undocumented)
2663 */
2664 BOOL
2665 WINAPI
2666 GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName)
2667 {
2668 return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE);
2669 }
2670
2671 /*
2672 * @implemented (undocumented)
2673 */
2674 BOOL
2675 WINAPI
2676 GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName)
2677 {
2678 return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE);
2679 }
2680
2681 /*
2682 * @implemented
2683 */
2684 DWORD
2685 WINAPI
2686 SetLastConsoleEventActive(VOID)
2687 {
2688 CONSOLE_API_MESSAGE ApiMessage;
2689 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest;
2690
2691 /* Set the flag used by the console control dispatcher */
2692 LastCloseNotify = TRUE;
2693
2694 /* Set up the input arguments */
2695 NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2696
2697 /* Call CSRSS; just return the NTSTATUS cast to DWORD */
2698 return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2699 NULL,
2700 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose),
2701 sizeof(*NotifyLastCloseRequest));
2702 }
2703
2704 /* EOF */