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