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