1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: dll/win32/kernel32/client/console/console.c 5 * PURPOSE: Win32 server console functions 6 * PROGRAMMERS: James Tabor <jimtabor@adsl-64-217-116-74.dsl.hstntx.swbell.net> 7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr) 8 */ 9 10 /* INCLUDES *******************************************************************/ 11 12 #include <k32.h> 13 14 #define NDEBUG 15 #include <debug.h> 16 17 18 /* GLOBALS ********************************************************************/ 19 20 extern RTL_CRITICAL_SECTION ConsoleLock; 21 extern BOOLEAN ConsoleInitialized; 22 23 /* Console reserved "file" names */ 24 static LPCWSTR BaseConFileName = CONSOLE_FILE_NAME; 25 static LPCWSTR BaseConInputFileName = CONSOLE_INPUT_FILE_NAME; 26 static LPCWSTR BaseConOutputFileName = CONSOLE_OUTPUT_FILE_NAME; 27 28 /* Console Control handling */ 29 static PHANDLER_ROUTINE InitialHandler[1]; 30 static PHANDLER_ROUTINE* CtrlHandlers; 31 static ULONG NrCtrlHandlers; 32 static ULONG NrAllocatedHandlers; 33 static BOOLEAN LastCloseNotify = FALSE; 34 35 extern BOOL WINAPI IsDebuggerPresent(VOID); 36 37 /* Console Input facilities */ 38 HANDLE InputWaitHandle = INVALID_HANDLE_VALUE; 39 40 #define EXENAME_LENGTH (255 + 1) 41 static RTL_CRITICAL_SECTION ExeNameLock; 42 static BOOLEAN ExeNameInitialized; 43 static WCHAR ExeNameBuffer[EXENAME_LENGTH]; // NULL-terminated 44 static USHORT ExeNameLength; // Count in number of characters without NULL 45 static WCHAR StartDirBuffer[MAX_PATH + 1]; // NULL-terminated 46 static USHORT StartDirLength; // Count in number of characters without NULL 47 48 49 /* Default Console Control Handler ********************************************/ 50 51 static BOOL 52 WINAPI 53 DefaultConsoleCtrlHandler(DWORD Event) 54 { 55 DPRINT("Default handler called: %lx\n", Event); 56 switch(Event) 57 { 58 case CTRL_C_EVENT: 59 DPRINT("Ctrl-C Event\n"); 60 break; 61 62 case CTRL_BREAK_EVENT: 63 DPRINT("Ctrl-Break Event\n"); 64 break; 65 66 case CTRL_CLOSE_EVENT: 67 DPRINT("Ctrl Close Event\n"); 68 break; 69 70 case CTRL_LAST_CLOSE_EVENT: 71 DPRINT("Ctrl Last Close Event\n"); 72 break; 73 74 case CTRL_LOGOFF_EVENT: 75 DPRINT("Ctrl Logoff Event\n"); 76 break; 77 78 case CTRL_SHUTDOWN_EVENT: 79 DPRINT("Ctrl Shutdown Event\n"); 80 break; 81 } 82 83 ExitProcess(CONTROL_C_EXIT); 84 return TRUE; 85 } 86 87 DWORD 88 WINAPI 89 ConsoleControlDispatcher(IN LPVOID lpThreadParameter) 90 { 91 DWORD nExitCode = 0; 92 DWORD CodeAndFlag = PtrToUlong(lpThreadParameter); 93 DWORD nCode = CodeAndFlag & MAXLONG; 94 UINT i; 95 EXCEPTION_RECORD erException; 96 97 DPRINT1("Console Dispatcher Active: %lx %lx\n", CodeAndFlag, nCode); 98 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); 99 100 switch(nCode) 101 { 102 case CTRL_C_EVENT: 103 case CTRL_BREAK_EVENT: 104 { 105 if (IsDebuggerPresent()) 106 { 107 erException.ExceptionCode = (nCode == CTRL_C_EVENT ? 108 DBG_CONTROL_C : DBG_CONTROL_BREAK); 109 erException.ExceptionFlags = 0; 110 erException.ExceptionRecord = NULL; 111 erException.ExceptionAddress = DefaultConsoleCtrlHandler; 112 erException.NumberParameters = 0; 113 114 _SEH2_TRY 115 { 116 RtlRaiseException(&erException); 117 } 118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 119 { 120 RtlEnterCriticalSection(&ConsoleLock); 121 122 if ((nCode != CTRL_C_EVENT) || 123 (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) 124 { 125 for (i = NrCtrlHandlers; i > 0; i--) 126 { 127 if (CtrlHandlers[i - 1](nCode)) break; 128 } 129 } 130 131 RtlLeaveCriticalSection(&ConsoleLock); 132 } 133 _SEH2_END; 134 135 ExitThread(0); 136 } 137 break; 138 } 139 140 case CTRL_CLOSE_EVENT: 141 case CTRL_LOGOFF_EVENT: 142 case CTRL_SHUTDOWN_EVENT: 143 break; 144 145 case CTRL_LAST_CLOSE_EVENT: 146 /* 147 * In case the console app hasn't register for last close notification, 148 * just kill this console handler thread. We don't want that such apps 149 * get killed for unexpected reasons. On the contrary apps that registered 150 * can be killed because they expect to be. 151 */ 152 if (!LastCloseNotify) ExitThread(0); 153 break; 154 155 case 4: 156 ExitProcess(CONTROL_C_EXIT); 157 break; 158 159 default: 160 ASSERT(FALSE); 161 break; 162 } 163 164 ASSERT(ConsoleInitialized); 165 166 RtlEnterCriticalSection(&ConsoleLock); 167 168 nExitCode = 0; 169 if ((nCode != CTRL_C_EVENT) || (NtCurrentPeb()->ProcessParameters->ConsoleFlags != 1)) 170 { 171 for (i = NrCtrlHandlers; i > 0; i--) 172 { 173 if ((i == 1) && 174 (CodeAndFlag & MINLONG) && 175 ((nCode == CTRL_LOGOFF_EVENT) || (nCode == CTRL_SHUTDOWN_EVENT))) 176 { 177 DPRINT("Skipping system/service apps\n"); 178 break; 179 } 180 181 if (CtrlHandlers[i - 1](nCode)) 182 { 183 switch(nCode) 184 { 185 case CTRL_CLOSE_EVENT: 186 case CTRL_LAST_CLOSE_EVENT: 187 case CTRL_LOGOFF_EVENT: 188 case CTRL_SHUTDOWN_EVENT: 189 nExitCode = CodeAndFlag; 190 break; 191 } 192 break; 193 } 194 } 195 } 196 197 RtlLeaveCriticalSection(&ConsoleLock); 198 199 ExitThread(nExitCode); 200 return STATUS_SUCCESS; 201 } 202 203 VOID 204 InitializeCtrlHandling(VOID) 205 { 206 /* Initialize Console Ctrl Handler */ 207 NrAllocatedHandlers = NrCtrlHandlers = 1; 208 CtrlHandlers = InitialHandler; 209 CtrlHandlers[0] = DefaultConsoleCtrlHandler; 210 } 211 212 213 /* Input EXE Name Support *****************************************************/ 214 215 VOID 216 InitExeName(VOID) 217 { 218 NTSTATUS Status; 219 PPEB Peb = NtCurrentPeb(); 220 PCURDIR CurrentDirectory = &Peb->ProcessParameters->CurrentDirectory; 221 PLDR_DATA_TABLE_ENTRY ImageEntry; 222 223 if (ExeNameInitialized) return; 224 225 /* Initialize the EXE name lock */ 226 Status = RtlInitializeCriticalSection(&ExeNameLock); 227 if (!NT_SUCCESS(Status)) return; 228 ExeNameInitialized = TRUE; 229 230 ImageEntry = CONTAINING_RECORD(Peb->Ldr->InLoadOrderModuleList.Flink, 231 LDR_DATA_TABLE_ENTRY, 232 InLoadOrderLinks); 233 234 /* Retrieve the EXE name, NULL-terminate it... */ 235 ExeNameLength = min(sizeof(ExeNameBuffer)/sizeof(ExeNameBuffer[0]), 236 ImageEntry->BaseDllName.Length / sizeof(WCHAR)); 237 RtlCopyMemory(ExeNameBuffer, 238 ImageEntry->BaseDllName.Buffer, 239 ImageEntry->BaseDllName.Length); 240 ExeNameBuffer[ExeNameLength] = UNICODE_NULL; 241 242 /* ... and retrieve the current directory path and NULL-terminate it. */ 243 StartDirLength = min(sizeof(StartDirBuffer)/sizeof(StartDirBuffer[0]), 244 CurrentDirectory->DosPath.Length / sizeof(WCHAR)); 245 RtlCopyMemory(StartDirBuffer, 246 CurrentDirectory->DosPath.Buffer, 247 CurrentDirectory->DosPath.Length); 248 StartDirBuffer[StartDirLength] = UNICODE_NULL; 249 } 250 251 /* 252 * NOTE: 253 * The "LPDWORD Length" parameters point on input to the maximum size of 254 * the buffers that can hold data (if != 0), and on output they hold the 255 * real size of the data. If "Length" are == 0 on input, then on output 256 * they receive the full size of the data. 257 * The "LPWSTR* String" parameters have a double meaning: 258 * - when "CaptureStrings" is TRUE, data is copied to the buffers pointed 259 * by the pointers (*String). 260 * - when "CaptureStrings" is FALSE, "*String" are set to the addresses of 261 * the source data. 262 */ 263 VOID 264 SetUpAppName(IN BOOLEAN CaptureStrings, 265 IN OUT LPDWORD CurDirLength, 266 IN OUT LPWSTR* CurDir, 267 IN OUT LPDWORD AppNameLength, 268 IN OUT LPWSTR* AppName) 269 { 270 DWORD Length; 271 272 /* Retrieve the needed buffer size */ 273 Length = (StartDirLength + 1) * sizeof(WCHAR); 274 if (*CurDirLength > 0) Length = min(Length, *CurDirLength); 275 *CurDirLength = Length; 276 277 /* Capture the data if needed, or, return a pointer to it */ 278 if (CaptureStrings) 279 { 280 /* 281 * Length is always >= sizeof(WCHAR). Copy everything but the 282 * possible trailing NULL character, and then NULL-terminate. 283 */ 284 Length -= sizeof(WCHAR); 285 RtlCopyMemory(*CurDir, StartDirBuffer, Length); 286 (*CurDir)[Length / sizeof(WCHAR)] = UNICODE_NULL; 287 } 288 else 289 { 290 *CurDir = StartDirBuffer; 291 } 292 293 /* Retrieve the needed buffer size */ 294 Length = (ExeNameLength + 1) * sizeof(WCHAR); 295 if (*AppNameLength > 0) Length = min(Length, *AppNameLength); 296 *AppNameLength = Length; 297 298 /* Capture the data if needed, or, return a pointer to it */ 299 if (CaptureStrings) 300 { 301 /* 302 * Length is always >= sizeof(WCHAR). Copy everything but the 303 * possible trailing NULL character, and then NULL-terminate. 304 */ 305 Length -= sizeof(WCHAR); 306 RtlCopyMemory(*AppName, ExeNameBuffer, Length); 307 (*AppName)[Length / sizeof(WCHAR)] = UNICODE_NULL; 308 } 309 else 310 { 311 *AppName = ExeNameBuffer; 312 } 313 } 314 315 USHORT 316 GetCurrentExeName(OUT PWCHAR ExeName, 317 IN USHORT BufferSize) 318 { 319 USHORT ExeLength; 320 321 if (ExeNameInitialized) 322 { 323 RtlEnterCriticalSection(&ExeNameLock); 324 325 if (BufferSize > ExeNameLength * sizeof(WCHAR)) 326 BufferSize = ExeNameLength * sizeof(WCHAR); 327 328 RtlCopyMemory(ExeName, ExeNameBuffer, BufferSize); 329 330 RtlLeaveCriticalSection(&ExeNameLock); 331 ExeLength = BufferSize; 332 } 333 else 334 { 335 *ExeName = UNICODE_NULL; 336 ExeLength = 0; 337 } 338 339 return ExeLength; 340 } 341 342 /* FUNCTIONS ******************************************************************/ 343 344 LPCWSTR 345 IntCheckForConsoleFileName(IN LPCWSTR pszName, 346 IN DWORD dwDesiredAccess) 347 { 348 LPCWSTR ConsoleName = pszName; 349 ULONG DeviceNameInfo; 350 351 /* 352 * Check whether we deal with a DOS device, and if so, 353 * strip the path till the file name. 354 * Therefore, things like \\.\CON or C:\some_path\CONIN$ 355 * are transformed into CON or CONIN$, for example. 356 */ 357 DeviceNameInfo = RtlIsDosDeviceName_U(pszName); 358 if (DeviceNameInfo != 0) 359 { 360 ConsoleName = (LPCWSTR)((ULONG_PTR)ConsoleName + ((DeviceNameInfo >> 16) & 0xFFFF)); 361 } 362 363 /* Return a standard console "file" name according to what we passed in parameters */ 364 if (_wcsicmp(ConsoleName, BaseConInputFileName) == 0) 365 { 366 return BaseConInputFileName; 367 } 368 else if (_wcsicmp(ConsoleName, BaseConOutputFileName) == 0) 369 { 370 return BaseConOutputFileName; 371 } 372 else if (_wcsicmp(ConsoleName, BaseConFileName) == 0) 373 { 374 if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_READ) 375 { 376 return BaseConInputFileName; 377 } 378 else if ((dwDesiredAccess & (GENERIC_READ | GENERIC_WRITE)) == GENERIC_WRITE) 379 { 380 return BaseConOutputFileName; 381 } 382 } 383 384 /* If we are there, that means that either the file name or the desired access are wrong */ 385 return NULL; 386 } 387 388 389 /* 390 * @implemented (Undocumented) 391 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ConsoleMenuControl.php 392 */ 393 HMENU 394 WINAPI 395 DECLSPEC_HOTPATCH 396 ConsoleMenuControl(HANDLE hConsoleOutput, 397 DWORD dwCmdIdLow, 398 DWORD dwCmdIdHigh) 399 { 400 CONSOLE_API_MESSAGE ApiMessage; 401 PCONSOLE_MENUCONTROL MenuControlRequest = &ApiMessage.Data.MenuControlRequest; 402 403 MenuControlRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 404 MenuControlRequest->OutputHandle = hConsoleOutput; 405 MenuControlRequest->CmdIdLow = dwCmdIdLow; 406 MenuControlRequest->CmdIdHigh = dwCmdIdHigh; 407 MenuControlRequest->MenuHandle = NULL; 408 409 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 410 NULL, 411 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepMenuControl), 412 sizeof(*MenuControlRequest)); 413 414 return MenuControlRequest->MenuHandle; 415 } 416 417 418 /* 419 * @implemented 420 */ 421 HANDLE 422 WINAPI 423 DECLSPEC_HOTPATCH 424 DuplicateConsoleHandle(HANDLE hConsole, 425 DWORD dwDesiredAccess, 426 BOOL bInheritHandle, 427 DWORD dwOptions) 428 { 429 CONSOLE_API_MESSAGE ApiMessage; 430 PCONSOLE_DUPLICATEHANDLE DuplicateHandleRequest = &ApiMessage.Data.DuplicateHandleRequest; 431 432 if ( (dwOptions & ~(DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) || 433 (!(dwOptions & DUPLICATE_SAME_ACCESS) && 434 (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE))) ) 435 { 436 SetLastError(ERROR_INVALID_PARAMETER); 437 return INVALID_HANDLE_VALUE; 438 } 439 440 DuplicateHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 441 DuplicateHandleRequest->SourceHandle = hConsole; 442 DuplicateHandleRequest->DesiredAccess = dwDesiredAccess; 443 DuplicateHandleRequest->InheritHandle = bInheritHandle; 444 DuplicateHandleRequest->Options = dwOptions; 445 446 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 447 NULL, 448 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepDuplicateHandle), 449 sizeof(*DuplicateHandleRequest)); 450 if (!NT_SUCCESS(ApiMessage.Status)) 451 { 452 BaseSetLastNTError(ApiMessage.Status); 453 return INVALID_HANDLE_VALUE; 454 } 455 456 return DuplicateHandleRequest->TargetHandle; 457 } 458 459 460 /* 461 * @implemented 462 */ 463 BOOL 464 WINAPI 465 GetConsoleHandleInformation(IN HANDLE hHandle, 466 OUT LPDWORD lpdwFlags) 467 { 468 CONSOLE_API_MESSAGE ApiMessage; 469 PCONSOLE_GETHANDLEINFO GetHandleInfoRequest = &ApiMessage.Data.GetHandleInfoRequest; 470 471 GetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 472 GetHandleInfoRequest->Handle = hHandle; 473 474 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 475 NULL, 476 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHandleInformation), 477 sizeof(*GetHandleInfoRequest)); 478 if (!NT_SUCCESS(ApiMessage.Status)) 479 { 480 BaseSetLastNTError(ApiMessage.Status); 481 return FALSE; 482 } 483 484 *lpdwFlags = GetHandleInfoRequest->Flags; 485 486 return TRUE; 487 } 488 489 490 /* 491 * @implemented 492 */ 493 BOOL 494 WINAPI 495 SetConsoleHandleInformation(IN HANDLE hHandle, 496 IN DWORD dwMask, 497 IN DWORD dwFlags) 498 { 499 CONSOLE_API_MESSAGE ApiMessage; 500 PCONSOLE_SETHANDLEINFO SetHandleInfoRequest = &ApiMessage.Data.SetHandleInfoRequest; 501 502 SetHandleInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 503 SetHandleInfoRequest->Handle = hHandle; 504 SetHandleInfoRequest->Mask = dwMask; 505 SetHandleInfoRequest->Flags = dwFlags; 506 507 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 508 NULL, 509 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHandleInformation), 510 sizeof(*SetHandleInfoRequest)); 511 if (!NT_SUCCESS(ApiMessage.Status)) 512 { 513 BaseSetLastNTError(ApiMessage.Status); 514 return FALSE; 515 } 516 517 return TRUE; 518 } 519 520 521 /* 522 * @implemented 523 */ 524 BOOL 525 WINAPI 526 GetConsoleDisplayMode(LPDWORD lpModeFlags) 527 { 528 CONSOLE_API_MESSAGE ApiMessage; 529 PCONSOLE_GETDISPLAYMODE GetDisplayModeRequest = &ApiMessage.Data.GetDisplayModeRequest; 530 531 if (lpModeFlags == NULL) 532 { 533 SetLastError(ERROR_INVALID_PARAMETER); 534 return FALSE; 535 } 536 537 GetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 538 539 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 540 NULL, 541 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetDisplayMode), 542 sizeof(*GetDisplayModeRequest)); 543 if (!NT_SUCCESS(ApiMessage.Status)) 544 { 545 BaseSetLastNTError(ApiMessage.Status); 546 return FALSE; 547 } 548 549 *lpModeFlags = GetDisplayModeRequest->DisplayMode; // ModeFlags 550 551 return TRUE; 552 } 553 554 555 /* 556 * @implemented (Undocumented) 557 * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 558 */ 559 DWORD 560 WINAPI 561 GetConsoleFontInfo(IN HANDLE hConsoleOutput, 562 IN BOOL bMaximumWindow, 563 IN DWORD nFontCount, 564 OUT PCONSOLE_FONT_INFO lpConsoleFontInfo) 565 { 566 CONSOLE_API_MESSAGE ApiMessage; 567 PCONSOLE_GETFONTINFO GetFontInfoRequest = &ApiMessage.Data.GetFontInfoRequest; 568 PCSR_CAPTURE_BUFFER CaptureBuffer; 569 570 GetFontInfoRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 571 GetFontInfoRequest->OutputHandle = hConsoleOutput; 572 GetFontInfoRequest->MaximumWindow = bMaximumWindow; 573 GetFontInfoRequest->NumFonts = nFontCount; 574 575 CaptureBuffer = CsrAllocateCaptureBuffer(1, nFontCount * sizeof(CONSOLE_FONT_INFO)); 576 if (CaptureBuffer == NULL) 577 { 578 DPRINT1("CsrAllocateCaptureBuffer failed!\n"); 579 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 580 return 0; 581 } 582 583 CsrAllocateMessagePointer(CaptureBuffer, 584 nFontCount * sizeof(CONSOLE_FONT_INFO), 585 (PVOID*)&GetFontInfoRequest->FontInfo); 586 587 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 588 CaptureBuffer, 589 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetFontInfo), 590 sizeof(*GetFontInfoRequest)); 591 if (!NT_SUCCESS(ApiMessage.Status)) 592 { 593 BaseSetLastNTError(ApiMessage.Status); 594 } 595 else 596 { 597 RtlCopyMemory(lpConsoleFontInfo, 598 GetFontInfoRequest->FontInfo, 599 GetFontInfoRequest->NumFonts * sizeof(CONSOLE_FONT_INFO)); 600 } 601 602 CsrFreeCaptureBuffer(CaptureBuffer); 603 return GetFontInfoRequest->NumFonts; 604 } 605 606 607 /* 608 * @implemented 609 */ 610 COORD 611 WINAPI 612 DECLSPEC_HOTPATCH 613 GetConsoleFontSize(IN HANDLE hConsoleOutput, 614 IN DWORD nFont) 615 { 616 CONSOLE_API_MESSAGE ApiMessage; 617 PCONSOLE_GETFONTSIZE GetFontSizeRequest = &ApiMessage.Data.GetFontSizeRequest; 618 COORD Empty = {0, 0}; 619 620 GetFontSizeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 621 GetFontSizeRequest->OutputHandle = hConsoleOutput; 622 GetFontSizeRequest->FontIndex = nFont; 623 624 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 625 NULL, 626 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetFontSize), 627 sizeof(*GetFontSizeRequest)); 628 if (!NT_SUCCESS(ApiMessage.Status)) 629 { 630 BaseSetLastNTError(ApiMessage.Status); 631 return Empty; 632 } 633 634 return GetFontSizeRequest->FontSize; 635 } 636 637 638 /* 639 * @implemented (Undocumented) 640 */ 641 BOOL 642 WINAPI 643 GetConsoleHardwareState(HANDLE hConsoleOutput, 644 PDWORD Flags, 645 PDWORD State) 646 { 647 CONSOLE_API_MESSAGE ApiMessage; 648 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest; 649 650 DPRINT1("GetConsoleHardwareState(%lu, 0x%p) UNIMPLEMENTED!\n", Flags, State); 651 652 if (Flags == NULL || State == NULL) 653 { 654 SetLastError(ERROR_INVALID_PARAMETER); 655 return FALSE; 656 } 657 658 HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 659 HardwareStateRequest->OutputHandle = hConsoleOutput; 660 661 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 662 NULL, 663 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetHardwareState), 664 sizeof(*HardwareStateRequest)); 665 if (!NT_SUCCESS(ApiMessage.Status)) 666 { 667 BaseSetLastNTError(ApiMessage.Status); 668 return FALSE; 669 } 670 671 *Flags = HardwareStateRequest->Flags; 672 *State = HardwareStateRequest->State; 673 674 return TRUE; 675 } 676 677 678 /* 679 * @implemented (Undocumented) 680 */ 681 HANDLE 682 WINAPI 683 GetConsoleInputWaitHandle(VOID) 684 { 685 return InputWaitHandle; 686 } 687 688 689 /* 690 * @implemented 691 */ 692 BOOL 693 WINAPI 694 GetCurrentConsoleFont(IN HANDLE hConsoleOutput, 695 IN BOOL bMaximumWindow, 696 OUT PCONSOLE_FONT_INFO lpConsoleCurrentFont) 697 { 698 CONSOLE_API_MESSAGE ApiMessage; 699 PCONSOLE_GETCURRENTFONT GetCurrentFontRequest = &ApiMessage.Data.GetCurrentFontRequest; 700 701 GetCurrentFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 702 GetCurrentFontRequest->OutputHandle = hConsoleOutput; 703 GetCurrentFontRequest->MaximumWindow = bMaximumWindow; 704 705 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 706 NULL, 707 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetCurrentFont), 708 sizeof(*GetCurrentFontRequest)); 709 if (!NT_SUCCESS(ApiMessage.Status)) 710 { 711 BaseSetLastNTError(ApiMessage.Status); 712 return FALSE; 713 } 714 715 lpConsoleCurrentFont->dwFontSize = GetCurrentFontRequest->FontSize; 716 lpConsoleCurrentFont->nFont = GetCurrentFontRequest->FontIndex; 717 718 return TRUE; 719 } 720 721 722 /* 723 * @implemented (Undocumented) 724 * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 725 */ 726 DWORD 727 WINAPI 728 DECLSPEC_HOTPATCH 729 GetNumberOfConsoleFonts(VOID) 730 { 731 CONSOLE_API_MESSAGE ApiMessage; 732 PCONSOLE_GETNUMFONTS GetNumFontsRequest = &ApiMessage.Data.GetNumFontsRequest; 733 734 GetNumFontsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 735 736 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 737 NULL, 738 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetNumberOfFonts), 739 sizeof(*GetNumFontsRequest)); 740 if (!NT_SUCCESS(ApiMessage.Status)) 741 { 742 BaseSetLastNTError(ApiMessage.Status); 743 return 0; 744 } 745 746 return GetNumFontsRequest->NumFonts; 747 } 748 749 750 /* 751 * @implemented (Undocumented) 752 * @note See http://blog.airesoft.co.uk/2012/10/things-ms-can-do-that-they-dont-tell-you-about-console-graphics/ 753 */ 754 BOOL 755 WINAPI 756 InvalidateConsoleDIBits(IN HANDLE hConsoleOutput, 757 IN PSMALL_RECT lpRect) 758 { 759 CONSOLE_API_MESSAGE ApiMessage; 760 PCONSOLE_INVALIDATEDIBITS InvalidateDIBitsRequest = &ApiMessage.Data.InvalidateDIBitsRequest; 761 762 if (lpRect == NULL) 763 { 764 SetLastError(ERROR_INVALID_PARAMETER); 765 return FALSE; 766 } 767 768 InvalidateDIBitsRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 769 InvalidateDIBitsRequest->OutputHandle = hConsoleOutput; 770 InvalidateDIBitsRequest->Region = *lpRect; 771 772 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 773 NULL, 774 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepInvalidateBitMapRect), 775 sizeof(*InvalidateDIBitsRequest)); 776 if (!NT_SUCCESS(ApiMessage.Status)) 777 { 778 BaseSetLastNTError(ApiMessage.Status); 779 return FALSE; 780 } 781 782 return TRUE; 783 } 784 785 786 /* 787 * @implemented (Undocumented) 788 */ 789 HANDLE 790 WINAPI 791 OpenConsoleW(LPCWSTR wsName, 792 DWORD dwDesiredAccess, 793 BOOL bInheritHandle, 794 DWORD dwShareMode) 795 { 796 CONSOLE_API_MESSAGE ApiMessage; 797 PCONSOLE_OPENCONSOLE OpenConsoleRequest = &ApiMessage.Data.OpenConsoleRequest; 798 CONSOLE_HANDLE_TYPE HandleType; 799 800 if (wsName && (_wcsicmp(wsName, BaseConInputFileName) == 0)) 801 { 802 HandleType = HANDLE_INPUT; 803 } 804 else if (wsName && (_wcsicmp(wsName, BaseConOutputFileName) == 0)) 805 { 806 HandleType = HANDLE_OUTPUT; 807 } 808 else 809 { 810 SetLastError(ERROR_INVALID_PARAMETER); 811 return INVALID_HANDLE_VALUE; 812 } 813 814 if ( (dwDesiredAccess & ~(GENERIC_READ | GENERIC_WRITE)) || 815 (dwShareMode & ~(FILE_SHARE_READ | FILE_SHARE_WRITE)) ) 816 { 817 SetLastError(ERROR_INVALID_PARAMETER); 818 return INVALID_HANDLE_VALUE; 819 } 820 821 OpenConsoleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 822 OpenConsoleRequest->HandleType = HandleType; 823 OpenConsoleRequest->DesiredAccess = dwDesiredAccess; 824 OpenConsoleRequest->InheritHandle = bInheritHandle; 825 OpenConsoleRequest->ShareMode = dwShareMode; 826 827 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 828 NULL, 829 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepOpenConsole), 830 sizeof(*OpenConsoleRequest)); 831 if (!NT_SUCCESS(ApiMessage.Status)) 832 { 833 BaseSetLastNTError(ApiMessage.Status); 834 return INVALID_HANDLE_VALUE; 835 } 836 837 return OpenConsoleRequest->Handle; 838 } 839 840 841 /* 842 * @implemented (Undocumented) 843 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleCursor.php 844 */ 845 BOOL 846 WINAPI 847 DECLSPEC_HOTPATCH 848 SetConsoleCursor(HANDLE hConsoleOutput, 849 HCURSOR hCursor) 850 { 851 CONSOLE_API_MESSAGE ApiMessage; 852 PCONSOLE_SETCURSOR SetCursorRequest = &ApiMessage.Data.SetCursorRequest; 853 854 SetCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 855 SetCursorRequest->OutputHandle = hConsoleOutput; 856 SetCursorRequest->CursorHandle = hCursor; 857 858 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 859 NULL, 860 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetCursor), 861 sizeof(*SetCursorRequest)); 862 if (!NT_SUCCESS(ApiMessage.Status)) 863 { 864 BaseSetLastNTError(ApiMessage.Status); 865 return FALSE; 866 } 867 868 return TRUE; 869 } 870 871 872 /* 873 * @implemented 874 */ 875 BOOL 876 WINAPI 877 SetConsoleDisplayMode(HANDLE hConsoleOutput, 878 DWORD dwFlags, // dwModeFlags 879 PCOORD lpNewScreenBufferDimensions) 880 { 881 CONSOLE_API_MESSAGE ApiMessage; 882 PCONSOLE_SETDISPLAYMODE SetDisplayModeRequest = &ApiMessage.Data.SetDisplayModeRequest; 883 884 SetDisplayModeRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 885 SetDisplayModeRequest->OutputHandle = hConsoleOutput; 886 SetDisplayModeRequest->DisplayMode = dwFlags; // ModeFlags ; dwModeFlags 887 SetDisplayModeRequest->NewSBDim.X = 0; 888 SetDisplayModeRequest->NewSBDim.Y = 0; 889 /* SetDisplayModeRequest->EventHandle; */ 890 891 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 892 NULL, 893 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetDisplayMode), 894 sizeof(*SetDisplayModeRequest)); 895 if (!NT_SUCCESS(ApiMessage.Status)) 896 { 897 BaseSetLastNTError(ApiMessage.Status); 898 return FALSE; 899 } 900 901 if (lpNewScreenBufferDimensions) 902 *lpNewScreenBufferDimensions = SetDisplayModeRequest->NewSBDim; 903 904 return TRUE; 905 } 906 907 908 /* 909 * @implemented (Undocumented) 910 * @note See http://cboard.cprogramming.com/windows-programming/102187-console-font-size.html 911 */ 912 BOOL 913 WINAPI 914 DECLSPEC_HOTPATCH 915 SetConsoleFont(IN HANDLE hConsoleOutput, 916 IN DWORD nFont) 917 { 918 CONSOLE_API_MESSAGE ApiMessage; 919 PCONSOLE_SETFONT SetFontRequest = &ApiMessage.Data.SetFontRequest; 920 921 SetFontRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 922 SetFontRequest->OutputHandle = hConsoleOutput; 923 SetFontRequest->FontIndex = nFont; 924 925 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 926 NULL, 927 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetFont), 928 sizeof(*SetFontRequest)); 929 if (!NT_SUCCESS(ApiMessage.Status)) 930 { 931 BaseSetLastNTError(ApiMessage.Status); 932 return FALSE; 933 } 934 935 return TRUE; 936 } 937 938 939 /* 940 * @implemented (Undocumented) 941 */ 942 BOOL 943 WINAPI 944 SetConsoleHardwareState(HANDLE hConsoleOutput, 945 DWORD Flags, 946 DWORD State) 947 { 948 CONSOLE_API_MESSAGE ApiMessage; 949 PCONSOLE_GETSETHWSTATE HardwareStateRequest = &ApiMessage.Data.HardwareStateRequest; 950 951 DPRINT1("SetConsoleHardwareState(%lu, %lu) UNIMPLEMENTED!\n", Flags, State); 952 953 HardwareStateRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 954 HardwareStateRequest->OutputHandle = hConsoleOutput; 955 HardwareStateRequest->Flags = Flags; 956 HardwareStateRequest->State = State; 957 958 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 959 NULL, 960 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetHardwareState), 961 sizeof(*HardwareStateRequest)); 962 if (!NT_SUCCESS(ApiMessage.Status)) 963 { 964 BaseSetLastNTError(ApiMessage.Status); 965 return FALSE; 966 } 967 968 return TRUE; 969 } 970 971 972 /* 973 * @unimplemented (Undocumented) 974 */ 975 BOOL 976 WINAPI 977 DECLSPEC_HOTPATCH 978 SetConsoleKeyShortcuts(DWORD Unknown0, 979 DWORD Unknown1, 980 DWORD Unknown2, 981 DWORD Unknown3) 982 { 983 DPRINT1("SetConsoleKeyShortcuts(0x%x, 0x%x, 0x%x, 0x%x) UNIMPLEMENTED!\n", Unknown0, Unknown1, Unknown2, Unknown3); 984 SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 985 return FALSE; 986 } 987 988 989 /* 990 * @implemented (Undocumented) 991 * @note See http://undoc.airesoft.co.uk/kernel32.dll/SetConsoleMaximumWindowSize.php 992 * Does nothing, returns TRUE only. Checked on Windows Server 2003. 993 */ 994 BOOL 995 WINAPI 996 SetConsoleMaximumWindowSize(HANDLE hConsoleOutput, 997 COORD dwMaximumSize) 998 { 999 DPRINT1("SetConsoleMaximumWindowSize(0x%p, {%d, %d}) does nothing\n", 1000 hConsoleOutput, dwMaximumSize.X, dwMaximumSize.Y); 1001 return TRUE; 1002 } 1003 1004 1005 /* 1006 * @implemented (Undocumented) 1007 */ 1008 BOOL 1009 WINAPI 1010 DECLSPEC_HOTPATCH 1011 SetConsoleMenuClose(BOOL bEnable) 1012 { 1013 CONSOLE_API_MESSAGE ApiMessage; 1014 PCONSOLE_SETMENUCLOSE SetMenuCloseRequest = &ApiMessage.Data.SetMenuCloseRequest; 1015 1016 SetMenuCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1017 SetMenuCloseRequest->Enable = bEnable; 1018 1019 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1020 NULL, 1021 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetMenuClose), 1022 sizeof(*SetMenuCloseRequest)); 1023 if (!NT_SUCCESS(ApiMessage.Status)) 1024 { 1025 BaseSetLastNTError(ApiMessage.Status); 1026 return FALSE; 1027 } 1028 1029 return TRUE; 1030 } 1031 1032 1033 /* 1034 * @implemented (Undocumented) 1035 * @note See http://comments.gmane.org/gmane.comp.lang.harbour.devel/27844 1036 * Usage example: https://github.com/harbour/core/commit/d79a1b7b812cbde6ddf718ebfd6939a24f633e52 1037 */ 1038 BOOL 1039 WINAPI 1040 DECLSPEC_HOTPATCH 1041 SetConsolePalette(HANDLE hConsoleOutput, 1042 HPALETTE hPalette, 1043 UINT dwUsage) 1044 { 1045 CONSOLE_API_MESSAGE ApiMessage; 1046 PCONSOLE_SETPALETTE SetPaletteRequest = &ApiMessage.Data.SetPaletteRequest; 1047 1048 SetPaletteRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1049 SetPaletteRequest->OutputHandle = hConsoleOutput; 1050 SetPaletteRequest->PaletteHandle = hPalette; 1051 SetPaletteRequest->Usage = dwUsage; 1052 1053 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1054 NULL, 1055 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepSetPalette), 1056 sizeof(*SetPaletteRequest)); 1057 if (!NT_SUCCESS(ApiMessage.Status)) 1058 { 1059 BaseSetLastNTError(ApiMessage.Status); 1060 return FALSE; 1061 } 1062 1063 return TRUE; 1064 } 1065 1066 /* 1067 * @implemented (Undocumented) 1068 * @note See http://undoc.airesoft.co.uk/kernel32.dll/ShowConsoleCursor.php 1069 */ 1070 INT 1071 WINAPI 1072 DECLSPEC_HOTPATCH 1073 ShowConsoleCursor(HANDLE hConsoleOutput, 1074 BOOL bShow) 1075 { 1076 CONSOLE_API_MESSAGE ApiMessage; 1077 PCONSOLE_SHOWCURSOR ShowCursorRequest = &ApiMessage.Data.ShowCursorRequest; 1078 1079 ShowCursorRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1080 ShowCursorRequest->OutputHandle = hConsoleOutput; 1081 ShowCursorRequest->Show = bShow; 1082 ShowCursorRequest->RefCount = 0; 1083 1084 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1085 NULL, 1086 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepShowCursor), 1087 sizeof(*ShowCursorRequest)); 1088 1089 return ShowCursorRequest->RefCount; 1090 } 1091 1092 1093 /* 1094 * FUNCTION: Checks whether the given handle is a valid console handle. 1095 * 1096 * ARGUMENTS: 1097 * hIoHandle - Handle to be checked. 1098 * 1099 * RETURNS: 1100 * TRUE : Handle is a valid console handle. 1101 * FALSE: Handle is not a valid console handle. 1102 * 1103 * STATUS: Officially undocumented 1104 * 1105 * @implemented 1106 */ 1107 BOOL 1108 WINAPI 1109 DECLSPEC_HOTPATCH 1110 VerifyConsoleIoHandle(HANDLE hIoHandle) 1111 { 1112 CONSOLE_API_MESSAGE ApiMessage; 1113 PCONSOLE_VERIFYHANDLE VerifyHandleRequest = &ApiMessage.Data.VerifyHandleRequest; 1114 1115 VerifyHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1116 VerifyHandleRequest->Handle = hIoHandle; 1117 VerifyHandleRequest->IsValid = FALSE; 1118 1119 /* If the process is not attached to a console, return invalid handle */ 1120 if (VerifyHandleRequest->ConsoleHandle == NULL) return FALSE; 1121 1122 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1123 NULL, 1124 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepVerifyIoHandle), 1125 sizeof(*VerifyHandleRequest)); 1126 if (!NT_SUCCESS(ApiMessage.Status)) 1127 { 1128 BaseSetLastNTError(ApiMessage.Status); 1129 return FALSE; 1130 } 1131 1132 return VerifyHandleRequest->IsValid; 1133 } 1134 1135 1136 /* 1137 * @implemented (Undocumented) 1138 */ 1139 BOOL 1140 WINAPI 1141 DECLSPEC_HOTPATCH 1142 CloseConsoleHandle(HANDLE hHandle) 1143 { 1144 CONSOLE_API_MESSAGE ApiMessage; 1145 PCONSOLE_CLOSEHANDLE CloseHandleRequest = &ApiMessage.Data.CloseHandleRequest; 1146 1147 CloseHandleRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 1148 CloseHandleRequest->Handle = hHandle; 1149 1150 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1151 NULL, 1152 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepCloseHandle), 1153 sizeof(*CloseHandleRequest)); 1154 if (!NT_SUCCESS(ApiMessage.Status)) 1155 { 1156 BaseSetLastNTError(ApiMessage.Status); 1157 return FALSE; 1158 } 1159 1160 return TRUE; 1161 } 1162 1163 1164 /* 1165 * @implemented 1166 */ 1167 HANDLE 1168 WINAPI 1169 DECLSPEC_HOTPATCH 1170 GetStdHandle(DWORD nStdHandle) 1171 /* 1172 * FUNCTION: Get a handle for the standard input, standard output 1173 * and a standard error device. 1174 * 1175 * ARGUMENTS: 1176 * nStdHandle - Specifies the device for which to return the handle. 1177 * 1178 * RETURNS: If the function succeeds, the return value is the handle 1179 * of the specified device. Otherwise the value is INVALID_HANDLE_VALUE. 1180 */ 1181 { 1182 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; 1183 HANDLE Handle = INVALID_HANDLE_VALUE; 1184 1185 switch (nStdHandle) 1186 { 1187 case STD_INPUT_HANDLE: 1188 Handle = Ppb->StandardInput; 1189 break; 1190 1191 case STD_OUTPUT_HANDLE: 1192 Handle = Ppb->StandardOutput; 1193 break; 1194 1195 case STD_ERROR_HANDLE: 1196 Handle = Ppb->StandardError; 1197 break; 1198 } 1199 1200 /* If the returned handle is invalid, set last error */ 1201 if (Handle == INVALID_HANDLE_VALUE) SetLastError(ERROR_INVALID_HANDLE); 1202 1203 return Handle; 1204 } 1205 1206 1207 /* 1208 * @implemented 1209 */ 1210 BOOL 1211 WINAPI 1212 DECLSPEC_HOTPATCH 1213 SetStdHandle(DWORD nStdHandle, 1214 HANDLE hHandle) 1215 /* 1216 * FUNCTION: Set the handle for the standard input, standard output or 1217 * the standard error device. 1218 * 1219 * ARGUMENTS: 1220 * nStdHandle - Specifies the handle to be set. 1221 * hHandle - The handle to set. 1222 * 1223 * RETURNS: TRUE if the function succeeds, FALSE otherwise. 1224 */ 1225 { 1226 PRTL_USER_PROCESS_PARAMETERS Ppb = NtCurrentPeb()->ProcessParameters; 1227 1228 /* No need to check if hHandle == INVALID_HANDLE_VALUE */ 1229 1230 switch (nStdHandle) 1231 { 1232 case STD_INPUT_HANDLE: 1233 Ppb->StandardInput = hHandle; 1234 return TRUE; 1235 1236 case STD_OUTPUT_HANDLE: 1237 Ppb->StandardOutput = hHandle; 1238 return TRUE; 1239 1240 case STD_ERROR_HANDLE: 1241 Ppb->StandardError = hHandle; 1242 return TRUE; 1243 } 1244 1245 /* nStdHandle was invalid, bail out */ 1246 SetLastError(ERROR_INVALID_HANDLE); 1247 return FALSE; 1248 } 1249 1250 1251 /* 1252 * @implemented 1253 */ 1254 static BOOL 1255 IntAllocConsole(LPWSTR Title, 1256 DWORD TitleLength, 1257 LPWSTR Desktop, 1258 DWORD DesktopLength, 1259 LPWSTR CurDir, 1260 DWORD CurDirLength, 1261 LPWSTR AppName, 1262 DWORD AppNameLength, 1263 LPTHREAD_START_ROUTINE CtrlRoutine, 1264 LPTHREAD_START_ROUTINE PropRoutine, 1265 PCONSOLE_START_INFO ConsoleStartInfo) 1266 { 1267 BOOL Success = TRUE; 1268 NTSTATUS Status; 1269 1270 CONSOLE_API_MESSAGE ApiMessage; 1271 PCONSOLE_ALLOCCONSOLE AllocConsoleRequest = &ApiMessage.Data.AllocConsoleRequest; 1272 PCSR_CAPTURE_BUFFER CaptureBuffer; 1273 1274 AllocConsoleRequest->CtrlRoutine = CtrlRoutine; 1275 AllocConsoleRequest->PropRoutine = PropRoutine; 1276 1277 CaptureBuffer = CsrAllocateCaptureBuffer(5, TitleLength + 1278 DesktopLength + 1279 CurDirLength + 1280 AppNameLength + 1281 sizeof(CONSOLE_START_INFO)); 1282 if (CaptureBuffer == NULL) 1283 { 1284 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 1285 Success = FALSE; 1286 goto Quit; 1287 } 1288 1289 CsrCaptureMessageBuffer(CaptureBuffer, 1290 ConsoleStartInfo, 1291 sizeof(CONSOLE_START_INFO), 1292 (PVOID*)&AllocConsoleRequest->ConsoleStartInfo); 1293 1294 AllocConsoleRequest->TitleLength = TitleLength; 1295 CsrCaptureMessageBuffer(CaptureBuffer, 1296 Title, 1297 TitleLength, 1298 (PVOID*)&AllocConsoleRequest->ConsoleTitle); 1299 1300 AllocConsoleRequest->DesktopLength = DesktopLength; 1301 CsrCaptureMessageBuffer(CaptureBuffer, 1302 Desktop, 1303 DesktopLength, 1304 (PVOID*)&AllocConsoleRequest->Desktop); 1305 1306 AllocConsoleRequest->CurDirLength = CurDirLength; 1307 CsrCaptureMessageBuffer(CaptureBuffer, 1308 CurDir, 1309 CurDirLength, 1310 (PVOID*)&AllocConsoleRequest->CurDir); 1311 1312 AllocConsoleRequest->AppNameLength = AppNameLength; 1313 CsrCaptureMessageBuffer(CaptureBuffer, 1314 AppName, 1315 AppNameLength, 1316 (PVOID*)&AllocConsoleRequest->AppName); 1317 1318 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 1319 CaptureBuffer, 1320 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepAlloc), 1321 sizeof(*AllocConsoleRequest)); 1322 if (!NT_SUCCESS(ApiMessage.Status)) 1323 { 1324 BaseSetLastNTError(ApiMessage.Status); 1325 Success = FALSE; 1326 goto Quit; 1327 } 1328 1329 // Is AllocConsoleRequest->ConsoleStartInfo->InitEvents aligned on handle boundary ???? 1330 Status = NtWaitForMultipleObjects(MAX_INIT_EVENTS, 1331 AllocConsoleRequest->ConsoleStartInfo->InitEvents, 1332 WaitAny, FALSE, NULL); 1333 if (!NT_SUCCESS(Status)) 1334 { 1335 BaseSetLastNTError(Status); 1336 Success = FALSE; 1337 goto Quit; 1338 } 1339 1340 NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_SUCCESS]); 1341 NtClose(AllocConsoleRequest->ConsoleStartInfo->InitEvents[INIT_FAILURE]); 1342 if (Status != INIT_SUCCESS) 1343 { 1344 NtCurrentPeb()->ProcessParameters->ConsoleHandle = NULL; 1345 Success = FALSE; 1346 } 1347 else 1348 { 1349 RtlCopyMemory(ConsoleStartInfo, 1350 AllocConsoleRequest->ConsoleStartInfo, 1351 sizeof(CONSOLE_START_INFO)); 1352 Success = TRUE; 1353 } 1354 1355 Quit: 1356 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer); 1357 return Success; 1358 } 1359 1360 BOOL 1361 WINAPI 1362 DECLSPEC_HOTPATCH 1363 AllocConsole(VOID) 1364 { 1365 BOOL Success; 1366 CONSOLE_START_INFO ConsoleStartInfo; 1367 1368 PWCHAR ConsoleTitle; 1369 PWCHAR Desktop; 1370 PWCHAR AppName; 1371 PWCHAR CurDir; 1372 1373 ULONG TitleLength = (MAX_PATH + 1) * sizeof(WCHAR); 1374 ULONG DesktopLength = (MAX_PATH + 1) * sizeof(WCHAR); 1375 ULONG AppNameLength = 128 * sizeof(WCHAR); 1376 ULONG CurDirLength = (MAX_PATH + 1) * sizeof(WCHAR); 1377 1378 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2235 GetConsoleTitleA(LPSTR lpConsoleTitle, 2236 DWORD nSize) 2237 { 2238 return IntGetConsoleTitle(lpConsoleTitle, nSize, FALSE); 2239 } 2240 2241 2242 static BOOL 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 2290 SetConsoleTitleW(LPCWSTR lpConsoleTitle) 2291 { 2292 return IntSetConsoleTitle(lpConsoleTitle, TRUE); 2293 } 2294 2295 2296 /* 2297 * @implemented 2298 */ 2299 BOOL 2300 WINAPI 2301 DECLSPEC_HOTPATCH 2302 SetConsoleTitleA(LPCSTR lpConsoleTitle) 2303 { 2304 return IntSetConsoleTitle(lpConsoleTitle, FALSE); 2305 } 2306 2307 2308 /* 2309 * @implemented 2310 */ 2311 HANDLE 2312 WINAPI 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 2982 GetConsoleCharType(HANDLE hConsole, COORD Coord, PDWORD Type) 2983 { 2984 STUB; 2985 return FALSE; 2986 } 2987 2988 BOOL 2989 WINAPI 2990 DECLSPEC_HOTPATCH 2991 GetConsoleCursorMode(HANDLE hConsole, PBOOL pUnknown1, PBOOL pUnknown2) 2992 { 2993 STUB; 2994 return FALSE; 2995 } 2996 2997 BOOL 2998 WINAPI 2999 DECLSPEC_HOTPATCH 3000 SetConsoleCursorMode(HANDLE hConsole, BOOL Unknown1, BOOL Unknown2) 3001 { 3002 STUB; 3003 return FALSE; 3004 } 3005 3006 BOOL 3007 WINAPI 3008 DECLSPEC_HOTPATCH 3009 GetConsoleNlsMode(HANDLE hConsole, LPDWORD lpMode) 3010 { 3011 STUB; 3012 return FALSE; 3013 } 3014 3015 BOOL 3016 WINAPI 3017 DECLSPEC_HOTPATCH 3018 SetConsoleNlsMode(HANDLE hConsole, DWORD dwMode) 3019 { 3020 STUB; 3021 return FALSE; 3022 } 3023 3024 BOOL 3025 WINAPI 3026 DECLSPEC_HOTPATCH 3027 SetConsoleLocalEUDC(DWORD Unknown1, DWORD Unknown2, DWORD Unknown3, DWORD Unknown4) 3028 { 3029 STUB; 3030 return FALSE; 3031 } 3032 3033 BOOL 3034 WINAPI 3035 DECLSPEC_HOTPATCH 3036 RegisterConsoleIME(HWND hWnd, LPDWORD ThreadId) 3037 { 3038 STUB; 3039 return FALSE; 3040 } 3041 3042 BOOL 3043 WINAPI 3044 DECLSPEC_HOTPATCH 3045 RegisterConsoleOS2(BOOL bUnknown) 3046 { 3047 STUB; 3048 return FALSE; 3049 } 3050 3051 BOOL 3052 WINAPI 3053 DECLSPEC_HOTPATCH 3054 SetConsoleOS2OemFormat(BOOL bUnknown) 3055 { 3056 STUB; 3057 return FALSE; 3058 } 3059 3060 BOOL 3061 WINAPI 3062 DECLSPEC_HOTPATCH 3063 UnregisterConsoleIME(VOID) 3064 { 3065 STUB; 3066 return FALSE; 3067 } 3068 3069 /** 3070 * @brief 3071 * Internal helper function used to synchronize the current 3072 * thread's language ID with the one from the console. 3073 **/ 3074 VOID 3075 SetTEBLangID(VOID) 3076 { 3077 CONSOLE_API_MESSAGE ApiMessage; 3078 PCONSOLE_GETLANGID LangIdRequest = &ApiMessage.Data.LangIdRequest; 3079 3080 /* Retrieve the "best-suited" language ID corresponding 3081 * to the active console output code page. */ 3082 LangIdRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3083 3084 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3085 NULL, 3086 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetLangId), 3087 sizeof(*LangIdRequest)); 3088 if (!NT_SUCCESS(ApiMessage.Status)) 3089 { 3090 /* 3091 * No best console language ID: keep the current thread's one. 3092 * Since this internal function only modifies an optional setting, 3093 * don't set any last error, as it could otherwise mess with the 3094 * main last error set by the caller. 3095 */ 3096 return; 3097 } 3098 3099 /* 3100 * We succeeded, set the current thread's language ID by 3101 * modifying its locale -- Windows <= 2003 does not have 3102 * the concept of a separate thread UI language. 3103 * Ignore the returned value. 3104 */ 3105 if (!SetThreadLocale(MAKELCID(LangIdRequest->LangId, SORT_DEFAULT))) 3106 { 3107 DPRINT1("SetTEBLangID: Could not set thread locale to console lang ID %lu\n", 3108 LangIdRequest->LangId); 3109 } 3110 } 3111 3112 static 3113 BOOL 3114 IntGetConsoleKeyboardLayoutName(OUT PVOID pszLayoutName, 3115 IN BOOL bAnsi) 3116 { 3117 CONSOLE_API_MESSAGE ApiMessage; 3118 PCONSOLE_GETKBDLAYOUTNAME GetKbdLayoutNameRequest = &ApiMessage.Data.GetKbdLayoutNameRequest; 3119 3120 /* Set up the data to send to the Console Server */ 3121 GetKbdLayoutNameRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3122 GetKbdLayoutNameRequest->Ansi = bAnsi; 3123 3124 /* Call the server */ 3125 CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3126 NULL, 3127 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepGetKeyboardLayoutName), 3128 sizeof(*GetKbdLayoutNameRequest)); 3129 3130 /* Check for success */ 3131 if (!NT_SUCCESS(ApiMessage.Status)) 3132 { 3133 BaseSetLastNTError(ApiMessage.Status); 3134 return FALSE; 3135 } 3136 3137 /* Retrieve the results */ 3138 _SEH2_TRY 3139 { 3140 /* Copy only KL_NAMELENGTH == 9 characters, ANSI or UNICODE */ 3141 if (bAnsi) 3142 strncpy(pszLayoutName, (PCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); 3143 else 3144 wcsncpy(pszLayoutName, (PWCHAR)GetKbdLayoutNameRequest->LayoutBuffer, KL_NAMELENGTH); 3145 } 3146 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 3147 { 3148 SetLastError(ERROR_INVALID_ACCESS); 3149 _SEH2_YIELD(return FALSE); 3150 } 3151 _SEH2_END; 3152 3153 return TRUE; 3154 } 3155 3156 /* 3157 * @implemented (undocumented) 3158 */ 3159 BOOL 3160 WINAPI 3161 DECLSPEC_HOTPATCH 3162 GetConsoleKeyboardLayoutNameA(OUT LPSTR pszLayoutName) 3163 { 3164 return IntGetConsoleKeyboardLayoutName(pszLayoutName, TRUE); 3165 } 3166 3167 /* 3168 * @implemented (undocumented) 3169 */ 3170 BOOL 3171 WINAPI 3172 DECLSPEC_HOTPATCH 3173 GetConsoleKeyboardLayoutNameW(OUT LPWSTR pszLayoutName) 3174 { 3175 return IntGetConsoleKeyboardLayoutName(pszLayoutName, FALSE); 3176 } 3177 3178 /* 3179 * @implemented 3180 */ 3181 DWORD 3182 WINAPI 3183 SetLastConsoleEventActive(VOID) 3184 { 3185 CONSOLE_API_MESSAGE ApiMessage; 3186 PCONSOLE_NOTIFYLASTCLOSE NotifyLastCloseRequest = &ApiMessage.Data.NotifyLastCloseRequest; 3187 3188 /* Set the flag used by the console control dispatcher */ 3189 LastCloseNotify = TRUE; 3190 3191 /* Set up the input arguments */ 3192 NotifyLastCloseRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; 3193 3194 /* Call CSRSS; just return the NTSTATUS cast to DWORD */ 3195 return CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, 3196 NULL, 3197 CSR_CREATE_API_NUMBER(CONSRV_SERVERDLL_INDEX, ConsolepNotifyLastClose), 3198 sizeof(*NotifyLastCloseRequest)); 3199 } 3200 3201 /* EOF */ 3202