Reactos
at master 3303 lines 96 kB view raw
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 20extern RTL_CRITICAL_SECTION ConsoleLock; 21extern BOOLEAN ConsoleInitialized; 22 23/* Console reserved "file" names */ 24static LPCWSTR BaseConFileName = CONSOLE_FILE_NAME; 25static LPCWSTR BaseConInputFileName = CONSOLE_INPUT_FILE_NAME; 26static LPCWSTR BaseConOutputFileName = CONSOLE_OUTPUT_FILE_NAME; 27 28/* Console Control handling */ 29static PHANDLER_ROUTINE InitialHandler[1]; 30static PHANDLER_ROUTINE* CtrlHandlers; 31static ULONG NrCtrlHandlers; 32static ULONG NrAllocatedHandlers; 33static BOOLEAN LastCloseNotify = FALSE; 34 35extern BOOL WINAPI IsDebuggerPresent(VOID); 36 37/* Console Input facilities */ 38HANDLE InputWaitHandle = INVALID_HANDLE_VALUE; 39 40#define EXENAME_LENGTH (255 + 1) 41static RTL_CRITICAL_SECTION ExeNameLock; 42static BOOLEAN ExeNameInitialized; 43static WCHAR ExeNameBuffer[EXENAME_LENGTH]; // NULL-terminated 44static USHORT ExeNameLength; // Count in number of characters without NULL 45static WCHAR StartDirBuffer[MAX_PATH + 1]; // NULL-terminated 46static USHORT StartDirLength; // Count in number of characters without NULL 47 48 49/* Default Console Control Handler ********************************************/ 50 51static BOOL 52WINAPI 53DefaultConsoleCtrlHandler(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 87DWORD 88WINAPI 89ConsoleControlDispatcher(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 203VOID 204InitializeCtrlHandling(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 215VOID 216InitExeName(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 */ 263VOID 264SetUpAppName(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 315USHORT 316GetCurrentExeName(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 344LPCWSTR 345IntCheckForConsoleFileName(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 */ 393HMENU 394WINAPI 395DECLSPEC_HOTPATCH 396ConsoleMenuControl(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 */ 421HANDLE 422WINAPI 423DECLSPEC_HOTPATCH 424DuplicateConsoleHandle(HANDLE hSourceHandle, 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 = hSourceHandle; 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 */ 463BOOL 464WINAPI 465GetConsoleHandleInformation(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 */ 493BOOL 494WINAPI 495SetConsoleHandleInformation(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 */ 524BOOL 525WINAPI 526GetConsoleDisplayMode(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 https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 558 */ 559DWORD 560WINAPI 561GetConsoleFontInfo(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 */ 610COORD 611WINAPI 612DECLSPEC_HOTPATCH 613GetConsoleFontSize(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 */ 641BOOL 642WINAPI 643GetConsoleHardwareState(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 */ 681HANDLE 682WINAPI 683GetConsoleInputWaitHandle(VOID) 684{ 685 return InputWaitHandle; 686} 687 688 689/* 690 * @implemented 691 */ 692BOOL 693WINAPI 694GetCurrentConsoleFont(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 https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 725 */ 726DWORD 727WINAPI 728DECLSPEC_HOTPATCH 729GetNumberOfConsoleFonts(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 */ 754BOOL 755WINAPI 756InvalidateConsoleDIBits(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 */ 789HANDLE 790WINAPI 791OpenConsoleW(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 */ 845BOOL 846WINAPI 847DECLSPEC_HOTPATCH 848SetConsoleCursor(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 */ 875BOOL 876WINAPI 877SetConsoleDisplayMode(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 https://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 911 */ 912BOOL 913WINAPI 914DECLSPEC_HOTPATCH 915SetConsoleFont(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 */ 942BOOL 943WINAPI 944SetConsoleHardwareState(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 */ 975BOOL 976WINAPI 977DECLSPEC_HOTPATCH 978SetConsoleKeyShortcuts( 979 _In_ BOOL bSet, 980 _In_ BYTE bReserveKeys, 981 _In_reads_(dwNumAppKeys) LPAPPKEY lpAppKeys, 982 _In_ DWORD dwNumAppKeys) 983{ 984 DPRINT1("SetConsoleKeyShortcuts(%lu, 0x%x, 0x%p, 0x%x) UNIMPLEMENTED!\n", 985 bSet, bReserveKeys, lpAppKeys, dwNumAppKeys); 986 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 987 return FALSE; 988} 989 990 991/* 992 * @implemented (Undocumented) 993 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php 994 * Does nothing, returns TRUE only. Checked on Windows Server 2003. 995 */ 996BOOL 997WINAPI 998SetConsoleMaximumWindowSize(HANDLE hConsoleOutput, 999 COORD dwMaximumSize) 1000{ 1001 DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n", 1002 hConsoleOutput, dwMaximumSize.X, dwMaximumSize.Y); 1003 return TRUE; 1004} 1005 1006 1007/* 1008 * @implemented (Undocumented) 1009 */ 1010BOOL 1011WINAPI 1012DECLSPEC_HOTPATCH 1013SetConsoleMenuClose(BOOL bEnable) 1014{ 1015 CONSOLE_API_MESSAGE ApiMessage; 1016 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest; 1017 1018 SetMenuCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1019 SetMenuCloseRequest->Enable = bEnable; 1020 1021 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1022 NULL, 1023 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose), 1024 sizeof(*SetMenuCloseRequest)); 1025 if (!NT_SUCCESS(ApiMessage.Status)) 1026 { 1027 BaseSetLastNTError(ApiMessage.Status); 1028 return FALSE; 1029 } 1030 1031 return TRUE; 1032} 1033 1034 1035/* 1036 * @implemented (Undocumented) 1037 * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844 (DEAD_LINK) 1038 * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52 1039 */ 1040BOOL 1041WINAPI 1042DECLSPEC_HOTPATCH 1043SetConsolePalette(HANDLE hConsoleOutput, 1044 HPALETTE hPalette, 1045 UINT dwUsage) 1046{ 1047 CONSOLE_API_MESSAGE ApiMessage; 1048 PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest; 1049 1050 SetPaletteRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1051 SetPaletteRequest->OutputHandle = hConsoleOutput; 1052 SetPaletteRequest->PaletteHandle = hPalette; 1053 SetPaletteRequest->Usage = dwUsage; 1054 1055 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1056 NULL, 1057 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetPalette), 1058 sizeof(*SetPaletteRequest)); 1059 if (!NT_SUCCESS(ApiMessage.Status)) 1060 { 1061 BaseSetLastNTError(ApiMessage.Status); 1062 return FALSE; 1063 } 1064 1065 return TRUE; 1066} 1067 1068/* 1069 * @implemented (Undocumented) 1070 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php 1071 */ 1072INT 1073WINAPI 1074DECLSPEC_HOTPATCH 1075ShowConsoleCursor(HANDLE hConsoleOutput, 1076 BOOL bShow) 1077{ 1078 CONSOLE_API_MESSAGE ApiMessage; 1079 PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest; 1080 1081 ShowCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1082 ShowCursorRequest->OutputHandle = hConsoleOutput; 1083 ShowCursorRequest->Show = bShow; 1084 ShowCursorRequest->RefCount = 0; 1085 1086 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1087 NULL, 1088 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepShowCursor), 1089 sizeof(*ShowCursorRequest)); 1090 1091 return ShowCursorRequest->RefCount; 1092} 1093 1094 1095/* 1096 * FUNCTION: Checks whether the given handle is a valid console handle. 1097 * 1098 * ARGUMENTS: 1099 * hIoHandle - Handle to be checked. 1100 * 1101 * RETURNS: 1102 * TRUE : Handle is a valid console handle. 1103 * FALSE: Handle is not a valid console handle. 1104 * 1105 * STATUS: Officially undocumented 1106 * 1107 * @implemented 1108 */ 1109BOOL 1110WINAPI 1111DECLSPEC_HOTPATCH 1112VerifyConsoleIoHandle(HANDLE hIoHandle) 1113{ 1114 CONSOLE_API_MESSAGE ApiMessage; 1115 PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &ApiMessage.Data.VerifyHandleRequest; 1116 1117 VerifyHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1118 VerifyHandleRequest->Handle = hIoHandle; 1119 VerifyHandleRequest->IsValid = FALSE; 1120 1121 /* If the process is not attached to a console, return invalid handle */ 1122 if (VerifyHandleRequest->ConsoleHandle == NULL) return FALSE; 1123 1124 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1125 NULL, 1126 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle), 1127 sizeof(*VerifyHandleRequest)); 1128 if (!NT_SUCCESS(ApiMessage.Status)) 1129 { 1130 BaseSetLastNTError(ApiMessage.Status); 1131 return FALSE; 1132 } 1133 1134 return VerifyHandleRequest->IsValid; 1135} 1136 1137 1138/* 1139 * @implemented (Undocumented) 1140 */ 1141BOOL 1142WINAPI 1143DECLSPEC_HOTPATCH 1144CloseConsoleHandle(HANDLE hHandle) 1145{ 1146 CONSOLE_API_MESSAGE ApiMessage; 1147 PCONSOLE_CLOSEHANDLE CloseHandleRequest = &ApiMessage.Data.CloseHandleRequest; 1148 1149 CloseHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1150 CloseHandleRequest->Handle = hHandle; 1151 1152 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1153 NULL, 1154 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle), 1155 sizeof(*CloseHandleRequest)); 1156 if (!NT_SUCCESS(ApiMessage.Status)) 1157 { 1158 BaseSetLastNTError(ApiMessage.Status); 1159 return FALSE; 1160 } 1161 1162 return TRUE; 1163} 1164 1165 1166/* 1167 * @implemented 1168 */ 1169HANDLE 1170WINAPI 1171DECLSPEC_HOTPATCH 1172GetStdHandle(DWORD nStdHandle) 1173/* 1174 * FUNCTION: Get a handle for the standard input, standard output 1175 * and a standard error device. 1176 * 1177 * ARGUMENTS: 1178 * nStdHandle - Specifies the device for which to return the handle. 1179 * 1180 * RETURNS: If the function succeeds, the return value is the handle 1181 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE. 1182 */ 1183{ 1184 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; 1185 HANDLE Handle = INVALID_HANDLE_VALUE; 1186 1187 switch (nStdHandle) 1188 { 1189 case STD_INPUT_HANDLE: 1190 Handle = Ppb->StandardInput; 1191 break; 1192 1193 case STD_OUTPUT_HANDLE: 1194 Handle = Ppb->StandardOutput; 1195 break; 1196 1197 case STD_ERROR_HANDLE: 1198 Handle = Ppb->StandardError; 1199 break; 1200 } 1201 1202 /* If the returned handle is invalid, set last error */ 1203 if (Handle == INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE); 1204 1205 return Handle; 1206} 1207 1208 1209/* 1210 * @implemented 1211 */ 1212BOOL 1213WINAPI 1214DECLSPEC_HOTPATCH 1215SetStdHandle(DWORD nStdHandle, 1216 HANDLE hHandle) 1217/* 1218 * FUNCTION: Set the handle for the standard input, standard output or 1219 * the standard error device. 1220 * 1221 * ARGUMENTS: 1222 * nStdHandle - Specifies the handle to be set. 1223 * hHandle - The handle to set. 1224 * 1225 * RETURNS: TRUE if the function succeeds, FALSE otherwise. 1226 */ 1227{ 1228 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; 1229 1230 /* No need to check if hHandle == INVALID_HANDLE_VALUE */ 1231 1232 switch (nStdHandle) 1233 { 1234 case STD_INPUT_HANDLE: 1235 Ppb->StandardInput = hHandle; 1236 return TRUE; 1237 1238 case STD_OUTPUT_HANDLE: 1239 Ppb->StandardOutput = hHandle; 1240 return TRUE; 1241 1242 case STD_ERROR_HANDLE: 1243 Ppb->StandardError = hHandle; 1244 return TRUE; 1245 } 1246 1247 /* nStdHandle was invalid, bail out */ 1248 SetLastError(ERROR_INVALID_HANDLE); 1249 return FALSE; 1250} 1251 1252 1253/* 1254 * @implemented 1255 */ 1256static BOOL 1257IntAllocConsole(LPWSTR Title, 1258 DWORD TitleLength, 1259 LPWSTR Desktop, 1260 DWORD DesktopLength, 1261 LPWSTR CurDir, 1262 DWORD CurDirLength, 1263 LPWSTR AppName, 1264 DWORD AppNameLength, 1265 LPTHREAD_START_ROUTINE CtrlRoutine, 1266 LPTHREAD_START_ROUTINE PropRoutine, 1267 PCONSOLE_START_INFO ConsoleStartInfo) 1268{ 1269 BOOL Success = TRUE; 1270 NTSTATUS Status; 1271 1272 CONSOLE_API_MESSAGE ApiMessage; 1273 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; 1274 PCSR_CAPTURE_BUFFER CaptureBuffer; 1275 1276 AllocConsoleRequest->CtrlRoutine = CtrlRoutine; 1277 AllocConsoleRequest->PropRoutine = PropRoutine; 1278 1279 CaptureBuffer = CsrAllocateCaptureBuffer(5, TitleLength + 1280 DesktopLength + 1281 CurDirLength + 1282 AppNameLength + 1283 sizeof(CONSOLE_START_INFO)); 1284 if (CaptureBuffer == NULL) 1285 { 1286 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1287 Success = FALSE; 1288 goto Quit; 1289 } 1290 1291 CsrCaptureMessageBuffer(CaptureBuffer, 1292 ConsoleStartInfo, 1293 sizeof(CONSOLE_START_INFO), 1294 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo); 1295 1296 AllocConsoleRequest->TitleLength = TitleLength; 1297 CsrCaptureMessageBuffer(CaptureBuffer, 1298 Title, 1299 TitleLength, 1300 (PVOID*)&AllocConsoleRequest->ConsoleTitle); 1301 1302 AllocConsoleRequest->DesktopLength = DesktopLength; 1303 CsrCaptureMessageBuffer(CaptureBuffer, 1304 Desktop, 1305 DesktopLength, 1306 (PVOID*)&AllocConsoleRequest->Desktop); 1307 1308 AllocConsoleRequest->CurDirLength = CurDirLength; 1309 CsrCaptureMessageBuffer(CaptureBuffer, 1310 CurDir, 1311 CurDirLength, 1312 (PVOID*)&AllocConsoleRequest->CurDir); 1313 1314 AllocConsoleRequest->AppNameLength = AppNameLength; 1315 CsrCaptureMessageBuffer(CaptureBuffer, 1316 AppName, 1317 AppNameLength, 1318 (PVOID*)&AllocConsoleRequest->AppName); 1319 1320 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1321 CaptureBuffer, 1322 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc), 1323 sizeof(*AllocConsoleRequest)); 1324 if (!NT_SUCCESS(ApiMessage.Status)) 1325 { 1326 BaseSetLastNTError(ApiMessage.Status); 1327 Success = FALSE; 1328 goto Quit; 1329 } 1330 1331 // Is AllocConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? 1332 Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, 1333 AllocConsoleRequest->ConsoleStartInfo->InitEvents, 1334 WaitAny, FALSE, NULL); 1335 if (!NT_SUCCESS(Status)) 1336 { 1337 BaseSetLastNTError(Status); 1338 Success = FALSE; 1339 goto Quit; 1340 } 1341 1342 NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); 1343 NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); 1344 if (Status != INIT_SUCCESS) 1345 { 1346 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; 1347 Success = FALSE; 1348 } 1349 else 1350 { 1351 RtlCopyMemory(ConsoleStartInfo, 1352 AllocConsoleRequest->ConsoleStartInfo, 1353 sizeof(CONSOLE_START_INFO)); 1354 Success = TRUE; 1355 } 1356 1357Quit: 1358 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); 1359 return Success; 1360} 1361 1362BOOL 1363WINAPI 1364DECLSPEC_HOTPATCH 1365AllocConsole(VOID) 1366{ 1367 BOOL Success; 1368 CONSOLE_START_INFO ConsoleStartInfo; 1369 1370 PWCHAR ConsoleTitle; 1371 PWCHAR Desktop; 1372 PWCHAR AppName; 1373 PWCHAR CurDir; 1374 1375 ULONG TitleLength = (MAX_PATH + 1) * sizeof(WCHAR); 1376 ULONG DesktopLength = (MAX_PATH + 1) * sizeof(WCHAR); 1377 ULONG AppNameLength = 128 * sizeof(WCHAR); 1378 ULONG CurDirLength = (MAX_PATH + 1) * sizeof(WCHAR); 1379 1380 RtlEnterCriticalSection(&ConsoleLock); 1381 1382 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle) 1383 { 1384 DPRINT1("AllocConsole: Allocating a console to a process already having one\n"); 1385 SetLastError(ERROR_ACCESS_DENIED); 1386 Success = FALSE; 1387 goto Quit; 1388 } 1389 1390 /* Set up the console properties */ 1391 SetUpConsoleInfo(FALSE, 1392 &TitleLength, 1393 &ConsoleTitle, 1394 &DesktopLength, 1395 &Desktop, 1396 &ConsoleStartInfo); 1397 DPRINT("ConsoleTitle = '%S' - Desktop = '%S'\n", 1398 ConsoleTitle, Desktop); 1399 1400 /* Initialize the Input EXE name */ 1401 InitExeName(); 1402 SetUpAppName(FALSE, 1403 &CurDirLength, 1404 &CurDir, 1405 &AppNameLength, 1406 &AppName); 1407 DPRINT("CurDir = '%S' - AppName = '%S'\n", 1408 CurDir, AppName); 1409 1410 Success = IntAllocConsole(ConsoleTitle, 1411 TitleLength, 1412 Desktop, 1413 DesktopLength, 1414 CurDir, 1415 CurDirLength, 1416 AppName, 1417 AppNameLength, 1418 ConsoleControlDispatcher, 1419 PropDialogHandler, 1420 &ConsoleStartInfo); 1421 if (Success) 1422 { 1423 /* Set up the handles */ 1424 SetUpHandles(&ConsoleStartInfo); 1425 InputWaitHandle = ConsoleStartInfo.InputWaitHandle; 1426 1427 /* Initialize Console Ctrl Handling */ 1428 InitializeCtrlHandling(); 1429 1430 /* Sync the current thread's LangId with the console's one */ 1431 SetTEBLangID(); 1432 } 1433 1434Quit: 1435 RtlLeaveCriticalSection(&ConsoleLock); 1436 return Success; 1437} 1438 1439 1440/* 1441 * @implemented 1442 */ 1443BOOL 1444WINAPI 1445DECLSPEC_HOTPATCH 1446FreeConsole(VOID) 1447{ 1448 BOOL Success = TRUE; 1449 CONSOLE_API_MESSAGE ApiMessage; 1450 PCONSOLE_FREECONSOLE FreeConsoleRequest = &ApiMessage.Data.FreeConsoleRequest; 1451 HANDLE ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1452 1453 RtlEnterCriticalSection(&ConsoleLock); 1454 1455 /* We must have a non-trivial handle to close */ 1456 if (ConsoleHandle == NULL) // IsConsoleHandle(ConsoleHandle) 1457 { 1458 SetLastError(ERROR_INVALID_PARAMETER); 1459 Success = FALSE; 1460 goto Quit; 1461 } 1462 1463 /* Set up the data to send to the Console Server */ 1464 FreeConsoleRequest->ConsoleHandle = ConsoleHandle; 1465 1466 /* Call the server */ 1467 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1468 NULL, 1469 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFree), 1470 sizeof(*FreeConsoleRequest)); 1471 1472 /* Check for success */ 1473 if (!NT_SUCCESS(ApiMessage.Status)) 1474 { 1475 BaseSetLastNTError(ApiMessage.Status); 1476 Success = FALSE; 1477 goto Quit; 1478 } 1479 1480 /* Reset the console handle */ 1481 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; 1482 1483 /* Close the associated input handle */ 1484 CloseHandle(InputWaitHandle); 1485 InputWaitHandle = INVALID_HANDLE_VALUE; 1486 1487Quit: 1488 RtlLeaveCriticalSection(&ConsoleLock); 1489 return Success; 1490} 1491 1492 1493/* 1494 * @implemented 1495 */ 1496BOOL 1497WINAPI 1498GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, 1499 PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo) 1500{ 1501 CONSOLE_API_MESSAGE ApiMessage; 1502 PCONSOLE_GETSCREENBUFFERINFO ScreenBufferInfoRequest = &ApiMessage.Data.ScreenBufferInfoRequest; 1503 1504 if (lpConsoleScreenBufferInfo == NULL) 1505 { 1506 SetLastError(ERROR_INVALID_PARAMETER); 1507 return FALSE; 1508 } 1509 1510 ScreenBufferInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1511 ScreenBufferInfoRequest->OutputHandle = hConsoleOutput; 1512 1513 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1514 NULL, 1515 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetScreenBufferInfo), 1516 sizeof(*ScreenBufferInfoRequest)); 1517 if (!NT_SUCCESS(ApiMessage.Status)) 1518 { 1519 BaseSetLastNTError(ApiMessage.Status); 1520 return FALSE; 1521 } 1522 1523 lpConsoleScreenBufferInfo->dwSize = ScreenBufferInfoRequest->ScreenBufferSize; 1524 lpConsoleScreenBufferInfo->dwCursorPosition = ScreenBufferInfoRequest->CursorPosition; 1525 lpConsoleScreenBufferInfo->wAttributes = ScreenBufferInfoRequest->Attributes; 1526 lpConsoleScreenBufferInfo->srWindow.Left = ScreenBufferInfoRequest->ViewOrigin.X; 1527 lpConsoleScreenBufferInfo->srWindow.Top = ScreenBufferInfoRequest->ViewOrigin.Y; 1528 lpConsoleScreenBufferInfo->srWindow.Right = ScreenBufferInfoRequest->ViewOrigin.X + ScreenBufferInfoRequest->ViewSize.X - 1; 1529 lpConsoleScreenBufferInfo->srWindow.Bottom = ScreenBufferInfoRequest->ViewOrigin.Y + ScreenBufferInfoRequest->ViewSize.Y - 1; 1530 lpConsoleScreenBufferInfo->dwMaximumWindowSize = ScreenBufferInfoRequest->MaximumViewSize; 1531 1532 return TRUE; 1533} 1534 1535 1536/* 1537 * @implemented 1538 */ 1539BOOL 1540WINAPI 1541DECLSPEC_HOTPATCH 1542SetConsoleCursorPosition(HANDLE hConsoleOutput, 1543 COORD dwCursorPosition) 1544{ 1545 CONSOLE_API_MESSAGE ApiMessage; 1546 PCONSOLE_SETCURSORPOSITION SetCursorPositionRequest = &ApiMessage.Data.SetCursorPositionRequest; 1547 1548 SetCursorPositionRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1549 SetCursorPositionRequest->OutputHandle = hConsoleOutput; 1550 SetCursorPositionRequest->Position = dwCursorPosition; 1551 1552 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1553 NULL, 1554 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorPosition), 1555 sizeof(*SetCursorPositionRequest)); 1556 if (!NT_SUCCESS(ApiMessage.Status)) 1557 { 1558 BaseSetLastNTError(ApiMessage.Status); 1559 return FALSE; 1560 } 1561 1562 return TRUE; 1563} 1564 1565 1566/* 1567 * @implemented 1568 */ 1569BOOL 1570WINAPI 1571GetConsoleMode(HANDLE hConsoleHandle, 1572 LPDWORD lpMode) 1573{ 1574 CONSOLE_API_MESSAGE ApiMessage; 1575 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest; 1576 1577 if (lpMode == NULL) 1578 { 1579 SetLastError(ERROR_INVALID_PARAMETER); 1580 return FALSE; 1581 } 1582 1583 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1584 ConsoleModeRequest->Handle = hConsoleHandle; 1585 1586 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1587 NULL, 1588 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMode), 1589 sizeof(*ConsoleModeRequest)); 1590 if (!NT_SUCCESS(ApiMessage.Status)) 1591 { 1592 BaseSetLastNTError(ApiMessage.Status); 1593 return FALSE; 1594 } 1595 1596 *lpMode = ConsoleModeRequest->Mode; 1597 1598 return TRUE; 1599} 1600 1601 1602/* 1603 * @implemented 1604 */ 1605BOOL 1606WINAPI 1607DECLSPEC_HOTPATCH 1608SetConsoleMode(HANDLE hConsoleHandle, 1609 DWORD dwMode) 1610{ 1611 CONSOLE_API_MESSAGE ApiMessage; 1612 PCONSOLE_GETSETCONSOLEMODE ConsoleModeRequest = &ApiMessage.Data.ConsoleModeRequest; 1613 1614 ConsoleModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1615 ConsoleModeRequest->Handle = hConsoleHandle; 1616 ConsoleModeRequest->Mode = dwMode; 1617 1618 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1619 NULL, 1620 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMode), 1621 sizeof(*ConsoleModeRequest)); 1622 if (!NT_SUCCESS(ApiMessage.Status)) 1623 { 1624 BaseSetLastNTError(ApiMessage.Status); 1625 return FALSE; 1626 } 1627 1628 return TRUE; 1629} 1630 1631 1632/* 1633 * @implemented 1634 */ 1635BOOL 1636WINAPI 1637GetNumberOfConsoleInputEvents(HANDLE hConsoleInput, 1638 LPDWORD lpNumberOfEvents) 1639{ 1640 CONSOLE_API_MESSAGE ApiMessage; 1641 PCONSOLE_GETNUMINPUTEVENTS GetNumInputEventsRequest = &ApiMessage.Data.GetNumInputEventsRequest; 1642 1643 GetNumInputEventsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1644 GetNumInputEventsRequest->InputHandle = hConsoleInput; 1645 GetNumInputEventsRequest->NumberOfEvents = 0; 1646 1647 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1648 NULL, 1649 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfInputEvents), 1650 sizeof(*GetNumInputEventsRequest)); 1651 if (!NT_SUCCESS(ApiMessage.Status)) 1652 { 1653 BaseSetLastNTError(ApiMessage.Status); 1654 return FALSE; 1655 } 1656 1657 if (lpNumberOfEvents == NULL) 1658 { 1659 SetLastError(ERROR_INVALID_ACCESS); 1660 return FALSE; 1661 } 1662 1663 *lpNumberOfEvents = GetNumInputEventsRequest->NumberOfEvents; 1664 1665 return TRUE; 1666} 1667 1668 1669/* 1670 * @implemented 1671 */ 1672COORD 1673WINAPI 1674DECLSPEC_HOTPATCH 1675GetLargestConsoleWindowSize(HANDLE hConsoleOutput) 1676{ 1677 CONSOLE_API_MESSAGE ApiMessage; 1678 PCONSOLE_GETLARGESTWINDOWSIZE GetLargestWindowSizeRequest = &ApiMessage.Data.GetLargestWindowSizeRequest; 1679 1680 GetLargestWindowSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1681 GetLargestWindowSizeRequest->OutputHandle = hConsoleOutput; 1682 GetLargestWindowSizeRequest->Size.X = 0; 1683 GetLargestWindowSizeRequest->Size.Y = 0; 1684 1685 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1686 NULL, 1687 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLargestWindowSize), 1688 sizeof(*GetLargestWindowSizeRequest)); 1689 if (!NT_SUCCESS(ApiMessage.Status)) 1690 { 1691 BaseSetLastNTError(ApiMessage.Status); 1692 } 1693 1694 DPRINT("GetLargestConsoleWindowSize, X = %d, Y = %d\n", GetLargestWindowSizeRequest->Size.X, GetLargestWindowSizeRequest->Size.Y); 1695 return GetLargestWindowSizeRequest->Size; 1696} 1697 1698 1699/* 1700 * @implemented 1701 */ 1702BOOL 1703WINAPI 1704GetConsoleCursorInfo(HANDLE hConsoleOutput, 1705 PCONSOLE_CURSOR_INFO lpConsoleCursorInfo) 1706{ 1707 CONSOLE_API_MESSAGE ApiMessage; 1708 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest; 1709 1710 if (!lpConsoleCursorInfo) 1711 { 1712 if (!hConsoleOutput) 1713 SetLastError(ERROR_INVALID_HANDLE); 1714 else 1715 SetLastError(ERROR_INVALID_ACCESS); 1716 1717 return FALSE; 1718 } 1719 1720 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1721 CursorInfoRequest->OutputHandle = hConsoleOutput; 1722 1723 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1724 NULL, 1725 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCursorInfo), 1726 sizeof(*CursorInfoRequest)); 1727 if (!NT_SUCCESS(ApiMessage.Status)) 1728 { 1729 BaseSetLastNTError(ApiMessage.Status); 1730 return FALSE; 1731 } 1732 1733 *lpConsoleCursorInfo = CursorInfoRequest->Info; 1734 1735 return TRUE; 1736} 1737 1738 1739/* 1740 * @implemented 1741 */ 1742BOOL 1743WINAPI 1744SetConsoleCursorInfo(HANDLE hConsoleOutput, 1745 CONST CONSOLE_CURSOR_INFO *lpConsoleCursorInfo) 1746{ 1747 CONSOLE_API_MESSAGE ApiMessage; 1748 PCONSOLE_GETSETCURSORINFO CursorInfoRequest = &ApiMessage.Data.CursorInfoRequest; 1749 1750 CursorInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1751 CursorInfoRequest->OutputHandle = hConsoleOutput; 1752 CursorInfoRequest->Info = *lpConsoleCursorInfo; 1753 1754 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1755 NULL, 1756 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursorInfo), 1757 sizeof(*CursorInfoRequest)); 1758 if (!NT_SUCCESS(ApiMessage.Status)) 1759 { 1760 BaseSetLastNTError(ApiMessage.Status); 1761 return FALSE; 1762 } 1763 1764 return TRUE; 1765} 1766 1767 1768/* 1769 * @implemented 1770 */ 1771BOOL 1772WINAPI 1773GetNumberOfConsoleMouseButtons(LPDWORD lpNumberOfMouseButtons) 1774{ 1775 CONSOLE_API_MESSAGE ApiMessage; 1776 PCONSOLE_GETMOUSEINFO GetMouseInfoRequest = &ApiMessage.Data.GetMouseInfoRequest; 1777 1778 GetMouseInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1779 1780 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1781 NULL, 1782 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetMouseInfo), 1783 sizeof(*GetMouseInfoRequest)); 1784 if (!NT_SUCCESS(ApiMessage.Status)) 1785 { 1786 BaseSetLastNTError(ApiMessage.Status); 1787 return FALSE; 1788 } 1789 1790 *lpNumberOfMouseButtons = GetMouseInfoRequest->NumButtons; 1791 return TRUE; 1792} 1793 1794 1795/* 1796 * @implemented 1797 */ 1798BOOL 1799WINAPI 1800DECLSPEC_HOTPATCH 1801SetConsoleActiveScreenBuffer(HANDLE hConsoleOutput) 1802{ 1803 CONSOLE_API_MESSAGE ApiMessage; 1804 PCONSOLE_SETACTIVESCREENBUFFER SetScreenBufferRequest = &ApiMessage.Data.SetScreenBufferRequest; 1805 1806 SetScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1807 SetScreenBufferRequest->OutputHandle = hConsoleOutput; 1808 1809 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1810 NULL, 1811 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetActiveScreenBuffer), 1812 sizeof(*SetScreenBufferRequest)); 1813 if (!NT_SUCCESS(ApiMessage.Status)) 1814 { 1815 BaseSetLastNTError(ApiMessage.Status); 1816 return FALSE; 1817 } 1818 1819 return TRUE; 1820} 1821 1822 1823/* 1824 * @implemented 1825 */ 1826BOOL 1827WINAPI 1828DECLSPEC_HOTPATCH 1829FlushConsoleInputBuffer(HANDLE hConsoleInput) 1830{ 1831 CONSOLE_API_MESSAGE ApiMessage; 1832 PCONSOLE_FLUSHINPUTBUFFER FlushInputBufferRequest = &ApiMessage.Data.FlushInputBufferRequest; 1833 1834 FlushInputBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1835 FlushInputBufferRequest->InputHandle = hConsoleInput; 1836 1837 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1838 NULL, 1839 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepFlushInputBuffer), 1840 sizeof(*FlushInputBufferRequest)); 1841 if (!NT_SUCCESS(ApiMessage.Status)) 1842 { 1843 BaseSetLastNTError(ApiMessage.Status); 1844 return FALSE; 1845 } 1846 1847 return TRUE; 1848} 1849 1850 1851/* 1852 * @implemented 1853 */ 1854BOOL 1855WINAPI 1856DECLSPEC_HOTPATCH 1857SetConsoleScreenBufferSize(HANDLE hConsoleOutput, 1858 COORD dwSize) 1859{ 1860 CONSOLE_API_MESSAGE ApiMessage; 1861 PCONSOLE_SETSCREENBUFFERSIZE SetScreenBufferSizeRequest = &ApiMessage.Data.SetScreenBufferSizeRequest; 1862 1863 SetScreenBufferSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1864 SetScreenBufferSizeRequest->OutputHandle = hConsoleOutput; 1865 SetScreenBufferSizeRequest->Size = dwSize; 1866 1867 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1868 NULL, 1869 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetScreenBufferSize), 1870 sizeof(*SetScreenBufferSizeRequest)); 1871 if (!NT_SUCCESS(ApiMessage.Status)) 1872 { 1873 BaseSetLastNTError(ApiMessage.Status); 1874 return FALSE; 1875 } 1876 1877 return TRUE; 1878} 1879 1880 1881static 1882BOOL 1883IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput, 1884 CONST SMALL_RECT* lpScrollRectangle, 1885 CONST SMALL_RECT* lpClipRectangle, 1886 COORD dwDestinationOrigin, 1887 CONST CHAR_INFO* lpFill, 1888 BOOL bUnicode) 1889{ 1890 CONSOLE_API_MESSAGE ApiMessage; 1891 PCONSOLE_SCROLLSCREENBUFFER ScrollScreenBufferRequest = &ApiMessage.Data.ScrollScreenBufferRequest; 1892 1893 ScrollScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1894 ScrollScreenBufferRequest->OutputHandle = hConsoleOutput; 1895 ScrollScreenBufferRequest->ScrollRectangle = *lpScrollRectangle; 1896 1897 if (lpClipRectangle != NULL) 1898 { 1899 ScrollScreenBufferRequest->UseClipRectangle = TRUE; 1900 ScrollScreenBufferRequest->ClipRectangle = *lpClipRectangle; 1901 } 1902 else 1903 { 1904 ScrollScreenBufferRequest->UseClipRectangle = FALSE; 1905 } 1906 1907 ScrollScreenBufferRequest->DestinationOrigin = dwDestinationOrigin; 1908 ScrollScreenBufferRequest->Fill = *lpFill; 1909 ScrollScreenBufferRequest->Unicode = bUnicode; 1910 1911 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1912 NULL, 1913 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepScrollScreenBuffer), 1914 sizeof(*ScrollScreenBufferRequest)); 1915 if (!NT_SUCCESS(ApiMessage.Status)) 1916 { 1917 BaseSetLastNTError(ApiMessage.Status); 1918 return FALSE; 1919 } 1920 1921 return TRUE; 1922} 1923 1924 1925/* 1926 * @implemented 1927 */ 1928BOOL 1929WINAPI 1930DECLSPEC_HOTPATCH 1931ScrollConsoleScreenBufferA(HANDLE hConsoleOutput, 1932 CONST SMALL_RECT* lpScrollRectangle, 1933 CONST SMALL_RECT* lpClipRectangle, 1934 COORD dwDestinationOrigin, 1935 CONST CHAR_INFO* lpFill) 1936{ 1937 return IntScrollConsoleScreenBuffer(hConsoleOutput, 1938 lpScrollRectangle, 1939 lpClipRectangle, 1940 dwDestinationOrigin, 1941 lpFill, 1942 FALSE); 1943} 1944 1945 1946/* 1947 * @implemented 1948 */ 1949BOOL 1950WINAPI 1951DECLSPEC_HOTPATCH 1952ScrollConsoleScreenBufferW(HANDLE hConsoleOutput, 1953 CONST SMALL_RECT *lpScrollRectangle, 1954 CONST SMALL_RECT *lpClipRectangle, 1955 COORD dwDestinationOrigin, 1956 CONST CHAR_INFO *lpFill) 1957{ 1958 return IntScrollConsoleScreenBuffer(hConsoleOutput, 1959 lpScrollRectangle, 1960 lpClipRectangle, 1961 dwDestinationOrigin, 1962 lpFill, 1963 TRUE); 1964} 1965 1966 1967/* 1968 * @implemented 1969 */ 1970BOOL 1971WINAPI 1972SetConsoleWindowInfo(HANDLE hConsoleOutput, 1973 BOOL bAbsolute, 1974 CONST SMALL_RECT *lpConsoleWindow) 1975{ 1976 CONSOLE_API_MESSAGE ApiMessage; 1977 PCONSOLE_SETWINDOWINFO SetWindowInfoRequest = &ApiMessage.Data.SetWindowInfoRequest; 1978 1979 if (lpConsoleWindow == NULL) 1980 { 1981 SetLastError(ERROR_INVALID_PARAMETER); 1982 return FALSE; 1983 } 1984 1985 SetWindowInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1986 SetWindowInfoRequest->OutputHandle = hConsoleOutput; 1987 SetWindowInfoRequest->Absolute = bAbsolute; 1988 SetWindowInfoRequest->WindowRect = *lpConsoleWindow; 1989 1990 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1991 NULL, 1992 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetWindowInfo), 1993 sizeof(*SetWindowInfoRequest)); 1994 if (!NT_SUCCESS(ApiMessage.Status)) 1995 { 1996 BaseSetLastNTError(ApiMessage.Status); 1997 return FALSE; 1998 } 1999 2000 return TRUE; 2001} 2002 2003 2004/* 2005 * @implemented 2006 */ 2007BOOL 2008WINAPI 2009DECLSPEC_HOTPATCH 2010SetConsoleTextAttribute(HANDLE hConsoleOutput, 2011 WORD wAttributes) 2012{ 2013 CONSOLE_API_MESSAGE ApiMessage; 2014 PCONSOLE_SETTEXTATTRIB SetTextAttribRequest = &ApiMessage.Data.SetTextAttribRequest; 2015 2016 SetTextAttribRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2017 SetTextAttribRequest->OutputHandle = hConsoleOutput; 2018 SetTextAttribRequest->Attributes = wAttributes; 2019 2020 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2021 NULL, 2022 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTextAttribute), 2023 sizeof(*SetTextAttribRequest)); 2024 if (!NT_SUCCESS(ApiMessage.Status)) 2025 { 2026 BaseSetLastNTError(ApiMessage.Status); 2027 return FALSE; 2028 } 2029 2030 return TRUE; 2031} 2032 2033 2034static 2035BOOL 2036AddConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine) 2037{ 2038 PHANDLER_ROUTINE* NewCtrlHandlers = NULL; 2039 2040 if (HandlerRoutine == NULL) 2041 { 2042 NtCurrentPeb()->ProcessParameters->ConsoleFlags = TRUE; 2043 return TRUE; 2044 } 2045 2046 if (NrCtrlHandlers == NrAllocatedHandlers) 2047 { 2048 NewCtrlHandlers = RtlAllocateHeap(RtlGetProcessHeap(), 2049 0, 2050 (NrCtrlHandlers + 4) * sizeof(PHANDLER_ROUTINE)); 2051 if (NewCtrlHandlers == NULL) 2052 { 2053 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2054 return FALSE; 2055 } 2056 2057 memmove(NewCtrlHandlers, CtrlHandlers, sizeof(PHANDLER_ROUTINE) * NrCtrlHandlers); 2058 2059 if (NrAllocatedHandlers > 1) RtlFreeHeap(RtlGetProcessHeap(), 0, CtrlHandlers); 2060 2061 CtrlHandlers = NewCtrlHandlers; 2062 NrAllocatedHandlers += 4; 2063 } 2064 2065 ASSERT(NrCtrlHandlers < NrAllocatedHandlers); 2066 2067 CtrlHandlers[NrCtrlHandlers++] = HandlerRoutine; 2068 return TRUE; 2069} 2070 2071 2072static 2073BOOL 2074RemoveConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine) 2075{ 2076 ULONG i; 2077 2078 if (HandlerRoutine == NULL) 2079 { 2080 NtCurrentPeb()->ProcessParameters->ConsoleFlags = FALSE; 2081 return TRUE; 2082 } 2083 2084 for (i = 0; i < NrCtrlHandlers; i++) 2085 { 2086 if (CtrlHandlers[i] == HandlerRoutine) 2087 { 2088 if (i < (NrCtrlHandlers - 1)) 2089 { 2090 memmove(&CtrlHandlers[i], 2091 &CtrlHandlers[i+1], 2092 (NrCtrlHandlers - i + 1) * sizeof(PHANDLER_ROUTINE)); 2093 } 2094 2095 NrCtrlHandlers--; 2096 return TRUE; 2097 } 2098 } 2099 2100 SetLastError(ERROR_INVALID_PARAMETER); 2101 return FALSE; 2102} 2103 2104 2105/* 2106 * @implemented 2107 */ 2108BOOL 2109WINAPI 2110DECLSPEC_HOTPATCH 2111SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, 2112 BOOL Add) 2113{ 2114 BOOL Ret; 2115 2116 RtlEnterCriticalSection(&ConsoleLock); 2117 2118 if (Add) 2119 Ret = AddConsoleCtrlHandler(HandlerRoutine); 2120 else 2121 Ret = RemoveConsoleCtrlHandler(HandlerRoutine); 2122 2123 RtlLeaveCriticalSection(&ConsoleLock); 2124 return Ret; 2125} 2126 2127 2128/* 2129 * @implemented 2130 */ 2131BOOL 2132WINAPI 2133DECLSPEC_HOTPATCH 2134GenerateConsoleCtrlEvent(DWORD dwCtrlEvent, 2135 DWORD dwProcessGroupId) 2136{ 2137 CONSOLE_API_MESSAGE ApiMessage; 2138 PCONSOLE_GENERATECTRLEVENT GenerateCtrlEventRequest = &ApiMessage.Data.GenerateCtrlEventRequest; 2139 2140 if (dwCtrlEvent != CTRL_C_EVENT && dwCtrlEvent != CTRL_BREAK_EVENT) 2141 { 2142 SetLastError(ERROR_INVALID_PARAMETER); 2143 return FALSE; 2144 } 2145 2146 GenerateCtrlEventRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2147 GenerateCtrlEventRequest->CtrlEvent = dwCtrlEvent; 2148 GenerateCtrlEventRequest->ProcessGroupId = dwProcessGroupId; 2149 2150 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2151 NULL, 2152 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGenerateCtrlEvent), 2153 sizeof(*GenerateCtrlEventRequest)); 2154 if (!NT_SUCCESS(ApiMessage.Status)) 2155 { 2156 BaseSetLastNTError(ApiMessage.Status); 2157 return FALSE; 2158 } 2159 2160 return TRUE; 2161} 2162 2163 2164static DWORD 2165IntGetConsoleTitle(LPVOID lpConsoleTitle, DWORD dwNumChars, BOOLEAN bUnicode) 2166{ 2167 CONSOLE_API_MESSAGE ApiMessage; 2168 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest; 2169 PCSR_CAPTURE_BUFFER CaptureBuffer; 2170 2171 if (dwNumChars == 0) return 0; 2172 2173 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2174 TitleRequest->Length = dwNumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); 2175 TitleRequest->Unicode = bUnicode; 2176 2177 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length); 2178 if (CaptureBuffer == NULL) 2179 { 2180 DPRINT1("CsrAllocateCaptureBuffer failed!\n"); 2181 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2182 return 0; 2183 } 2184 2185 CsrAllocateMessagePointer(CaptureBuffer, 2186 TitleRequest->Length, 2187 (PVOID*)&TitleRequest->Title); 2188 2189 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2190 CaptureBuffer, 2191 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetTitle), 2192 sizeof(*TitleRequest)); 2193 if (!NT_SUCCESS(ApiMessage.Status)) 2194 { 2195 CsrFreeCaptureBuffer(CaptureBuffer); 2196 BaseSetLastNTError(ApiMessage.Status); 2197 return 0; 2198 } 2199 2200 dwNumChars = TitleRequest->Length / (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); 2201 2202 if (dwNumChars > 0) 2203 { 2204 RtlCopyMemory(lpConsoleTitle, TitleRequest->Title, TitleRequest->Length); 2205 2206 if (bUnicode) 2207 ((LPWSTR)lpConsoleTitle)[dwNumChars] = UNICODE_NULL; 2208 else 2209 ((LPSTR)lpConsoleTitle)[dwNumChars] = ANSI_NULL; 2210 } 2211 2212 CsrFreeCaptureBuffer(CaptureBuffer); 2213 2214 return dwNumChars; 2215} 2216 2217 2218/* 2219 * @implemented 2220 */ 2221DWORD 2222WINAPI 2223DECLSPEC_HOTPATCH 2224GetConsoleTitleW(LPWSTR lpConsoleTitle, 2225 DWORD nSize) 2226{ 2227 return IntGetConsoleTitle(lpConsoleTitle, nSize, TRUE); 2228} 2229 2230 2231/* 2232 * @implemented 2233 */ 2234DWORD 2235WINAPI 2236DECLSPEC_HOTPATCH 2237GetConsoleTitleA(LPSTR lpConsoleTitle, 2238 DWORD nSize) 2239{ 2240 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE); 2241} 2242 2243 2244static BOOL 2245IntSetConsoleTitle(CONST VOID *lpConsoleTitle, BOOLEAN bUnicode) 2246{ 2247 CONSOLE_API_MESSAGE ApiMessage; 2248 PCONSOLE_GETSETCONSOLETITLE TitleRequest = &ApiMessage.Data.TitleRequest; 2249 PCSR_CAPTURE_BUFFER CaptureBuffer; 2250 2251 ULONG NumChars = (ULONG)(lpConsoleTitle ? (bUnicode ? wcslen(lpConsoleTitle) : strlen(lpConsoleTitle)) : 0); 2252 2253 TitleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2254 TitleRequest->Length = NumChars * (bUnicode ? sizeof(WCHAR) : sizeof(CHAR)); 2255 TitleRequest->Unicode = bUnicode; 2256 2257 CaptureBuffer = CsrAllocateCaptureBuffer(1, TitleRequest->Length); 2258 if (CaptureBuffer == NULL) 2259 { 2260 DPRINT1("CsrAllocateCaptureBuffer failed!\n"); 2261 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2262 return FALSE; 2263 } 2264 2265 CsrCaptureMessageBuffer(CaptureBuffer, 2266 (PVOID)lpConsoleTitle, 2267 TitleRequest->Length, 2268 (PVOID*)&TitleRequest->Title); 2269 2270 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2271 CaptureBuffer, 2272 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetTitle), 2273 sizeof(*TitleRequest)); 2274 2275 CsrFreeCaptureBuffer(CaptureBuffer); 2276 2277 if (!NT_SUCCESS(ApiMessage.Status)) 2278 { 2279 BaseSetLastNTError(ApiMessage.Status); 2280 return FALSE; 2281 } 2282 2283 return TRUE; 2284} 2285 2286/* 2287 * @implemented 2288 */ 2289BOOL 2290WINAPI 2291DECLSPEC_HOTPATCH 2292SetConsoleTitleW(LPCWSTR lpConsoleTitle) 2293{ 2294 return IntSetConsoleTitle(lpConsoleTitle, TRUE); 2295} 2296 2297 2298/* 2299 * @implemented 2300 */ 2301BOOL 2302WINAPI 2303DECLSPEC_HOTPATCH 2304SetConsoleTitleA(LPCSTR lpConsoleTitle) 2305{ 2306 return IntSetConsoleTitle(lpConsoleTitle, FALSE); 2307} 2308 2309 2310/* 2311 * @implemented 2312 */ 2313HANDLE 2314WINAPI 2315CreateConsoleScreenBuffer(DWORD dwDesiredAccess, 2316 DWORD dwShareMode, 2317 CONST SECURITY_ATTRIBUTES *lpSecurityAttributes, 2318 DWORD dwFlags, 2319 LPVOID lpScreenBufferData) 2320{ 2321 CONSOLE_API_MESSAGE ApiMessage; 2322 PCONSOLE_CREATESCREENBUFFER CreateScreenBufferRequest = &ApiMessage.Data.CreateScreenBufferRequest; 2323 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; 2324 PCONSOLE_GRAPHICS_BUFFER_INFO GraphicsBufferInfo = lpScreenBufferData; 2325 2326 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) || 2327 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) || 2328 (dwFlags != CONSOLE_TEXTMODE_BUFFER && dwFlags != CONSOLE_GRAPHICS_BUFFER) ) 2329 { 2330 SetLastError(ERROR_INVALID_PARAMETER); 2331 return INVALID_HANDLE_VALUE; 2332 } 2333 2334 CreateScreenBufferRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2335 CreateScreenBufferRequest->DesiredAccess = dwDesiredAccess; 2336 CreateScreenBufferRequest->InheritHandle = 2337 (lpSecurityAttributes ? lpSecurityAttributes->bInheritHandle : FALSE); 2338 CreateScreenBufferRequest->ShareMode = dwShareMode; 2339 CreateScreenBufferRequest->ScreenBufferType = dwFlags; 2340 2341 if (dwFlags == CONSOLE_GRAPHICS_BUFFER) 2342 { 2343 if (CreateScreenBufferRequest->InheritHandle || GraphicsBufferInfo == NULL) 2344 { 2345 SetLastError(ERROR_INVALID_PARAMETER); 2346 return INVALID_HANDLE_VALUE; 2347 } 2348 2349 CreateScreenBufferRequest->GraphicsBufferInfo = *GraphicsBufferInfo; 2350 2351 CaptureBuffer = CsrAllocateCaptureBuffer(1, GraphicsBufferInfo->dwBitMapInfoLength); 2352 if (CaptureBuffer == NULL) 2353 { 2354 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2355 return INVALID_HANDLE_VALUE; 2356 } 2357 2358 CsrCaptureMessageBuffer(CaptureBuffer, 2359 (PVOID)GraphicsBufferInfo->lpBitMapInfo, 2360 GraphicsBufferInfo->dwBitMapInfoLength, 2361 (PVOID*)&CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMapInfo); 2362 } 2363 2364 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2365 CaptureBuffer, 2366 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCreateScreenBuffer), 2367 sizeof(*CreateScreenBufferRequest)); 2368 2369 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); 2370 2371 if (!NT_SUCCESS(ApiMessage.Status)) 2372 { 2373 BaseSetLastNTError(ApiMessage.Status); 2374 return INVALID_HANDLE_VALUE; 2375 } 2376 2377 if (dwFlags == CONSOLE_GRAPHICS_BUFFER && GraphicsBufferInfo) 2378 { 2379 GraphicsBufferInfo->hMutex = CreateScreenBufferRequest->hMutex ; // CreateScreenBufferRequest->GraphicsBufferInfo.hMutex ; 2380 GraphicsBufferInfo->lpBitMap = CreateScreenBufferRequest->lpBitMap; // CreateScreenBufferRequest->GraphicsBufferInfo.lpBitMap; 2381 } 2382 2383 return CreateScreenBufferRequest->OutputHandle; 2384} 2385 2386 2387/* 2388 * @implemented 2389 */ 2390UINT 2391WINAPI 2392DECLSPEC_HOTPATCH 2393GetConsoleCP(VOID) 2394{ 2395 CONSOLE_API_MESSAGE ApiMessage; 2396 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest; 2397 2398 /* Get the Input Code Page */ 2399 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2400 GetConsoleCPRequest->OutputCP = FALSE; 2401 2402 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2403 NULL, 2404 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP), 2405 sizeof(*GetConsoleCPRequest)); 2406 if (!NT_SUCCESS(ApiMessage.Status)) 2407 { 2408 BaseSetLastNTError(ApiMessage.Status); 2409 return 0; 2410 } 2411 2412 return GetConsoleCPRequest->CodePage; 2413} 2414 2415 2416/* 2417 * @implemented 2418 */ 2419BOOL 2420WINAPI 2421DECLSPEC_HOTPATCH 2422SetConsoleCP(UINT wCodePageID) 2423{ 2424 CONSOLE_API_MESSAGE ApiMessage; 2425 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest; 2426 2427 /* Set the Input Code Page */ 2428 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2429 SetConsoleCPRequest->CodePage = wCodePageID; 2430 SetConsoleCPRequest->OutputCP = FALSE; 2431 /* SetConsoleCPRequest->EventHandle; */ 2432 2433 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2434 NULL, 2435 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP), 2436 sizeof(*SetConsoleCPRequest)); 2437 if (!NT_SUCCESS(ApiMessage.Status)) 2438 { 2439 BaseSetLastNTError(ApiMessage.Status); 2440 return FALSE; 2441 } 2442 2443 return TRUE; 2444} 2445 2446 2447/* 2448 * @implemented 2449 */ 2450UINT 2451WINAPI 2452DECLSPEC_HOTPATCH 2453GetConsoleOutputCP(VOID) 2454{ 2455 CONSOLE_API_MESSAGE ApiMessage; 2456 PCONSOLE_GETINPUTOUTPUTCP GetConsoleCPRequest = &ApiMessage.Data.GetConsoleCPRequest; 2457 2458 /* Get the Output Code Page */ 2459 GetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2460 GetConsoleCPRequest->OutputCP = TRUE; 2461 2462 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2463 NULL, 2464 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCP), 2465 sizeof(*GetConsoleCPRequest)); 2466 if (!NT_SUCCESS(ApiMessage.Status)) 2467 { 2468 BaseSetLastNTError(ApiMessage.Status); 2469 return 0; 2470 } 2471 2472 return GetConsoleCPRequest->CodePage; 2473} 2474 2475 2476/* 2477 * @implemented 2478 */ 2479BOOL 2480WINAPI 2481DECLSPEC_HOTPATCH 2482SetConsoleOutputCP(UINT wCodePageID) 2483{ 2484 CONSOLE_API_MESSAGE ApiMessage; 2485 PCONSOLE_SETINPUTOUTPUTCP SetConsoleCPRequest = &ApiMessage.Data.SetConsoleCPRequest; 2486 2487 /* Set the Output Code Page */ 2488 SetConsoleCPRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2489 SetConsoleCPRequest->CodePage = wCodePageID; 2490 SetConsoleCPRequest->OutputCP = TRUE; 2491 /* SetConsoleCPRequest->EventHandle; */ 2492 2493 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2494 NULL, 2495 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCP), 2496 sizeof(*SetConsoleCPRequest)); 2497 if (!NT_SUCCESS(ApiMessage.Status)) 2498 { 2499 BaseSetLastNTError(ApiMessage.Status); 2500 return FALSE; 2501 } 2502 2503 /* Sync the current thread's LangId with the console's one */ 2504 SetTEBLangID(); 2505 2506 return TRUE; 2507} 2508 2509 2510/* 2511 * @implemented 2512 */ 2513DWORD 2514WINAPI 2515GetConsoleProcessList(LPDWORD lpdwProcessList, 2516 DWORD dwProcessCount) 2517{ 2518 CONSOLE_API_MESSAGE ApiMessage; 2519 PCONSOLE_GETPROCESSLIST GetProcessListRequest = &ApiMessage.Data.GetProcessListRequest; 2520 PCSR_CAPTURE_BUFFER CaptureBuffer; 2521 ULONG nProcesses = 0; 2522 2523 if (lpdwProcessList == NULL || dwProcessCount == 0) 2524 { 2525 SetLastError(ERROR_INVALID_PARAMETER); 2526 return 0; 2527 } 2528 2529 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwProcessCount * sizeof(DWORD)); 2530 if (CaptureBuffer == NULL) 2531 { 2532 DPRINT1("CsrAllocateCaptureBuffer failed!\n"); 2533 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2534 return 0; 2535 } 2536 2537 GetProcessListRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2538 GetProcessListRequest->ProcessCount = dwProcessCount; 2539 2540 CsrAllocateMessagePointer(CaptureBuffer, 2541 dwProcessCount * sizeof(DWORD), 2542 (PVOID*)&GetProcessListRequest->ProcessIdsList); 2543 2544 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2545 CaptureBuffer, 2546 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetProcessList), 2547 sizeof(*GetProcessListRequest)); 2548 if (!NT_SUCCESS(ApiMessage.Status)) 2549 { 2550 BaseSetLastNTError(ApiMessage.Status); 2551 } 2552 else 2553 { 2554 nProcesses = GetProcessListRequest->ProcessCount; 2555 if (dwProcessCount >= nProcesses) 2556 { 2557 RtlCopyMemory(lpdwProcessList, GetProcessListRequest->ProcessIdsList, nProcesses * sizeof(DWORD)); 2558 } 2559 } 2560 2561 CsrFreeCaptureBuffer(CaptureBuffer); 2562 return nProcesses; 2563} 2564 2565 2566/* 2567 * @implemented 2568 */ 2569BOOL 2570WINAPI 2571GetConsoleSelectionInfo(PCONSOLE_SELECTION_INFO lpConsoleSelectionInfo) 2572{ 2573 CONSOLE_API_MESSAGE ApiMessage; 2574 PCONSOLE_GETSELECTIONINFO GetSelectionInfoRequest = &ApiMessage.Data.GetSelectionInfoRequest; 2575 2576 if (lpConsoleSelectionInfo == NULL) 2577 { 2578 SetLastError(ERROR_INVALID_PARAMETER); 2579 return FALSE; 2580 } 2581 2582 GetSelectionInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2583 2584 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2585 NULL, 2586 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetSelectionInfo), 2587 sizeof(*GetSelectionInfoRequest)); 2588 if (!NT_SUCCESS(ApiMessage.Status)) 2589 { 2590 BaseSetLastNTError(ApiMessage.Status); 2591 return FALSE; 2592 } 2593 2594 *lpConsoleSelectionInfo = GetSelectionInfoRequest->Info; 2595 2596 return TRUE; 2597} 2598 2599 2600/* 2601 * @implemented 2602 * @note Strongly inspired by AllocConsole. 2603 */ 2604static BOOL 2605IntAttachConsole(DWORD ProcessId, 2606 LPTHREAD_START_ROUTINE CtrlRoutine, 2607 LPTHREAD_START_ROUTINE PropRoutine, 2608 PCONSOLE_START_INFO ConsoleStartInfo) 2609{ 2610 BOOL Success = TRUE; 2611 NTSTATUS Status; 2612 2613 CONSOLE_API_MESSAGE ApiMessage; 2614 PCONSOLE_ATTACHCONSOLE AttachConsoleRequest = &ApiMessage.Data.AttachConsoleRequest; 2615 PCSR_CAPTURE_BUFFER CaptureBuffer; 2616 2617 AttachConsoleRequest->ProcessId = ProcessId; 2618 AttachConsoleRequest->CtrlRoutine = CtrlRoutine; 2619 AttachConsoleRequest->PropRoutine = PropRoutine; 2620 2621 CaptureBuffer = CsrAllocateCaptureBuffer(1, sizeof(CONSOLE_START_INFO)); 2622 if (CaptureBuffer == NULL) 2623 { 2624 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 2625 Success = FALSE; 2626 goto Quit; 2627 } 2628 2629 CsrCaptureMessageBuffer(CaptureBuffer, 2630 ConsoleStartInfo, 2631 sizeof(CONSOLE_START_INFO), 2632 (PVOID*)&AttachConsoleRequest->ConsoleStartInfo); 2633 2634 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2635 CaptureBuffer, 2636 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAttach), 2637 sizeof(*AttachConsoleRequest)); 2638 if (!NT_SUCCESS(ApiMessage.Status)) 2639 { 2640 BaseSetLastNTError(ApiMessage.Status); 2641 Success = FALSE; 2642 goto Quit; 2643 } 2644 2645 // Is AttachConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? 2646 Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, 2647 AttachConsoleRequest->ConsoleStartInfo->InitEvents, 2648 WaitAny, FALSE, NULL); 2649 if (!NT_SUCCESS(Status)) 2650 { 2651 BaseSetLastNTError(Status); 2652 Success = FALSE; 2653 goto Quit; 2654 } 2655 2656 NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); 2657 NtClose(AttachConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); 2658 if (Status != INIT_SUCCESS) 2659 { 2660 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; 2661 Success = FALSE; 2662 } 2663 else 2664 { 2665 RtlCopyMemory(ConsoleStartInfo, 2666 AttachConsoleRequest->ConsoleStartInfo, 2667 sizeof(CONSOLE_START_INFO)); 2668 Success = TRUE; 2669 } 2670 2671Quit: 2672 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); 2673 return Success; 2674} 2675 2676BOOL 2677WINAPI 2678AttachConsole(DWORD dwProcessId) 2679{ 2680 BOOL Success; 2681 CONSOLE_START_INFO ConsoleStartInfo; 2682 DWORD dummy; 2683 2684 RtlEnterCriticalSection(&ConsoleLock); 2685 2686 if (NtCurrentPeb()->ProcessParameters->ConsoleHandle) 2687 { 2688 DPRINT1("AttachConsole: Attaching a console to a process already having one\n"); 2689 SetLastError(ERROR_ACCESS_DENIED); 2690 Success = FALSE; 2691 goto Quit; 2692 } 2693 2694 /* Set up the console properties */ 2695 SetUpConsoleInfo(FALSE, 2696 &dummy, 2697 NULL, 2698 &dummy, 2699 NULL, 2700 &ConsoleStartInfo); 2701 2702 Success = IntAttachConsole(dwProcessId, 2703 ConsoleControlDispatcher, 2704 PropDialogHandler, 2705 &ConsoleStartInfo); 2706 if (Success) 2707 { 2708 /* Set up the handles */ 2709 SetUpHandles(&ConsoleStartInfo); 2710 InputWaitHandle = ConsoleStartInfo.InputWaitHandle; 2711 2712 /* Initialize Console Ctrl Handling */ 2713 InitializeCtrlHandling(); 2714 2715 /* Sync the current thread's LangId with the console's one */ 2716 SetTEBLangID(); 2717 } 2718 2719Quit: 2720 RtlLeaveCriticalSection(&ConsoleLock); 2721 return Success; 2722} 2723 2724 2725/* 2726 * @implemented 2727 */ 2728HWND 2729WINAPI 2730DECLSPEC_HOTPATCH 2731GetConsoleWindow(VOID) 2732{ 2733 CONSOLE_API_MESSAGE ApiMessage; 2734 PCONSOLE_GETWINDOW GetWindowRequest = &ApiMessage.Data.GetWindowRequest; 2735 2736 GetWindowRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2737 2738 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2739 NULL, 2740 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetConsoleWindow), 2741 sizeof(*GetWindowRequest)); 2742 if (!NT_SUCCESS(ApiMessage.Status)) 2743 { 2744 BaseSetLastNTError(ApiMessage.Status); 2745 return (HWND)NULL; 2746 } 2747 2748 return GetWindowRequest->WindowHandle; 2749} 2750 2751 2752/* 2753 * @implemented 2754 */ 2755BOOL 2756WINAPI 2757DECLSPEC_HOTPATCH 2758SetConsoleIcon(HICON hIcon) 2759{ 2760 CONSOLE_API_MESSAGE ApiMessage; 2761 PCONSOLE_SETICON SetIconRequest = &ApiMessage.Data.SetIconRequest; 2762 2763 SetIconRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 2764 SetIconRequest->IconHandle = hIcon; 2765 2766 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 2767 NULL, 2768 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetIcon), 2769 sizeof(*SetIconRequest)); 2770 if (!NT_SUCCESS(ApiMessage.Status)) 2771 { 2772 BaseSetLastNTError(ApiMessage.Status); 2773 return FALSE; 2774 } 2775 2776 return TRUE; 2777} 2778 2779 2780/****************************************************************************** 2781 * \name SetConsoleInputExeNameW 2782 * \brief Sets the console input file name from a unicode string. 2783 * \param lpExeName Pointer to a unicode string with the name. 2784 * \return TRUE if successful, FALSE if unsuccessful. 2785 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255, 2786 * the function fails and sets last error to ERROR_INVALID_PARAMETER. 2787 */ 2788BOOL 2789WINAPI 2790DECLSPEC_HOTPATCH 2791SetConsoleInputExeNameW(IN LPCWSTR lpExeName) 2792{ 2793 DWORD ExeLength; 2794 2795 ExeLength = lstrlenW(lpExeName); 2796 if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH)) 2797 { 2798 /* Fail if string is empty or too long */ 2799 SetLastError(ERROR_INVALID_PARAMETER); 2800 return FALSE; 2801 } 2802 2803 RtlEnterCriticalSection(&ExeNameLock); 2804 _SEH2_TRY 2805 { 2806 /* Set the input EXE name, not NULL terminated */ 2807 RtlCopyMemory(ExeNameBuffer, lpExeName, ExeLength * sizeof(WCHAR)); 2808 ExeNameLength = (USHORT)ExeLength; 2809 } 2810 _SEH2_FINALLY 2811 { 2812 RtlLeaveCriticalSection(&ExeNameLock); 2813 } 2814 _SEH2_END; 2815 2816 return TRUE; 2817} 2818 2819 2820/****************************************************************************** 2821 * \name SetConsoleInputExeNameA 2822 * \brief Sets the console input file name from an ansi string. 2823 * \param lpExeName Pointer to an ansi string with the name. 2824 * \return TRUE if successful, FALSE if unsuccessful. 2825 * \remarks If lpExeName is 0 or the string length is 0 or greater than 255, 2826 * the function fails and sets last error to ERROR_INVALID_PARAMETER. 2827 */ 2828BOOL 2829WINAPI 2830DECLSPEC_HOTPATCH 2831SetConsoleInputExeNameA(IN LPCSTR lpExeName) 2832{ 2833 NTSTATUS Status; 2834#ifdef USE_TEB_STATIC_USTR 2835 PUNICODE_STRING ExeNameU; 2836#else 2837 UNICODE_STRING ExeNameU; 2838#endif 2839 ANSI_STRING ExeNameA; 2840#ifndef USE_TEB_STATIC_USTR 2841 WCHAR Buffer[EXENAME_LENGTH]; 2842#endif 2843 2844#ifdef USE_TEB_STATIC_USTR 2845 /* 2846 * Use the TEB static UNICODE string for storage. It is already 2847 * initialized at process creation time by the Memory Manager. 2848 */ 2849 ExeNameU = &NtCurrentTeb()->StaticUnicodeString; 2850#endif 2851 2852 /* Initialize string for conversion */ 2853 RtlInitAnsiString(&ExeNameA, lpExeName); 2854 2855#if 1 2856 if ((ExeNameA.Length == 0) || (ExeNameA.Length >= EXENAME_LENGTH)) 2857 { 2858 /* Fail if string is empty or too long */ 2859 SetLastError(ERROR_INVALID_PARAMETER); 2860 return FALSE; 2861 } 2862#endif 2863#ifndef USE_TEB_STATIC_USTR 2864 ExeNameU.Length = 0; 2865 ExeNameU.MaximumLength = (USHORT)sizeof(Buffer); 2866 ExeNameU.Buffer = Buffer; 2867#endif 2868 2869#ifdef USE_TEB_STATIC_USTR 2870 Status = RtlAnsiStringToUnicodeString(ExeNameU, &ExeNameA, FALSE); 2871#else 2872 Status = RtlAnsiStringToUnicodeString(&ExeNameU, &ExeNameA, FALSE); 2873#endif 2874 if (!NT_SUCCESS(Status)) 2875 { 2876 /* Fail if string is empty or too long */ 2877 if (Status == STATUS_BUFFER_OVERFLOW) 2878 SetLastError(ERROR_FILENAME_EXCED_RANGE); 2879 else 2880 SetLastError(ERROR_INVALID_PARAMETER); 2881 2882 return FALSE; 2883 } 2884 2885#ifdef USE_TEB_STATIC_USTR 2886 return SetConsoleInputExeNameW(ExeNameU->Buffer); 2887#else 2888 return SetConsoleInputExeNameW(ExeNameU.Buffer); 2889#endif 2890} 2891 2892 2893/****************************************************************************** 2894 * \name GetConsoleInputExeNameW 2895 * \brief Retrieves the console input file name as unicode string. 2896 * \param nBufferLength Length of the buffer in WCHARs. 2897 * Specify 0 to receive the needed buffer length. 2898 * \param lpBuffer Pointer to a buffer that receives the string. 2899 * \return Needed buffer size if \p nBufferLength is 0. 2900 * Otherwise 1 if successful, 2 if buffer is too small. 2901 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer 2902 * is not big enough. 2903 */ 2904DWORD 2905WINAPI 2906DECLSPEC_HOTPATCH 2907GetConsoleInputExeNameW(IN DWORD nBufferLength, 2908 OUT LPWSTR lpExeName) 2909{ 2910 if (nBufferLength <= ExeNameLength) 2911 { 2912 /* Buffer is not large enough! Return the correct size. */ 2913 SetLastError(ERROR_BUFFER_OVERFLOW); 2914 return ExeNameLength + 1; 2915 } 2916 2917 RtlEnterCriticalSection(&ExeNameLock); 2918 _SEH2_TRY 2919 { 2920 /* Copy the input EXE name and NULL-terminate it */ 2921 RtlCopyMemory(lpExeName, ExeNameBuffer, ExeNameLength * sizeof(WCHAR)); 2922 lpExeName[ExeNameLength] = UNICODE_NULL; 2923 } 2924 _SEH2_FINALLY 2925 { 2926 RtlLeaveCriticalSection(&ExeNameLock); 2927 } 2928 _SEH2_END; 2929 2930 return TRUE; 2931} 2932 2933 2934/****************************************************************************** 2935 * \name GetConsoleInputExeNameA 2936 * \brief Retrieves the console input file name as ansi string. 2937 * \param nBufferLength Length of the buffer in CHARs. 2938 * \param lpBuffer Pointer to a buffer that receives the string. 2939 * \return 1 if successful, 2 if buffer is too small. 2940 * \remarks Sets last error value to ERROR_BUFFER_OVERFLOW if the buffer 2941 * is not big enough. The buffer receives as much characters as fit. 2942 */ 2943DWORD 2944WINAPI 2945DECLSPEC_HOTPATCH 2946GetConsoleInputExeNameA(IN DWORD nBufferLength, 2947 OUT LPSTR lpExeName) 2948{ 2949 NTSTATUS Status; 2950 DWORD ExeLength; 2951 UNICODE_STRING BufferU; 2952 ANSI_STRING BufferA; 2953 WCHAR Buffer[EXENAME_LENGTH]; 2954 2955 /* Get the UNICODE name */ 2956 ExeLength = GetConsoleInputExeNameW(EXENAME_LENGTH, Buffer); 2957 2958 if ((ExeLength == 0) || (ExeLength >= EXENAME_LENGTH)) 2959 return ExeLength; 2960 2961 /* Initialize the strings for conversion */ 2962 RtlInitUnicodeString(&BufferU, Buffer); 2963 BufferA.Length = 0; 2964 BufferA.MaximumLength = (USHORT)nBufferLength; 2965 BufferA.Buffer = lpExeName; 2966 2967 /* Convert UNICODE name to ANSI, copying as much chars as it can fit */ 2968 Status = RtlUnicodeStringToAnsiString(&BufferA, &BufferU, FALSE); 2969 if (!NT_SUCCESS(Status)) 2970 { 2971 if (Status == STATUS_BUFFER_OVERFLOW) 2972 { 2973 SetLastError(ERROR_BUFFER_OVERFLOW); 2974 return ExeLength + 1; 2975 } 2976 SetLastError(ERROR_INVALID_PARAMETER); 2977 } 2978 2979 return ExeLength; 2980} 2981 2982BOOL 2983WINAPI 2984GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type) 2985{ 2986 STUB; 2987 return FALSE; 2988} 2989 2990BOOL 2991WINAPI 2992DECLSPEC_HOTPATCH 2993GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2) 2994{ 2995 STUB; 2996 return FALSE; 2997} 2998 2999BOOL 3000WINAPI 3001DECLSPEC_HOTPATCH 3002SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2) 3003{ 3004 STUB; 3005 return FALSE; 3006} 3007 3008BOOL 3009WINAPI 3010DECLSPEC_HOTPATCH 3011GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode) 3012{ 3013 STUB; 3014 return FALSE; 3015} 3016 3017BOOL 3018WINAPI 3019DECLSPEC_HOTPATCH 3020SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode) 3021{ 3022 STUB; 3023 return FALSE; 3024} 3025 3026BOOL 3027WINAPI 3028DECLSPEC_HOTPATCH 3029SetConsoleLocalEUDC( 3030 _In_ HANDLE hConsoleHandle, 3031 _In_ WORD wCodePoint, 3032 _In_ COORD cFontSize, 3033 _In_ PCHAR lpSB) 3034{ 3035 STUB; 3036 return FALSE; 3037} 3038 3039static BOOL 3040IntRegisterConsoleIME( 3041 _In_ HWND hWnd, 3042 _In_ DWORD dwThreadId, 3043 _In_opt_ SIZE_T cbDesktop, 3044 _In_opt_ PWSTR pDesktop, 3045 _Out_opt_ PDWORD pdwAttachToThreadId) 3046{ 3047 CONSOLE_API_MESSAGE ApiMessage; 3048 PCONSOLE_REGISTERCONSOLEIME RegisterConsoleIME = &ApiMessage.Data.RegisterConsoleIME; 3049 PCSR_CAPTURE_BUFFER CaptureBuffer; 3050 3051 if (!cbDesktop || !pDesktop) 3052 { 3053 pDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Buffer; 3054 cbDesktop = NtCurrentPeb()->ProcessParameters->DesktopInfo.Length; 3055 } 3056 3057 cbDesktop = min(cbDesktop, (MAX_PATH + 1) * sizeof(WCHAR)); 3058 3059 RegisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3060 RegisterConsoleIME->hWnd = hWnd; 3061 RegisterConsoleIME->dwThreadId = dwThreadId; 3062 RegisterConsoleIME->cbDesktop = cbDesktop; 3063 3064 CaptureBuffer = CsrAllocateCaptureBuffer(1, cbDesktop); 3065 if (!CaptureBuffer) 3066 { 3067 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3068 return FALSE; 3069 } 3070 3071 CsrCaptureMessageBuffer(CaptureBuffer, 3072 pDesktop, 3073 cbDesktop, 3074 (PVOID*)&RegisterConsoleIME->pDesktop); 3075 3076 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3077 CaptureBuffer, 3078 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepRegisterConsoleIME), 3079 sizeof(*RegisterConsoleIME)); 3080 3081 CsrFreeCaptureBuffer(CaptureBuffer); 3082 3083 if (!NT_SUCCESS(ApiMessage.Status)) 3084 { 3085 BaseSetLastNTError(ApiMessage.Status); 3086 return FALSE; 3087 } 3088 3089 if (pdwAttachToThreadId) 3090 { 3091 _SEH2_TRY 3092 { 3093 *pdwAttachToThreadId = RegisterConsoleIME->dwAttachToThreadId; 3094 } 3095 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 3096 { 3097 BaseSetLastNTError(STATUS_ACCESS_VIOLATION); 3098 _SEH2_YIELD(return FALSE); 3099 } 3100 _SEH2_END; 3101 } 3102 3103 return TRUE; 3104} 3105 3106static BOOL 3107IntUnregisterConsoleIME( 3108 _In_ DWORD dwThreadId) 3109{ 3110 CONSOLE_API_MESSAGE ApiMessage; 3111 PCONSOLE_UNREGISTERCONSOLEIME UnregisterConsoleIME = &ApiMessage.Data.UnregisterConsoleIME; 3112 3113 UnregisterConsoleIME->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3114 UnregisterConsoleIME->dwThreadId = dwThreadId; 3115 3116 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3117 NULL, 3118 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepUnregisterConsoleIME), 3119 sizeof(*UnregisterConsoleIME)); 3120 if (!NT_SUCCESS(ApiMessage.Status)) 3121 { 3122 BaseSetLastNTError(ApiMessage.Status); 3123 return FALSE; 3124 } 3125 3126 return TRUE; 3127} 3128 3129/* This function is called by CONIME.EXE */ 3130BOOL 3131WINAPI 3132DECLSPEC_HOTPATCH 3133RegisterConsoleIME( 3134 _In_ HWND hWnd, 3135 _Out_opt_ LPDWORD pdwAttachToThreadId) 3136{ 3137 return IntRegisterConsoleIME(hWnd, 3138 GetCurrentThreadId(), 3139 0, 3140 NULL, 3141 pdwAttachToThreadId); 3142} 3143 3144BOOL 3145WINAPI 3146DECLSPEC_HOTPATCH 3147RegisterConsoleOS2(BOOL bUnknown) 3148{ 3149 STUB; 3150 return FALSE; 3151} 3152 3153BOOL 3154WINAPI 3155DECLSPEC_HOTPATCH 3156SetConsoleOS2OemFormat(BOOL bUnknown) 3157{ 3158 STUB; 3159 return FALSE; 3160} 3161 3162/* This function is called by CONIME.EXE */ 3163BOOL 3164WINAPI 3165DECLSPEC_HOTPATCH 3166UnregisterConsoleIME(VOID) 3167{ 3168 return IntUnregisterConsoleIME(GetCurrentThreadId()); 3169} 3170 3171/** 3172 * @brief 3173 * Internal helper function used to synchronize the current 3174 * thread's language ID with the one from the console. 3175 **/ 3176VOID 3177SetTEBLangID(VOID) 3178{ 3179 CONSOLE_API_MESSAGE ApiMessage; 3180 PCONSOLE_GETLANGID LangIdRequest = &ApiMessage.Data.LangIdRequest; 3181 3182 /* Retrieve the "best-suited" language ID corresponding 3183 * to the active console output code page. */ 3184 LangIdRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3185 3186 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3187 NULL, 3188 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLangId), 3189 sizeof(*LangIdRequest)); 3190 if (!NT_SUCCESS(ApiMessage.Status)) 3191 { 3192 /* 3193 * No best console language ID: keep the current thread's one. 3194 * Since this internal function only modifies an optional setting, 3195 * don't set any last error, as it could otherwise mess with the 3196 * main last error set by the caller. 3197 */ 3198 return; 3199 } 3200 3201 /* 3202 * We succeeded, set the current thread's language ID by 3203 * modifying its locale -- Windows <= 2003 does not have 3204 * the concept of a separate thread UI language. 3205 * Ignore the returned value. 3206 */ 3207 if (!SetThreadLocale(MAKELCID(LangIdRequest->LangId, SORT_DEFAULT))) 3208 { 3209 DPRINT1("SetTEBLangID: Could not set thread locale to console lang ID %lu\n", 3210 LangIdRequest->LangId); 3211 } 3212} 3213 3214static 3215BOOL 3216IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName, 3217 IN BOOL bAnsi) 3218{ 3219 CONSOLE_API_MESSAGE ApiMessage; 3220 PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest; 3221 3222 /* Set up the data to send to the Console Server */ 3223 GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3224 GetKbdLayoutNameRequest->Ansi = bAnsi; 3225 3226 /* Call the server */ 3227 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3228 NULL, 3229 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName), 3230 sizeof(*GetKbdLayoutNameRequest)); 3231 3232 /* Check for success */ 3233 if (!NT_SUCCESS(ApiMessage.Status)) 3234 { 3235 BaseSetLastNTError(ApiMessage.Status); 3236 return FALSE; 3237 } 3238 3239 /* Retrieve the results */ 3240 _SEH2_TRY 3241 { 3242 /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */ 3243 if (bAnsi) 3244 strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); 3245 else 3246 wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); 3247 } 3248 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 3249 { 3250 SetLastError(ERROR_INVALID_ACCESS); 3251 _SEH2_YIELD(return FALSE); 3252 } 3253 _SEH2_END; 3254 3255 return TRUE; 3256} 3257 3258/* 3259 * @implemented (undocumented) 3260 */ 3261BOOL 3262WINAPI 3263DECLSPEC_HOTPATCH 3264GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName) 3265{ 3266 return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE); 3267} 3268 3269/* 3270 * @implemented (undocumented) 3271 */ 3272BOOL 3273WINAPI 3274DECLSPEC_HOTPATCH 3275GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName) 3276{ 3277 return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE); 3278} 3279 3280/* 3281 * @implemented 3282 */ 3283DWORD 3284WINAPI 3285SetLastConsoleEventActive(VOID) 3286{ 3287 CONSOLE_API_MESSAGE ApiMessage; 3288 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest; 3289 3290 /* Set the flag used by the console control dispatcher */ 3291 LastCloseNotify = TRUE; 3292 3293 /* Set up the input arguments */ 3294 NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3295 3296 /* Call CSRSS; just return the NTSTATUS cast to DWORD */ 3297 return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3298 NULL, 3299 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose), 3300 sizeof(*NotifyLastCloseRequest)); 3301} 3302 3303/* EOF */