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
DefaultConsoleCtrlHandler(DWORD Event)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
ConsoleControlDispatcher(IN LPVOID lpThreadParameter)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
InitializeCtrlHandling(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
InitExeName(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
SetUpAppName(IN BOOLEAN CaptureStrings,IN OUT LPDWORD CurDirLength,IN OUT LPWSTR * CurDir,IN OUT LPDWORD AppNameLength,IN OUT LPWSTR * AppName)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
GetCurrentExeName(OUT PWCHAR ExeName,IN USHORT BufferSize)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
IntCheckForConsoleFileName(IN LPCWSTR pszName,IN DWORD dwDesiredAccess)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
ConsoleMenuControl(HANDLE hConsoleOutput,DWORD dwCmdIdLow,DWORD dwCmdIdHigh)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
DuplicateConsoleHandle(HANDLE hConsole,DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwOptions)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
GetConsoleHandleInformation(IN HANDLE hHandle,OUT LPDWORD lpdwFlags)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
SetConsoleHandleInformation(IN HANDLE hHandle,IN DWORD dwMask,IN DWORD dwFlags)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
GetConsoleDisplayMode(LPDWORD lpModeFlags)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
GetConsoleFontInfo(IN HANDLE hConsoleOutput,IN BOOL bMaximumWindow,IN DWORD nFontCount,OUT PCONSOLE_FONT_INFO lpConsoleFontInfo)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
GetConsoleFontSize(IN HANDLE hConsoleOutput,IN DWORD nFont)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
GetConsoleHardwareState(HANDLE hConsoleOutput,PDWORD Flags,PDWORD State)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
GetConsoleInputWaitHandle(VOID)683 GetConsoleInputWaitHandle(VOID)
684 {
685 return InputWaitHandle;
686 }
687
688
689 /*
690 * @implemented
691 */
692 BOOL
693 WINAPI
GetCurrentConsoleFont(IN HANDLE hConsoleOutput,IN BOOL bMaximumWindow,OUT PCONSOLE_FONT_INFO lpConsoleCurrentFont)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
GetNumberOfConsoleFonts(VOID)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
InvalidateConsoleDIBits(IN HANDLE hConsoleOutput,IN PSMALL_RECT lpRect)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
OpenConsoleW(LPCWSTR wsName,DWORD dwDesiredAccess,BOOL bInheritHandle,DWORD dwShareMode)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
SetConsoleCursor(HANDLE hConsoleOutput,HCURSOR hCursor)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
SetConsoleDisplayMode(HANDLE hConsoleOutput,DWORD dwFlags,PCOORD lpNewScreenBufferDimensions)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
SetConsoleFont(IN HANDLE hConsoleOutput,IN DWORD nFont)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
SetConsoleHardwareState(HANDLE hConsoleOutput,DWORD Flags,DWORD State)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
SetConsoleKeyShortcuts(DWORD Unknown0,DWORD Unknown1,DWORD Unknown2,DWORD Unknown3)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
SetConsoleMaximumWindowSize(HANDLE hConsoleOutput,COORD dwMaximumSize)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
SetConsoleMenuClose(BOOL bEnable)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
SetConsolePalette(HANDLE hConsoleOutput,HPALETTE hPalette,UINT dwUsage)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
ShowConsoleCursor(HANDLE hConsoleOutput,BOOL bShow)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
VerifyConsoleIoHandle(HANDLE hIoHandle)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
CloseConsoleHandle(HANDLE hHandle)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
GetStdHandle(DWORD nStdHandle)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
SetStdHandle(DWORD nStdHandle,HANDLE hHandle)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
IntAllocConsole(LPWSTR Title,DWORD TitleLength,LPWSTR Desktop,DWORD DesktopLength,LPWSTR CurDir,DWORD CurDirLength,LPWSTR AppName,DWORD AppNameLength,LPTHREAD_START_ROUTINE CtrlRoutine,LPTHREAD_START_ROUTINE PropRoutine,PCONSOLE_START_INFO ConsoleStartInfo)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
AllocConsole(VOID)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 RtlEnterCriticalSection(&ConsoleLock);
1379
1380 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
1381 {
1382 DPRINT1("AllocConsole: Allocating a console to a process already having one\n");
1383 SetLastError(ERROR_ACCESS_DENIED);
1384 Success = FALSE;
1385 goto Quit;
1386 }
1387
1388 /* Set up the console properties */
1389 SetUpConsoleInfo(FALSE,
1390 &TitleLength,
1391 &ConsoleTitle,
1392 &DesktopLength,
1393 &Desktop,
1394 &ConsoleStartInfo);
1395 DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n",
1396 ConsoleTitle, Desktop);
1397
1398 /* Initialize the Input EXE name */
1399 InitExeName();
1400 SetUpAppName(FALSE,
1401 &CurDirLength,
1402 &CurDir,
1403 &AppNameLength,
1404 &AppName);
1405 DPRINT("CurDir = '%S' - AppName = '%S'\n",
1406 CurDir, AppName);
1407
1408 Success = IntAllocConsole(ConsoleTitle,
1409 TitleLength,
1410 Desktop,
1411 DesktopLength,
1412 CurDir,
1413 CurDirLength,
1414 AppName,
1415 AppNameLength,
1416 ConsoleControlDispatcher,
1417 PropDialogHandler,
1418 &ConsoleStartInfo);
1419 if (Success)
1420 {
1421 /* Set up the handles */
1422 SetUpHandles(&ConsoleStartInfo);
1423 InputWaitHandle = ConsoleStartInfo.InputWaitHandle;
1424
1425 /* Initialize Console Ctrl Handling */
1426 InitializeCtrlHandling();
1427
1428 /* Sync the current thread's LangId with the console's one */
1429 SetTEBLangID();
1430 }
1431
1432 Quit:
1433 RtlLeaveCriticalSection(&ConsoleLock);
1434 return Success;
1435 }
1436
1437
1438 /*
1439 * @implemented
1440 */
1441 BOOL
1442 WINAPI
1443 DECLSPEC_HOTPATCH
FreeConsole(VOID)1444 FreeConsole(VOID)
1445 {
1446 BOOL Success = TRUE;
1447 CONSOLE_API_MESSAGE ApiMessage;
1448 PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest;
1449 HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1450
1451 RtlEnterCriticalSection(&ConsoleLock);
1452
1453 /* We must have a non-trivial handle to close */
1454 if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle)
1455 {
1456 SetLastError(ERROR_INVALID_PARAMETER);
1457 Success = FALSE;
1458 goto Quit;
1459 }
1460
1461 /* Set up the data to send to the Console Server */
1462 FreeConsoleRequest->ConsoleHandle = ConsoleHandle;
1463
1464 /* Call the server */
1465 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1466 NULL,
1467 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree),
1468 sizeof(*FreeConsoleRequest));
1469
1470 /* Check for success */
1471 if (!NT_SUCCESS(ApiMessage.Status))
1472 {
1473 BaseSetLastNTError(ApiMessage.Status);
1474 Success = FALSE;
1475 goto Quit;
1476 }
1477
1478 /* Reset the console handle */
1479 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
1480
1481 /* Close the associated input handle */
1482 CloseHandle(InputWaitHandle);
1483 InputWaitHandle = INVALID_HANDLE_VALUE;
1484
1485 Quit:
1486 RtlLeaveCriticalSection(&ConsoleLock);
1487 return Success;
1488 }
1489
1490
1491 /*
1492 * @implemented
1493 */
1494 BOOL
1495 WINAPI
GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)1496 GetConsoleScreenBufferInfo(HANDLE hConsoleOutput,
1497 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo)
1498 {
1499 CONSOLE_API_MESSAGE ApiMessage;
1500 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &ApiMessage.Data.ScreenBufferInfoRequest;
1501
1502 if (lpConsoleScreenBufferInfo == NULL)
1503 {
1504 SetLastError(ERROR_INVALID_PARAMETER);
1505 return FALSE;
1506 }
1507
1508 ScreenBufferInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1509 ScreenBufferInfoRequest->OutputHandle = hConsoleOutput;
1510
1511 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1512 NULL,
1513 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo),
1514 sizeof(*ScreenBufferInfoRequest));
1515 if (!NT_SUCCESS(ApiMessage.Status))
1516 {
1517 BaseSetLastNTError(ApiMessage.Status);
1518 return FALSE;
1519 }
1520
1521 lpConsoleScreenBufferInfo->dwSize = ScreenBufferInfoRequest->ScreenBufferSize;
1522 lpConsoleScreenBufferInfo->dwCursorPosition = ScreenBufferInfoRequest->CursorPosition;
1523 lpConsoleScreenBufferInfo->wAttributes = ScreenBufferInfoRequest->Attributes;
1524 lpConsoleScreenBufferInfo->srWindow.Left = ScreenBufferInfoRequest->ViewOrigin.X;
1525 lpConsoleScreenBufferInfo->srWindow.Top = ScreenBufferInfoRequest->ViewOrigin.Y;
1526 lpConsoleScreenBufferInfo->srWindow.Right = ScreenBufferInfoRequest->ViewOrigin.X + ScreenBufferInfoRequest->ViewSize.X - 1;
1527 lpConsoleScreenBufferInfo->srWindow.Bottom = ScreenBufferInfoRequest->ViewOrigin.Y + ScreenBufferInfoRequest->ViewSize.Y - 1;
1528 lpConsoleScreenBufferInfo->dwMaximumWindowSize = ScreenBufferInfoRequest->MaximumViewSize;
1529
1530 return TRUE;
1531 }
1532
1533
1534 /*
1535 * @implemented
1536 */
1537 BOOL
1538 WINAPI
1539 DECLSPEC_HOTPATCH
SetConsoleCursorPosition(HANDLE hConsoleOutput,COORD dwCursorPosition)1540 SetConsoleCursorPosition(HANDLE hConsoleOutput,
1541 COORD dwCursorPosition)
1542 {
1543 CONSOLE_API_MESSAGE ApiMessage;
1544 PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &ApiMessage.Data.SetCursorPositionRequest;
1545
1546 SetCursorPositionRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1547 SetCursorPositionRequest->OutputHandle = hConsoleOutput;
1548 SetCursorPositionRequest->Position = dwCursorPosition;
1549
1550 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1551 NULL,
1552 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition),
1553 sizeof(*SetCursorPositionRequest));
1554 if (!NT_SUCCESS(ApiMessage.Status))
1555 {
1556 BaseSetLastNTError(ApiMessage.Status);
1557 return FALSE;
1558 }
1559
1560 return TRUE;
1561 }
1562
1563
1564 /*
1565 * @implemented
1566 */
1567 BOOL
1568 WINAPI
GetConsoleMode(HANDLE hConsoleHandle,LPDWORD lpMode)1569 GetConsoleMode(HANDLE hConsoleHandle,
1570 LPDWORD lpMode)
1571 {
1572 CONSOLE_API_MESSAGE ApiMessage;
1573 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1574
1575 if (lpMode == NULL)
1576 {
1577 SetLastError(ERROR_INVALID_PARAMETER);
1578 return FALSE;
1579 }
1580
1581 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1582 ConsoleModeRequest->Handle = hConsoleHandle;
1583
1584 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1585 NULL,
1586 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode),
1587 sizeof(*ConsoleModeRequest));
1588 if (!NT_SUCCESS(ApiMessage.Status))
1589 {
1590 BaseSetLastNTError(ApiMessage.Status);
1591 return FALSE;
1592 }
1593
1594 *lpMode = ConsoleModeRequest->Mode;
1595
1596 return TRUE;
1597 }
1598
1599
1600 /*
1601 * @implemented
1602 */
1603 BOOL
1604 WINAPI
1605 DECLSPEC_HOTPATCH
SetConsoleMode(HANDLE hConsoleHandle,DWORD dwMode)1606 SetConsoleMode(HANDLE hConsoleHandle,
1607 DWORD dwMode)
1608 {
1609 CONSOLE_API_MESSAGE ApiMessage;
1610 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest;
1611
1612 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1613 ConsoleModeRequest->Handle = hConsoleHandle;
1614 ConsoleModeRequest->Mode = dwMode;
1615
1616 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1617 NULL,
1618 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode),
1619 sizeof(*ConsoleModeRequest));
1620 if (!NT_SUCCESS(ApiMessage.Status))
1621 {
1622 BaseSetLastNTError(ApiMessage.Status);
1623 return FALSE;
1624 }
1625
1626 return TRUE;
1627 }
1628
1629
1630 /*
1631 * @implemented
1632 */
1633 BOOL
1634 WINAPI
GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,LPDWORD lpNumberOfEvents)1635 GetNumberOfConsoleInputEvents(HANDLE hConsoleInput,
1636 LPDWORD lpNumberOfEvents)
1637 {
1638 CONSOLE_API_MESSAGE ApiMessage;
1639 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest;
1640
1641 GetNumInputEventsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1642 GetNumInputEventsRequest->InputHandle = hConsoleInput;
1643 GetNumInputEventsRequest->NumberOfEvents = 0;
1644
1645 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1646 NULL,
1647 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents),
1648 sizeof(*GetNumInputEventsRequest));
1649 if (!NT_SUCCESS(ApiMessage.Status))
1650 {
1651 BaseSetLastNTError(ApiMessage.Status);
1652 return FALSE;
1653 }
1654
1655 if (lpNumberOfEvents == NULL)
1656 {
1657 SetLastError(ERROR_INVALID_ACCESS);
1658 return FALSE;
1659 }
1660
1661 *lpNumberOfEvents = GetNumInputEventsRequest->NumberOfEvents;
1662
1663 return TRUE;
1664 }
1665
1666
1667 /*
1668 * @implemented
1669 */
1670 COORD
1671 WINAPI
1672 DECLSPEC_HOTPATCH
GetLargestConsoleWindowSize(HANDLE hConsoleOutput)1673 GetLargestConsoleWindowSize(HANDLE hConsoleOutput)
1674 {
1675 CONSOLE_API_MESSAGE ApiMessage;
1676 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest;
1677
1678 GetLargestWindowSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1679 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput;
1680 GetLargestWindowSizeRequest->Size.X = 0;
1681 GetLargestWindowSizeRequest->Size.Y = 0;
1682
1683 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1684 NULL,
1685 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize),
1686 sizeof(*GetLargestWindowSizeRequest));
1687 if (!NT_SUCCESS(ApiMessage.Status))
1688 {
1689 BaseSetLastNTError(ApiMessage.Status);
1690 }
1691
1692 DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y);
1693 return GetLargestWindowSizeRequest->Size;
1694 }
1695
1696
1697 /*
1698 * @implemented
1699 */
1700 BOOL
1701 WINAPI
GetConsoleCursorInfo(HANDLE hConsoleOutput,PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)1702 GetConsoleCursorInfo(HANDLE hConsoleOutput,
1703 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo)
1704 {
1705 CONSOLE_API_MESSAGE ApiMessage;
1706 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
1707
1708 if (!lpConsoleCursorInfo)
1709 {
1710 if (!hConsoleOutput)
1711 SetLastError(ERROR_INVALID_HANDLE);
1712 else
1713 SetLastError(ERROR_INVALID_ACCESS);
1714
1715 return FALSE;
1716 }
1717
1718 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1719 CursorInfoRequest->OutputHandle = hConsoleOutput;
1720
1721 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1722 NULL,
1723 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo),
1724 sizeof(*CursorInfoRequest));
1725 if (!NT_SUCCESS(ApiMessage.Status))
1726 {
1727 BaseSetLastNTError(ApiMessage.Status);
1728 return FALSE;
1729 }
1730
1731 *lpConsoleCursorInfo = CursorInfoRequest->Info;
1732
1733 return TRUE;
1734 }
1735
1736
1737 /*
1738 * @implemented
1739 */
1740 BOOL
1741 WINAPI
SetConsoleCursorInfo(HANDLE hConsoleOutput,CONST CONSOLE_CURSOR_INFO * lpConsoleCursorInfo)1742 SetConsoleCursorInfo(HANDLE hConsoleOutput,
1743 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo)
1744 {
1745 CONSOLE_API_MESSAGE ApiMessage;
1746 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest;
1747
1748 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1749 CursorInfoRequest->OutputHandle = hConsoleOutput;
1750 CursorInfoRequest->Info = *lpConsoleCursorInfo;
1751
1752 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1753 NULL,
1754 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo),
1755 sizeof(*CursorInfoRequest));
1756 if (!NT_SUCCESS(ApiMessage.Status))
1757 {
1758 BaseSetLastNTError(ApiMessage.Status);
1759 return FALSE;
1760 }
1761
1762 return TRUE;
1763 }
1764
1765
1766 /*
1767 * @implemented
1768 */
1769 BOOL
1770 WINAPI
GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)1771 GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons)
1772 {
1773 CONSOLE_API_MESSAGE ApiMessage;
1774 PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest;
1775
1776 GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1777
1778 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1779 NULL,
1780 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMouseInfo),
1781 sizeof(*GetMouseInfoRequest));
1782 if (!NT_SUCCESS(ApiMessage.Status))
1783 {
1784 BaseSetLastNTError(ApiMessage.Status);
1785 return FALSE;
1786 }
1787
1788 *lpNumberOfMouseButtons = GetMouseInfoRequest->NumButtons;
1789 return TRUE;
1790 }
1791
1792
1793 /*
1794 * @implemented
1795 */
1796 BOOL
1797 WINAPI
1798 DECLSPEC_HOTPATCH
SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)1799 SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput)
1800 {
1801 CONSOLE_API_MESSAGE ApiMessage;
1802 PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &ApiMessage.Data.SetScreenBufferRequest;
1803
1804 SetScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1805 SetScreenBufferRequest->OutputHandle = hConsoleOutput;
1806
1807 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1808 NULL,
1809 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer),
1810 sizeof(*SetScreenBufferRequest));
1811 if (!NT_SUCCESS(ApiMessage.Status))
1812 {
1813 BaseSetLastNTError(ApiMessage.Status);
1814 return FALSE;
1815 }
1816
1817 return TRUE;
1818 }
1819
1820
1821 /*
1822 * @implemented
1823 */
1824 BOOL
1825 WINAPI
1826 DECLSPEC_HOTPATCH
FlushConsoleInputBuffer(HANDLE hConsoleInput)1827 FlushConsoleInputBuffer(HANDLE hConsoleInput)
1828 {
1829 CONSOLE_API_MESSAGE ApiMessage;
1830 PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &ApiMessage.Data.FlushInputBufferRequest;
1831
1832 FlushInputBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1833 FlushInputBufferRequest->InputHandle = hConsoleInput;
1834
1835 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1836 NULL,
1837 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer),
1838 sizeof(*FlushInputBufferRequest));
1839 if (!NT_SUCCESS(ApiMessage.Status))
1840 {
1841 BaseSetLastNTError(ApiMessage.Status);
1842 return FALSE;
1843 }
1844
1845 return TRUE;
1846 }
1847
1848
1849 /*
1850 * @implemented
1851 */
1852 BOOL
1853 WINAPI
1854 DECLSPEC_HOTPATCH
SetConsoleScreenBufferSize(HANDLE hConsoleOutput,COORD dwSize)1855 SetConsoleScreenBufferSize(HANDLE hConsoleOutput,
1856 COORD dwSize)
1857 {
1858 CONSOLE_API_MESSAGE ApiMessage;
1859 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &ApiMessage.Data.SetScreenBufferSizeRequest;
1860
1861 SetScreenBufferSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1862 SetScreenBufferSizeRequest->OutputHandle = hConsoleOutput;
1863 SetScreenBufferSizeRequest->Size = dwSize;
1864
1865 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1866 NULL,
1867 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize),
1868 sizeof(*SetScreenBufferSizeRequest));
1869 if (!NT_SUCCESS(ApiMessage.Status))
1870 {
1871 BaseSetLastNTError(ApiMessage.Status);
1872 return FALSE;
1873 }
1874
1875 return TRUE;
1876 }
1877
1878
1879 static
1880 BOOL
IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,CONST SMALL_RECT * lpScrollRectangle,CONST SMALL_RECT * lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO * lpFill,BOOL bUnicode)1881 IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput,
1882 CONST SMALL_RECT* lpScrollRectangle,
1883 CONST SMALL_RECT* lpClipRectangle,
1884 COORD dwDestinationOrigin,
1885 CONST CHAR_INFO* lpFill,
1886 BOOL bUnicode)
1887 {
1888 CONSOLE_API_MESSAGE ApiMessage;
1889 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest;
1890
1891 ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1892 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput;
1893 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle;
1894
1895 if (lpClipRectangle != NULL)
1896 {
1897 ScrollScreenBufferRequest->UseClipRectangle = TRUE;
1898 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle;
1899 }
1900 else
1901 {
1902 ScrollScreenBufferRequest->UseClipRectangle = FALSE;
1903 }
1904
1905 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin;
1906 ScrollScreenBufferRequest->Fill = *lpFill;
1907 ScrollScreenBufferRequest->Unicode = bUnicode;
1908
1909 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1910 NULL,
1911 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer),
1912 sizeof(*ScrollScreenBufferRequest));
1913 if (!NT_SUCCESS(ApiMessage.Status))
1914 {
1915 BaseSetLastNTError(ApiMessage.Status);
1916 return FALSE;
1917 }
1918
1919 return TRUE;
1920 }
1921
1922
1923 /*
1924 * @implemented
1925 */
1926 BOOL
1927 WINAPI
1928 DECLSPEC_HOTPATCH
ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,CONST SMALL_RECT * lpScrollRectangle,CONST SMALL_RECT * lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO * lpFill)1929 ScrollConsoleScreenBufferA(HANDLE hConsoleOutput,
1930 CONST SMALL_RECT* lpScrollRectangle,
1931 CONST SMALL_RECT* lpClipRectangle,
1932 COORD dwDestinationOrigin,
1933 CONST CHAR_INFO* lpFill)
1934 {
1935 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1936 lpScrollRectangle,
1937 lpClipRectangle,
1938 dwDestinationOrigin,
1939 lpFill,
1940 FALSE);
1941 }
1942
1943
1944 /*
1945 * @implemented
1946 */
1947 BOOL
1948 WINAPI
1949 DECLSPEC_HOTPATCH
ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,CONST SMALL_RECT * lpScrollRectangle,CONST SMALL_RECT * lpClipRectangle,COORD dwDestinationOrigin,CONST CHAR_INFO * lpFill)1950 ScrollConsoleScreenBufferW(HANDLE hConsoleOutput,
1951 CONST SMALL_RECT *lpScrollRectangle,
1952 CONST SMALL_RECT *lpClipRectangle,
1953 COORD dwDestinationOrigin,
1954 CONST CHAR_INFO *lpFill)
1955 {
1956 return IntScrollConsoleScreenBuffer(hConsoleOutput,
1957 lpScrollRectangle,
1958 lpClipRectangle,
1959 dwDestinationOrigin,
1960 lpFill,
1961 TRUE);
1962 }
1963
1964
1965 /*
1966 * @implemented
1967 */
1968 BOOL
1969 WINAPI
SetConsoleWindowInfo(HANDLE hConsoleOutput,BOOL bAbsolute,CONST SMALL_RECT * lpConsoleWindow)1970 SetConsoleWindowInfo(HANDLE hConsoleOutput,
1971 BOOL bAbsolute,
1972 CONST SMALL_RECT *lpConsoleWindow)
1973 {
1974 CONSOLE_API_MESSAGE ApiMessage;
1975 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest;
1976
1977 if (lpConsoleWindow == NULL)
1978 {
1979 SetLastError(ERROR_INVALID_PARAMETER);
1980 return FALSE;
1981 }
1982
1983 SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1984 SetWindowInfoRequest->OutputHandle = hConsoleOutput;
1985 SetWindowInfoRequest->Absolute = bAbsolute;
1986 SetWindowInfoRequest->WindowRect = *lpConsoleWindow;
1987
1988 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
1989 NULL,
1990 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo),
1991 sizeof(*SetWindowInfoRequest));
1992 if (!NT_SUCCESS(ApiMessage.Status))
1993 {
1994 BaseSetLastNTError(ApiMessage.Status);
1995 return FALSE;
1996 }
1997
1998 return TRUE;
1999 }
2000
2001
2002 /*
2003 * @implemented
2004 */
2005 BOOL
2006 WINAPI
2007 DECLSPEC_HOTPATCH
SetConsoleTextAttribute(HANDLE hConsoleOutput,WORD wAttributes)2008 SetConsoleTextAttribute(HANDLE hConsoleOutput,
2009 WORD wAttributes)
2010 {
2011 CONSOLE_API_MESSAGE ApiMessage;
2012 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest;
2013
2014 SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2015 SetTextAttribRequest->OutputHandle = hConsoleOutput;
2016 SetTextAttribRequest->Attributes = wAttributes;
2017
2018 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2019 NULL,
2020 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute),
2021 sizeof(*SetTextAttribRequest));
2022 if (!NT_SUCCESS(ApiMessage.Status))
2023 {
2024 BaseSetLastNTError(ApiMessage.Status);
2025 return FALSE;
2026 }
2027
2028 return TRUE;
2029 }
2030
2031
2032 static
2033 BOOL
AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)2034 AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2035 {
2036 PHANDLER_ROUTINE* NewCtrlHandlers = NULL;
2037
2038 if (HandlerRoutine == NULL)
2039 {
2040 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE;
2041 return TRUE;
2042 }
2043
2044 if (NrCtrlHandlers == NrAllocatedHandlers)
2045 {
2046 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(),
2047 0,
2048 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE));
2049 if (NewCtrlHandlers == NULL)
2050 {
2051 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2052 return FALSE;
2053 }
2054
2055 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers);
2056
2057 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers);
2058
2059 CtrlHandlers = NewCtrlHandlers;
2060 NrAllocatedHandlers += 4;
2061 }
2062
2063 ASSERT(NrCtrlHandlers < NrAllocatedHandlers);
2064
2065 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine;
2066 return TRUE;
2067 }
2068
2069
2070 static
2071 BOOL
RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)2072 RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine)
2073 {
2074 ULONG i;
2075
2076 if (HandlerRoutine == NULL)
2077 {
2078 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE;
2079 return TRUE;
2080 }
2081
2082 for (i = 0; i < NrCtrlHandlers; i++)
2083 {
2084 if (CtrlHandlers[i] == HandlerRoutine)
2085 {
2086 if (i < (NrCtrlHandlers - 1))
2087 {
2088 memmove(&CtrlHandlers[i],
2089 &CtrlHandlers[i+1],
2090 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE));
2091 }
2092
2093 NrCtrlHandlers--;
2094 return TRUE;
2095 }
2096 }
2097
2098 SetLastError(ERROR_INVALID_PARAMETER);
2099 return FALSE;
2100 }
2101
2102
2103 /*
2104 * @implemented
2105 */
2106 BOOL
2107 WINAPI
2108 DECLSPEC_HOTPATCH
SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,BOOL Add)2109 SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine,
2110 BOOL Add)
2111 {
2112 BOOL Ret;
2113
2114 RtlEnterCriticalSection(&ConsoleLock);
2115
2116 if (Add)
2117 Ret = AddConsoleCtrlHandler(HandlerRoutine);
2118 else
2119 Ret = RemoveConsoleCtrlHandler(HandlerRoutine);
2120
2121 RtlLeaveCriticalSection(&ConsoleLock);
2122 return Ret;
2123 }
2124
2125
2126 /*
2127 * @implemented
2128 */
2129 BOOL
2130 WINAPI
2131 DECLSPEC_HOTPATCH
GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,DWORD dwProcessGroupId)2132 GenerateConsoleCtrlEvent(DWORD dwCtrlEvent,
2133 DWORD dwProcessGroupId)
2134 {
2135 CONSOLE_API_MESSAGE ApiMessage;
2136 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &ApiMessage.Data.GenerateCtrlEventRequest;
2137
2138 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT)
2139 {
2140 SetLastError(ERROR_INVALID_PARAMETER);
2141 return FALSE;
2142 }
2143
2144 GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2145 GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent;
2146 GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId;
2147
2148 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2149 NULL,
2150 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent),
2151 sizeof(*GenerateCtrlEventRequest));
2152 if (!NT_SUCCESS(ApiMessage.Status))
2153 {
2154 BaseSetLastNTError(ApiMessage.Status);
2155 return FALSE;
2156 }
2157
2158 return TRUE;
2159 }
2160
2161
2162 static DWORD
IntGetConsoleTitle(LPVOID lpConsoleTitle,DWORD dwNumChars,BOOLEAN bUnicode)2163 IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode)
2164 {
2165 CONSOLE_API_MESSAGE ApiMessage;
2166 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
2167 PCSR_CAPTURE_BUFFER CaptureBuffer;
2168
2169 if (dwNumChars == 0) return 0;
2170
2171 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2172 TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2173 TitleRequest->Unicode = bUnicode;
2174
2175 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
2176 if (CaptureBuffer == NULL)
2177 {
2178 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2179 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2180 return 0;
2181 }
2182
2183 CsrAllocateMessagePointer(CaptureBuffer,
2184 TitleRequest->Length,
2185 (PVOID*)&TitleRequest->Title);
2186
2187 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2188 CaptureBuffer,
2189 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle),
2190 sizeof(*TitleRequest));
2191 if (!NT_SUCCESS(ApiMessage.Status))
2192 {
2193 CsrFreeCaptureBuffer(CaptureBuffer);
2194 BaseSetLastNTError(ApiMessage.Status);
2195 return 0;
2196 }
2197
2198 dwNumChars = TitleRequest->Length / (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2199
2200 if (dwNumChars > 0)
2201 {
2202 RtlCopyMemory(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length);
2203
2204 if (bUnicode)
2205 ((LPWSTR)lpConsoleTitle)[dwNumChars] = UNICODE_NULL;
2206 else
2207 ((LPSTR)lpConsoleTitle)[dwNumChars] = ANSI_NULL;
2208 }
2209
2210 CsrFreeCaptureBuffer(CaptureBuffer);
2211
2212 return dwNumChars;
2213 }
2214
2215
2216 /*
2217 * @implemented
2218 */
2219 DWORD
2220 WINAPI
2221 DECLSPEC_HOTPATCH
GetConsoleTitleW(LPWSTR lpConsoleTitle,DWORD nSize)2222 GetConsoleTitleW(LPWSTR lpConsoleTitle,
2223 DWORD nSize)
2224 {
2225 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE);
2226 }
2227
2228
2229 /*
2230 * @implemented
2231 */
2232 DWORD
2233 WINAPI
2234 DECLSPEC_HOTPATCH
GetConsoleTitleA(LPSTR lpConsoleTitle,DWORD nSize)2235 GetConsoleTitleA(LPSTR lpConsoleTitle,
2236 DWORD nSize)
2237 {
2238 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE);
2239 }
2240
2241
2242 static BOOL
IntSetConsoleTitle(CONST VOID * lpConsoleTitle,BOOLEAN bUnicode)2243 IntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode)
2244 {
2245 CONSOLE_API_MESSAGE ApiMessage;
2246 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest;
2247 PCSR_CAPTURE_BUFFER CaptureBuffer;
2248
2249 ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0);
2250
2251 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2252 TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR));
2253 TitleRequest->Unicode = bUnicode;
2254
2255 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length);
2256 if (CaptureBuffer == NULL)
2257 {
2258 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2259 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2260 return FALSE;
2261 }
2262
2263 CsrCaptureMessageBuffer(CaptureBuffer,
2264 (PVOID)lpConsoleTitle,
2265 TitleRequest->Length,
2266 (PVOID*)&TitleRequest->Title);
2267
2268 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2269 CaptureBuffer,
2270 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle),
2271 sizeof(*TitleRequest));
2272
2273 CsrFreeCaptureBuffer(CaptureBuffer);
2274
2275 if (!NT_SUCCESS(ApiMessage.Status))
2276 {
2277 BaseSetLastNTError(ApiMessage.Status);
2278 return FALSE;
2279 }
2280
2281 return TRUE;
2282 }
2283
2284 /*
2285 * @implemented
2286 */
2287 BOOL
2288 WINAPI
2289 DECLSPEC_HOTPATCH
SetConsoleTitleW(LPCWSTR lpConsoleTitle)2290 SetConsoleTitleW(LPCWSTR lpConsoleTitle)
2291 {
2292 return IntSetConsoleTitle(lpConsoleTitle, TRUE);
2293 }
2294
2295
2296 /*
2297 * @implemented
2298 */
2299 BOOL
2300 WINAPI
2301 DECLSPEC_HOTPATCH
SetConsoleTitleA(LPCSTR lpConsoleTitle)2302 SetConsoleTitleA(LPCSTR lpConsoleTitle)
2303 {
2304 return IntSetConsoleTitle(lpConsoleTitle, FALSE);
2305 }
2306
2307
2308 /*
2309 * @implemented
2310 */
2311 HANDLE
2312 WINAPI
CreateConsoleScreenBuffer(DWORD dwDesiredAccess,DWORD dwShareMode,CONST SECURITY_ATTRIBUTES * lpSecurityAttributes,DWORD dwFlags,LPVOID lpScreenBufferData)2313 CreateConsoleScreenBuffer(DWORD dwDesiredAccess,
2314 DWORD dwShareMode,
2315 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes,
2316 DWORD dwFlags,
2317 LPVOID lpScreenBufferData)
2318 {
2319 CONSOLE_API_MESSAGE ApiMessage;
2320 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest;
2321 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
2322 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = lpScreenBufferData;
2323
2324 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) ||
2325 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ||
2326 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) )
2327 {
2328 SetLastError(ERROR_INVALID_PARAMETER);
2329 return INVALID_HANDLE_VALUE;
2330 }
2331
2332 CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2333 CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess;
2334 CreateScreenBufferRequest->InheritHandle =
2335 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE);
2336 CreateScreenBufferRequest->ShareMode = dwShareMode;
2337 CreateScreenBufferRequest->ScreenBufferType = dwFlags;
2338
2339 if (dwFlags == CONSOLE_GRAPHICS_BUFFER)
2340 {
2341 if (CreateScreenBufferRequest->InheritHandle || GraphicsBufferInfo == NULL)
2342 {
2343 SetLastError(ERROR_INVALID_PARAMETER);
2344 return INVALID_HANDLE_VALUE;
2345 }
2346
2347 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo;
2348
2349 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength);
2350 if (CaptureBuffer == NULL)
2351 {
2352 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2353 return INVALID_HANDLE_VALUE;
2354 }
2355
2356 CsrCaptureMessageBuffer(CaptureBuffer,
2357 (PVOID)GraphicsBufferInfo->lpBitMapInfo,
2358 GraphicsBufferInfo->dwBitMapInfoLength,
2359 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo);
2360 }
2361
2362 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2363 CaptureBuffer,
2364 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer),
2365 sizeof(*CreateScreenBufferRequest));
2366
2367 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
2368
2369 if (!NT_SUCCESS(ApiMessage.Status))
2370 {
2371 BaseSetLastNTError(ApiMessage.Status);
2372 return INVALID_HANDLE_VALUE;
2373 }
2374
2375 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo)
2376 {
2377 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ;
2378 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap;
2379 }
2380
2381 return CreateScreenBufferRequest->OutputHandle;
2382 }
2383
2384
2385 /*
2386 * @implemented
2387 */
2388 UINT
2389 WINAPI
2390 DECLSPEC_HOTPATCH
GetConsoleCP(VOID)2391 GetConsoleCP(VOID)
2392 {
2393 CONSOLE_API_MESSAGE ApiMessage;
2394 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2395
2396 /* Get the Input Code Page */
2397 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2398 GetConsoleCPRequest->OutputCP = FALSE;
2399
2400 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2401 NULL,
2402 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2403 sizeof(*GetConsoleCPRequest));
2404 if (!NT_SUCCESS(ApiMessage.Status))
2405 {
2406 BaseSetLastNTError(ApiMessage.Status);
2407 return 0;
2408 }
2409
2410 return GetConsoleCPRequest->CodePage;
2411 }
2412
2413
2414 /*
2415 * @implemented
2416 */
2417 BOOL
2418 WINAPI
2419 DECLSPEC_HOTPATCH
SetConsoleCP(UINT wCodePageID)2420 SetConsoleCP(UINT wCodePageID)
2421 {
2422 CONSOLE_API_MESSAGE ApiMessage;
2423 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2424
2425 /* Set the Input Code Page */
2426 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2427 SetConsoleCPRequest->CodePage = wCodePageID;
2428 SetConsoleCPRequest->OutputCP = FALSE;
2429 /* SetConsoleCPRequest->EventHandle; */
2430
2431 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2432 NULL,
2433 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2434 sizeof(*SetConsoleCPRequest));
2435 if (!NT_SUCCESS(ApiMessage.Status))
2436 {
2437 BaseSetLastNTError(ApiMessage.Status);
2438 return FALSE;
2439 }
2440
2441 return TRUE;
2442 }
2443
2444
2445 /*
2446 * @implemented
2447 */
2448 UINT
2449 WINAPI
2450 DECLSPEC_HOTPATCH
GetConsoleOutputCP(VOID)2451 GetConsoleOutputCP(VOID)
2452 {
2453 CONSOLE_API_MESSAGE ApiMessage;
2454 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest;
2455
2456 /* Get the Output Code Page */
2457 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2458 GetConsoleCPRequest->OutputCP = TRUE;
2459
2460 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2461 NULL,
2462 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP),
2463 sizeof(*GetConsoleCPRequest));
2464 if (!NT_SUCCESS(ApiMessage.Status))
2465 {
2466 BaseSetLastNTError(ApiMessage.Status);
2467 return 0;
2468 }
2469
2470 return GetConsoleCPRequest->CodePage;
2471 }
2472
2473
2474 /*
2475 * @implemented
2476 */
2477 BOOL
2478 WINAPI
2479 DECLSPEC_HOTPATCH
SetConsoleOutputCP(UINT wCodePageID)2480 SetConsoleOutputCP(UINT wCodePageID)
2481 {
2482 CONSOLE_API_MESSAGE ApiMessage;
2483 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest;
2484
2485 /* Set the Output Code Page */
2486 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2487 SetConsoleCPRequest->CodePage = wCodePageID;
2488 SetConsoleCPRequest->OutputCP = TRUE;
2489 /* SetConsoleCPRequest->EventHandle; */
2490
2491 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2492 NULL,
2493 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP),
2494 sizeof(*SetConsoleCPRequest));
2495 if (!NT_SUCCESS(ApiMessage.Status))
2496 {
2497 BaseSetLastNTError(ApiMessage.Status);
2498 return FALSE;
2499 }
2500
2501 /* Sync the current thread's LangId with the console's one */
2502 SetTEBLangID();
2503
2504 return TRUE;
2505 }
2506
2507
2508 /*
2509 * @implemented
2510 */
2511 DWORD
2512 WINAPI
GetConsoleProcessList(LPDWORD lpdwProcessList,DWORD dwProcessCount)2513 GetConsoleProcessList(LPDWORD lpdwProcessList,
2514 DWORD dwProcessCount)
2515 {
2516 CONSOLE_API_MESSAGE ApiMessage;
2517 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest;
2518 PCSR_CAPTURE_BUFFER CaptureBuffer;
2519 ULONG nProcesses = 0;
2520
2521 if (lpdwProcessList == NULL || dwProcessCount == 0)
2522 {
2523 SetLastError(ERROR_INVALID_PARAMETER);
2524 return 0;
2525 }
2526
2527 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD));
2528 if (CaptureBuffer == NULL)
2529 {
2530 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
2531 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2532 return 0;
2533 }
2534
2535 GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2536 GetProcessListRequest->ProcessCount = dwProcessCount;
2537
2538 CsrAllocateMessagePointer(CaptureBuffer,
2539 dwProcessCount * sizeof(DWORD),
2540 (PVOID*)&GetProcessListRequest->ProcessIdsList);
2541
2542 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2543 CaptureBuffer,
2544 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList),
2545 sizeof(*GetProcessListRequest));
2546 if (!NT_SUCCESS(ApiMessage.Status))
2547 {
2548 BaseSetLastNTError(ApiMessage.Status);
2549 }
2550 else
2551 {
2552 nProcesses = GetProcessListRequest->ProcessCount;
2553 if (dwProcessCount >= nProcesses)
2554 {
2555 RtlCopyMemory(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD));
2556 }
2557 }
2558
2559 CsrFreeCaptureBuffer(CaptureBuffer);
2560 return nProcesses;
2561 }
2562
2563
2564 /*
2565 * @implemented
2566 */
2567 BOOL
2568 WINAPI
GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)2569 GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo)
2570 {
2571 CONSOLE_API_MESSAGE ApiMessage;
2572 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &ApiMessage.Data.GetSelectionInfoRequest;
2573
2574 if (lpConsoleSelectionInfo == NULL)
2575 {
2576 SetLastError(ERROR_INVALID_PARAMETER);
2577 return FALSE;
2578 }
2579
2580 GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2581
2582 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2583 NULL,
2584 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo),
2585 sizeof(*GetSelectionInfoRequest));
2586 if (!NT_SUCCESS(ApiMessage.Status))
2587 {
2588 BaseSetLastNTError(ApiMessage.Status);
2589 return FALSE;
2590 }
2591
2592 *lpConsoleSelectionInfo = GetSelectionInfoRequest->Info;
2593
2594 return TRUE;
2595 }
2596
2597
2598 /*
2599 * @implemented
2600 * @note Strongly inspired by AllocConsole.
2601 */
2602 static BOOL
IntAttachConsole(DWORD ProcessId,LPTHREAD_START_ROUTINE CtrlRoutine,LPTHREAD_START_ROUTINE PropRoutine,PCONSOLE_START_INFO ConsoleStartInfo)2603 IntAttachConsole(DWORD ProcessId,
2604 LPTHREAD_START_ROUTINE CtrlRoutine,
2605 LPTHREAD_START_ROUTINE PropRoutine,
2606 PCONSOLE_START_INFO ConsoleStartInfo)
2607 {
2608 BOOL Success = TRUE;
2609 NTSTATUS Status;
2610
2611 CONSOLE_API_MESSAGE ApiMessage;
2612 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest;
2613 PCSR_CAPTURE_BUFFER CaptureBuffer;
2614
2615 AttachConsoleRequest->ProcessId = ProcessId;
2616 AttachConsoleRequest->CtrlRoutine = CtrlRoutine;
2617 AttachConsoleRequest->PropRoutine = PropRoutine;
2618
2619 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO));
2620 if (CaptureBuffer == NULL)
2621 {
2622 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
2623 Success = FALSE;
2624 goto Quit;
2625 }
2626
2627 CsrCaptureMessageBuffer(CaptureBuffer,
2628 ConsoleStartInfo,
2629 sizeof(CONSOLE_START_INFO),
2630 (PVOID*)&AttachConsoleRequest->ConsoleStartInfo);
2631
2632 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2633 CaptureBuffer,
2634 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach),
2635 sizeof(*AttachConsoleRequest));
2636 if (!NT_SUCCESS(ApiMessage.Status))
2637 {
2638 BaseSetLastNTError(ApiMessage.Status);
2639 Success = FALSE;
2640 goto Quit;
2641 }
2642
2643 // Is AttachConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ????
2644 Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS,
2645 AttachConsoleRequest->ConsoleStartInfo->InitEvents,
2646 WaitAny, FALSE, NULL);
2647 if (!NT_SUCCESS(Status))
2648 {
2649 BaseSetLastNTError(Status);
2650 Success = FALSE;
2651 goto Quit;
2652 }
2653
2654 NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]);
2655 NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]);
2656 if (Status != INIT_SUCCESS)
2657 {
2658 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL;
2659 Success = FALSE;
2660 }
2661 else
2662 {
2663 RtlCopyMemory(ConsoleStartInfo,
2664 AttachConsoleRequest->ConsoleStartInfo,
2665 sizeof(CONSOLE_START_INFO));
2666 Success = TRUE;
2667 }
2668
2669 Quit:
2670 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
2671 return Success;
2672 }
2673
2674 BOOL
2675 WINAPI
AttachConsole(DWORD dwProcessId)2676 AttachConsole(DWORD dwProcessId)
2677 {
2678 BOOL Success;
2679 CONSOLE_START_INFO ConsoleStartInfo;
2680 DWORD dummy;
2681
2682 RtlEnterCriticalSection(&ConsoleLock);
2683
2684 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle)
2685 {
2686 DPRINT1("AttachConsole: Attaching a console to a process already having one\n");
2687 SetLastError(ERROR_ACCESS_DENIED);
2688 Success = FALSE;
2689 goto Quit;
2690 }
2691
2692 /* Set up the console properties */
2693 SetUpConsoleInfo(FALSE,
2694 &dummy,
2695 NULL,
2696 &dummy,
2697 NULL,
2698 &ConsoleStartInfo);
2699
2700 Success = IntAttachConsole(dwProcessId,
2701 ConsoleControlDispatcher,
2702 PropDialogHandler,
2703 &ConsoleStartInfo);
2704 if (Success)
2705 {
2706 /* Set up the handles */
2707 SetUpHandles(&ConsoleStartInfo);
2708 InputWaitHandle = ConsoleStartInfo.InputWaitHandle;
2709
2710 /* Initialize Console Ctrl Handling */
2711 InitializeCtrlHandling();
2712
2713 /* Sync the current thread's LangId with the console's one */
2714 SetTEBLangID();
2715 }
2716
2717 Quit:
2718 RtlLeaveCriticalSection(&ConsoleLock);
2719 return Success;
2720 }
2721
2722
2723 /*
2724 * @implemented
2725 */
2726 HWND
2727 WINAPI
2728 DECLSPEC_HOTPATCH
GetConsoleWindow(VOID)2729 GetConsoleWindow(VOID)
2730 {
2731 CONSOLE_API_MESSAGE ApiMessage;
2732 PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest;
2733
2734 GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2735
2736 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2737 NULL,
2738 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow),
2739 sizeof(*GetWindowRequest));
2740 if (!NT_SUCCESS(ApiMessage.Status))
2741 {
2742 BaseSetLastNTError(ApiMessage.Status);
2743 return (HWND)NULL;
2744 }
2745
2746 return GetWindowRequest->WindowHandle;
2747 }
2748
2749
2750 /*
2751 * @implemented
2752 */
2753 BOOL
2754 WINAPI
2755 DECLSPEC_HOTPATCH
SetConsoleIcon(HICON hIcon)2756 SetConsoleIcon(HICON hIcon)
2757 {
2758 CONSOLE_API_MESSAGE ApiMessage;
2759 PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest;
2760
2761 SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
2762 SetIconRequest->IconHandle = hIcon;
2763
2764 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
2765 NULL,
2766 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon),
2767 sizeof(*SetIconRequest));
2768 if (!NT_SUCCESS(ApiMessage.Status))
2769 {
2770 BaseSetLastNTError(ApiMessage.Status);
2771 return FALSE;
2772 }
2773
2774 return TRUE;
2775 }
2776
2777
2778 /******************************************************************************
2779 * \name SetConsoleInputExeNameW
2780 * \brief Sets the console input file name from a unicode string.
2781 * \param lpExeName Pointer to a unicode string with the name.
2782 * \return TRUE if successful, FALSE if unsuccessful.
2783 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255,
2784 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2785 */
2786 BOOL
2787 WINAPI
2788 DECLSPEC_HOTPATCH
SetConsoleInputExeNameW(IN LPCWSTR lpExeName)2789 SetConsoleInputExeNameW(IN LPCWSTR lpExeName)
2790 {
2791 DWORD ExeLength;
2792
2793 ExeLength = lstrlenW(lpExeName);
2794 if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH))
2795 {
2796 /* Fail if string is empty or too long */
2797 SetLastError(ERROR_INVALID_PARAMETER);
2798 return FALSE;
2799 }
2800
2801 RtlEnterCriticalSection(&ExeNameLock);
2802 _SEH2_TRY
2803 {
2804 /* Set the input EXE name, not NULL terminated */
2805 RtlCopyMemory(ExeNameBuffer, lpExeName, ExeLength * sizeof(WCHAR));
2806 ExeNameLength = (USHORT)ExeLength;
2807 }
2808 _SEH2_FINALLY
2809 {
2810 RtlLeaveCriticalSection(&ExeNameLock);
2811 }
2812 _SEH2_END;
2813
2814 return TRUE;
2815 }
2816
2817
2818 /******************************************************************************
2819 * \name SetConsoleInputExeNameA
2820 * \brief Sets the console input file name from an ansi string.
2821 * \param lpExeName Pointer to an ansi string with the name.
2822 * \return TRUE if successful, FALSE if unsuccessful.
2823 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255,
2824 * the function fails and sets last error to ERROR_INVALID_PARAMETER.
2825 */
2826 BOOL
2827 WINAPI
2828 DECLSPEC_HOTPATCH
SetConsoleInputExeNameA(IN LPCSTR lpExeName)2829 SetConsoleInputExeNameA(IN LPCSTR lpExeName)
2830 {
2831 NTSTATUS Status;
2832 #ifdef USE_TEB_STATIC_USTR
2833 PUNICODE_STRING ExeNameU;
2834 #else
2835 UNICODE_STRING ExeNameU;
2836 #endif
2837 ANSI_STRING ExeNameA;
2838 #ifndef USE_TEB_STATIC_USTR
2839 WCHAR Buffer[EXENAME_LENGTH];
2840 #endif
2841
2842 #ifdef USE_TEB_STATIC_USTR
2843 /*
2844 * Use the TEB static UNICODE string for storage. It is already
2845 * initialized at process creation time by the Memory Manager.
2846 */
2847 ExeNameU = &NtCurrentTeb()->StaticUnicodeString;
2848 #endif
2849
2850 /* Initialize string for conversion */
2851 RtlInitAnsiString(&ExeNameA, lpExeName);
2852
2853 #if 1
2854 if ((ExeNameA.Length == 0) || (ExeNameA.Length >= EXENAME_LENGTH))
2855 {
2856 /* Fail if string is empty or too long */
2857 SetLastError(ERROR_INVALID_PARAMETER);
2858 return FALSE;
2859 }
2860 #endif
2861 #ifndef USE_TEB_STATIC_USTR
2862 ExeNameU.Length = 0;
2863 ExeNameU.MaximumLength = (USHORT)sizeof(Buffer);
2864 ExeNameU.Buffer = Buffer;
2865 #endif
2866
2867 #ifdef USE_TEB_STATIC_USTR
2868 Status = RtlAnsiStringToUnicodeString(ExeNameU, &ExeNameA, FALSE);
2869 #else
2870 Status = RtlAnsiStringToUnicodeString(&ExeNameU, &ExeNameA, FALSE);
2871 #endif
2872 if (!NT_SUCCESS(Status))
2873 {
2874 /* Fail if string is empty or too long */
2875 if (Status == STATUS_BUFFER_OVERFLOW)
2876 SetLastError(ERROR_FILENAME_EXCED_RANGE);
2877 else
2878 SetLastError(ERROR_INVALID_PARAMETER);
2879
2880 return FALSE;
2881 }
2882
2883 #ifdef USE_TEB_STATIC_USTR
2884 return SetConsoleInputExeNameW(ExeNameU->Buffer);
2885 #else
2886 return SetConsoleInputExeNameW(ExeNameU.Buffer);
2887 #endif
2888 }
2889
2890
2891 /******************************************************************************
2892 * \name GetConsoleInputExeNameW
2893 * \brief Retrieves the console input file name as unicode string.
2894 * \param nBufferLength Length of the buffer in WCHARs.
2895 * Specify 0 to receive the needed buffer length.
2896 * \param lpBuffer Pointer to a buffer that receives the string.
2897 * \return Needed buffer size if \p nBufferLength is 0.
2898 * Otherwise 1 if successful, 2 if buffer is too small.
2899 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2900 * is not big enough.
2901 */
2902 DWORD
2903 WINAPI
2904 DECLSPEC_HOTPATCH
GetConsoleInputExeNameW(IN DWORD nBufferLength,OUT LPWSTR lpExeName)2905 GetConsoleInputExeNameW(IN DWORD nBufferLength,
2906 OUT LPWSTR lpExeName)
2907 {
2908 if (nBufferLength <= ExeNameLength)
2909 {
2910 /* Buffer is not large enough! Return the correct size. */
2911 SetLastError(ERROR_BUFFER_OVERFLOW);
2912 return ExeNameLength + 1;
2913 }
2914
2915 RtlEnterCriticalSection(&ExeNameLock);
2916 _SEH2_TRY
2917 {
2918 /* Copy the input EXE name and NULL-terminate it */
2919 RtlCopyMemory(lpExeName, ExeNameBuffer, ExeNameLength * sizeof(WCHAR));
2920 lpExeName[ExeNameLength] = UNICODE_NULL;
2921 }
2922 _SEH2_FINALLY
2923 {
2924 RtlLeaveCriticalSection(&ExeNameLock);
2925 }
2926 _SEH2_END;
2927
2928 return TRUE;
2929 }
2930
2931
2932 /******************************************************************************
2933 * \name GetConsoleInputExeNameA
2934 * \brief Retrieves the console input file name as ansi string.
2935 * \param nBufferLength Length of the buffer in CHARs.
2936 * \param lpBuffer Pointer to a buffer that receives the string.
2937 * \return 1 if successful, 2 if buffer is too small.
2938 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer
2939 * is not big enough. The buffer receives as much characters as fit.
2940 */
2941 DWORD
2942 WINAPI
2943 DECLSPEC_HOTPATCH
GetConsoleInputExeNameA(IN DWORD nBufferLength,OUT LPSTR lpExeName)2944 GetConsoleInputExeNameA(IN DWORD nBufferLength,
2945 OUT LPSTR lpExeName)
2946 {
2947 NTSTATUS Status;
2948 DWORD ExeLength;
2949 UNICODE_STRING BufferU;
2950 ANSI_STRING BufferA;
2951 WCHAR Buffer[EXENAME_LENGTH];
2952
2953 /* Get the UNICODE name */
2954 ExeLength = GetConsoleInputExeNameW(EXENAME_LENGTH, Buffer);
2955
2956 if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH))
2957 return ExeLength;
2958
2959 /* Initialize the strings for conversion */
2960 RtlInitUnicodeString(&BufferU, Buffer);
2961 BufferA.Length = 0;
2962 BufferA.MaximumLength = (USHORT)nBufferLength;
2963 BufferA.Buffer = lpExeName;
2964
2965 /* Convert UNICODE name to ANSI, copying as much chars as it can fit */
2966 Status = RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE);
2967 if (!NT_SUCCESS(Status))
2968 {
2969 if (Status == STATUS_BUFFER_OVERFLOW)
2970 {
2971 SetLastError(ERROR_BUFFER_OVERFLOW);
2972 return ExeLength + 1;
2973 }
2974 SetLastError(ERROR_INVALID_PARAMETER);
2975 }
2976
2977 return ExeLength;
2978 }
2979
2980 BOOL
2981 WINAPI
GetConsoleCharType(HANDLE hConsole,COORD Coord,PDWORD Type)2982 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type)
2983 {
2984 STUB;
2985 return FALSE;
2986 }
2987
2988 BOOL
2989 WINAPI
2990 DECLSPEC_HOTPATCH
GetConsoleCursorMode(HANDLE hConsole,PBOOL pUnknown1,PBOOL pUnknown2)2991 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2)
2992 {
2993 STUB;
2994 return FALSE;
2995 }
2996
2997 BOOL
2998 WINAPI
2999 DECLSPEC_HOTPATCH
SetConsoleCursorMode(HANDLE hConsole,BOOL Unknown1,BOOL Unknown2)3000 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2)
3001 {
3002 STUB;
3003 return FALSE;
3004 }
3005
3006 BOOL
3007 WINAPI
3008 DECLSPEC_HOTPATCH
GetConsoleNlsMode(HANDLE hConsole,LPDWORD lpMode)3009 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode)
3010 {
3011 STUB;
3012 return FALSE;
3013 }
3014
3015 BOOL
3016 WINAPI
3017 DECLSPEC_HOTPATCH
SetConsoleNlsMode(HANDLE hConsole,DWORD dwMode)3018 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode)
3019 {
3020 STUB;
3021 return FALSE;
3022 }
3023
3024 BOOL
3025 WINAPI
3026 DECLSPEC_HOTPATCH
SetConsoleLocalEUDC(DWORD Unknown1,DWORD Unknown2,DWORD Unknown3,DWORD Unknown4)3027 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4)
3028 {
3029 STUB;
3030 return FALSE;
3031 }
3032
3033 static BOOL
IntRegisterConsoleIME(_In_ HWND hWnd,_In_ DWORD dwThreadId,_In_opt_ SIZE_T cbDesktop,_In_opt_ PWSTR pDesktop,_Out_opt_ PDWORD pdwAttachToThreadId)3034 IntRegisterConsoleIME(
3035 _In_ HWND hWnd,
3036 _In_ DWORD dwThreadId,
3037 _In_opt_ SIZE_T cbDesktop,
3038 _In_opt_ PWSTR pDesktop,
3039 _Out_opt_ PDWORD pdwAttachToThreadId)
3040 {
3041 CONSOLE_API_MESSAGE ApiMessage;
3042 PCONSOLE_REGISTERCONSOLEIME RegisterConsoleIME = &ApiMessage.Data.RegisterConsoleIME;
3043 PCSR_CAPTURE_BUFFER CaptureBuffer;
3044
3045 if (!cbDesktop || !pDesktop)
3046 {
3047 pDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Buffer;
3048 cbDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Length;
3049 }
3050
3051 cbDesktop = min(cbDesktop, (MAX_PATH + 1) * sizeof(WCHAR));
3052
3053 RegisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
3054 RegisterConsoleIME->hWnd = hWnd;
3055 RegisterConsoleIME->dwThreadId = dwThreadId;
3056 RegisterConsoleIME->cbDesktop = cbDesktop;
3057
3058 CaptureBuffer = CsrAllocateCaptureBuffer(1, cbDesktop);
3059 if (!CaptureBuffer)
3060 {
3061 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
3062 return FALSE;
3063 }
3064
3065 CsrCaptureMessageBuffer(CaptureBuffer,
3066 pDesktop,
3067 cbDesktop,
3068 (PVOID*)&RegisterConsoleIME->pDesktop);
3069
3070 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
3071 CaptureBuffer,
3072 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepRegisterConsoleIME),
3073 sizeof(*RegisterConsoleIME));
3074
3075 CsrFreeCaptureBuffer(CaptureBuffer);
3076
3077 if (!NT_SUCCESS(ApiMessage.Status))
3078 {
3079 BaseSetLastNTError(ApiMessage.Status);
3080 return FALSE;
3081 }
3082
3083 if (pdwAttachToThreadId)
3084 {
3085 _SEH2_TRY
3086 {
3087 *pdwAttachToThreadId = RegisterConsoleIME->dwAttachToThreadId;
3088 }
3089 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3090 {
3091 BaseSetLastNTError(STATUS_ACCESS_VIOLATION);
3092 _SEH2_YIELD(return FALSE);
3093 }
3094 _SEH2_END;
3095 }
3096
3097 return TRUE;
3098 }
3099
3100 static BOOL
IntUnregisterConsoleIME(_In_ DWORD dwThreadId)3101 IntUnregisterConsoleIME(
3102 _In_ DWORD dwThreadId)
3103 {
3104 CONSOLE_API_MESSAGE ApiMessage;
3105 PCONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME = &ApiMessage.Data.UnregisterConsoleIME;
3106
3107 UnregisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
3108 UnregisterConsoleIME->dwThreadId = dwThreadId;
3109
3110 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
3111 NULL,
3112 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepUnregisterConsoleIME),
3113 sizeof(*UnregisterConsoleIME));
3114 if (!NT_SUCCESS(ApiMessage.Status))
3115 {
3116 BaseSetLastNTError(ApiMessage.Status);
3117 return FALSE;
3118 }
3119
3120 return TRUE;
3121 }
3122
3123 /* This function is called by CONIME.EXE */
3124 BOOL
3125 WINAPI
3126 DECLSPEC_HOTPATCH
RegisterConsoleIME(_In_ HWND hWnd,_Out_opt_ LPDWORD pdwAttachToThreadId)3127 RegisterConsoleIME(
3128 _In_ HWND hWnd,
3129 _Out_opt_ LPDWORD pdwAttachToThreadId)
3130 {
3131 return IntRegisterConsoleIME(hWnd,
3132 GetCurrentThreadId(),
3133 0,
3134 NULL,
3135 pdwAttachToThreadId);
3136 }
3137
3138 BOOL
3139 WINAPI
3140 DECLSPEC_HOTPATCH
RegisterConsoleOS2(BOOL bUnknown)3141 RegisterConsoleOS2(BOOL bUnknown)
3142 {
3143 STUB;
3144 return FALSE;
3145 }
3146
3147 BOOL
3148 WINAPI
3149 DECLSPEC_HOTPATCH
SetConsoleOS2OemFormat(BOOL bUnknown)3150 SetConsoleOS2OemFormat(BOOL bUnknown)
3151 {
3152 STUB;
3153 return FALSE;
3154 }
3155
3156 /* This function is called by CONIME.EXE */
3157 BOOL
3158 WINAPI
3159 DECLSPEC_HOTPATCH
UnregisterConsoleIME(VOID)3160 UnregisterConsoleIME(VOID)
3161 {
3162 return IntUnregisterConsoleIME(GetCurrentThreadId());
3163 }
3164
3165 /**
3166 * @brief
3167 * Internal helper function used to synchronize the current
3168 * thread's language ID with the one from the console.
3169 **/
3170 VOID
SetTEBLangID(VOID)3171 SetTEBLangID(VOID)
3172 {
3173 CONSOLE_API_MESSAGE ApiMessage;
3174 PCONSOLE_GETLANGID LangIdRequest = &ApiMessage.Data.LangIdRequest;
3175
3176 /* Retrieve the "best-suited" language ID corresponding
3177 * to the active console output code page. */
3178 LangIdRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
3179
3180 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
3181 NULL,
3182 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLangId),
3183 sizeof(*LangIdRequest));
3184 if (!NT_SUCCESS(ApiMessage.Status))
3185 {
3186 /*
3187 * No best console language ID: keep the current thread's one.
3188 * Since this internal function only modifies an optional setting,
3189 * don't set any last error, as it could otherwise mess with the
3190 * main last error set by the caller.
3191 */
3192 return;
3193 }
3194
3195 /*
3196 * We succeeded, set the current thread's language ID by
3197 * modifying its locale -- Windows <= 2003 does not have
3198 * the concept of a separate thread UI language.
3199 * Ignore the returned value.
3200 */
3201 if (!SetThreadLocale(MAKELCID(LangIdRequest->LangId, SORT_DEFAULT)))
3202 {
3203 DPRINT1("SetTEBLangID: Could not set thread locale to console lang ID %lu\n",
3204 LangIdRequest->LangId);
3205 }
3206 }
3207
3208 static
3209 BOOL
IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName,IN BOOL bAnsi)3210 IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName,
3211 IN BOOL bAnsi)
3212 {
3213 CONSOLE_API_MESSAGE ApiMessage;
3214 PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest;
3215
3216 /* Set up the data to send to the Console Server */
3217 GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
3218 GetKbdLayoutNameRequest->Ansi = bAnsi;
3219
3220 /* Call the server */
3221 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
3222 NULL,
3223 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName),
3224 sizeof(*GetKbdLayoutNameRequest));
3225
3226 /* Check for success */
3227 if (!NT_SUCCESS(ApiMessage.Status))
3228 {
3229 BaseSetLastNTError(ApiMessage.Status);
3230 return FALSE;
3231 }
3232
3233 /* Retrieve the results */
3234 _SEH2_TRY
3235 {
3236 /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */
3237 if (bAnsi)
3238 strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
3239 else
3240 wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH);
3241 }
3242 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
3243 {
3244 SetLastError(ERROR_INVALID_ACCESS);
3245 _SEH2_YIELD(return FALSE);
3246 }
3247 _SEH2_END;
3248
3249 return TRUE;
3250 }
3251
3252 /*
3253 * @implemented (undocumented)
3254 */
3255 BOOL
3256 WINAPI
3257 DECLSPEC_HOTPATCH
GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName)3258 GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName)
3259 {
3260 return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE);
3261 }
3262
3263 /*
3264 * @implemented (undocumented)
3265 */
3266 BOOL
3267 WINAPI
3268 DECLSPEC_HOTPATCH
GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName)3269 GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName)
3270 {
3271 return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE);
3272 }
3273
3274 /*
3275 * @implemented
3276 */
3277 DWORD
3278 WINAPI
SetLastConsoleEventActive(VOID)3279 SetLastConsoleEventActive(VOID)
3280 {
3281 CONSOLE_API_MESSAGE ApiMessage;
3282 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest;
3283
3284 /* Set the flag used by the console control dispatcher */
3285 LastCloseNotify = TRUE;
3286
3287 /* Set up the input arguments */
3288 NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
3289
3290 /* Call CSRSS; just return the NTSTATUS cast to DWORD */
3291 return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
3292 NULL,
3293 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose),
3294 sizeof(*NotifyLastCloseRequest));
3295 }
3296
3297 /* EOF */
3298