1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Win32k subsystem 4 * PURPOSE: Miscellaneous User functions 5 * FILE: win32ss/user/ntuser/misc.c 6 * PROGRAMER: Ge van Geldorp (ge@gse.nl) 7 */ 8 9 #include <win32k.h> 10 DBG_DEFAULT_CHANNEL(UserMisc); 11 12 13 /* 14 * NOTE: _scwprintf() is NOT exported by ntoskrnl.exe, 15 * only _vscwprintf() is, so we need to implement it here. 16 * Code comes from sdk/lib/crt/printf/_scwprintf.c . 17 * See also win32ss/user/winsrv/usersrv/harderror.c . 18 */ 19 int 20 __cdecl 21 _scwprintf( 22 const wchar_t *format, 23 ...) 24 { 25 int len; 26 va_list args; 27 28 va_start(args, format); 29 len = _vscwprintf(format, args); 30 va_end(args); 31 32 return len; 33 } 34 35 36 /* 37 * Test the Thread to verify and validate it. Hard to the core tests are required. 38 */ 39 PTHREADINFO 40 FASTCALL 41 IntTID2PTI(HANDLE id) 42 { 43 NTSTATUS Status; 44 PETHREAD Thread; 45 PTHREADINFO pti; 46 Status = PsLookupThreadByThreadId(id, &Thread); 47 if (!NT_SUCCESS(Status)) 48 { 49 return NULL; 50 } 51 if (PsIsThreadTerminating(Thread)) 52 { 53 ObDereferenceObject(Thread); 54 return NULL; 55 } 56 pti = PsGetThreadWin32Thread(Thread); 57 if (!pti) 58 { 59 ObDereferenceObject(Thread); 60 return NULL; 61 } 62 // Validate and verify! 63 _SEH2_TRY 64 { 65 if (pti->TIF_flags & TIF_INCLEANUP) pti = NULL; 66 if (pti && !(pti->TIF_flags & TIF_GUITHREADINITIALIZED)) pti = NULL; 67 if (PsGetThreadId(Thread) != id) pti = NULL; 68 } 69 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 70 { 71 pti = NULL; 72 } 73 _SEH2_END 74 ObDereferenceObject(Thread); 75 return pti; 76 } 77 78 DWORD 79 FASTCALL 80 UserGetLanguageToggle(VOID) 81 { 82 NTSTATUS Status; 83 DWORD dwValue = 0; 84 85 Status = RegReadUserSetting(L"Keyboard Layout\\Toggle", L"Layout Hotkey", REG_SZ, &dwValue, sizeof(dwValue)); 86 if (NT_SUCCESS(Status)) 87 { 88 dwValue = atoi((char *)&dwValue); 89 TRACE("Layout Hotkey %d\n",dwValue); 90 } 91 return dwValue; 92 } 93 94 USHORT 95 FASTCALL 96 UserGetLanguageID(VOID) 97 { 98 HANDLE KeyHandle; 99 OBJECT_ATTRIBUTES ObAttr; 100 // http://support.microsoft.com/kb/324097 101 ULONG Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); 102 PKEY_VALUE_PARTIAL_INFORMATION pKeyInfo; 103 ULONG Size = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + MAX_PATH*sizeof(WCHAR); 104 UNICODE_STRING Language; 105 106 RtlInitUnicodeString( &Language, 107 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language"); 108 109 InitializeObjectAttributes( &ObAttr, 110 &Language, 111 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 112 NULL, 113 NULL); 114 115 if ( NT_SUCCESS(ZwOpenKey(&KeyHandle, KEY_READ, &ObAttr))) 116 { 117 pKeyInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_STRING); 118 if ( pKeyInfo ) 119 { 120 RtlInitUnicodeString(&Language, L"Default"); 121 122 if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle, 123 &Language, 124 KeyValuePartialInformation, 125 pKeyInfo, 126 Size, 127 &Size)) ) 128 { 129 RtlInitUnicodeString(&Language, (PWSTR)pKeyInfo->Data); 130 if (!NT_SUCCESS(RtlUnicodeStringToInteger(&Language, 16, &Ret))) 131 { 132 Ret = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT); 133 } 134 } 135 ExFreePoolWithTag(pKeyInfo, TAG_STRING); 136 } 137 ZwClose(KeyHandle); 138 } 139 TRACE("Language ID = %x\n",Ret); 140 return (USHORT) Ret; 141 } 142 143 HBRUSH 144 FASTCALL 145 GetControlColor( 146 PWND pwndParent, 147 PWND pwnd, 148 HDC hdc, 149 UINT CtlMsg) 150 { 151 HBRUSH hBrush; 152 153 if (!pwndParent) pwndParent = pwnd; 154 155 if ( pwndParent->head.pti->ppi != PsGetCurrentProcessWin32Process()) 156 { 157 return (HBRUSH)IntDefWindowProc( pwndParent, CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd), FALSE); 158 } 159 160 hBrush = (HBRUSH)co_IntSendMessage( UserHMGetHandle(pwndParent), CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd)); 161 162 if (!hBrush || !GreIsHandleValid(hBrush)) 163 { 164 hBrush = (HBRUSH)IntDefWindowProc( pwndParent, CtlMsg, (WPARAM)hdc, (LPARAM)UserHMGetHandle(pwnd), FALSE); 165 } 166 return hBrush; 167 } 168 169 HBRUSH 170 FASTCALL 171 GetControlBrush( 172 PWND pwnd, 173 HDC hdc, 174 UINT ctlType) 175 { 176 PWND pwndParent = IntGetParent(pwnd); 177 return GetControlColor( pwndParent, pwnd, hdc, ctlType); 178 } 179 180 HBRUSH 181 APIENTRY 182 NtUserGetControlBrush( 183 HWND hwnd, 184 HDC hdc, 185 UINT ctlType) 186 { 187 PWND pwnd; 188 HBRUSH hBrush = NULL; 189 190 UserEnterExclusive(); 191 if ( (pwnd = UserGetWindowObject(hwnd)) && 192 ((ctlType - WM_CTLCOLORMSGBOX) < CTLCOLOR_MAX) && 193 hdc ) 194 { 195 hBrush = GetControlBrush(pwnd, hdc, ctlType); 196 } 197 UserLeave(); 198 return hBrush; 199 } 200 201 /* 202 * Called from PaintRect, works almost like wine PaintRect16 but returns hBrush. 203 */ 204 HBRUSH 205 APIENTRY 206 NtUserGetControlColor( 207 HWND hwndParent, 208 HWND hwnd, 209 HDC hdc, 210 UINT CtlMsg) // Wine PaintRect: WM_CTLCOLORMSGBOX + hbrush 211 { 212 PWND pwnd, pwndParent = NULL; 213 HBRUSH hBrush = NULL; 214 215 UserEnterExclusive(); 216 if ( (pwnd = UserGetWindowObject(hwnd)) && 217 ((CtlMsg - WM_CTLCOLORMSGBOX) < CTLCOLOR_MAX) && 218 hdc ) 219 { 220 if (hwndParent) pwndParent = UserGetWindowObject(hwndParent); 221 hBrush = GetControlColor( pwndParent, pwnd, hdc, CtlMsg); 222 } 223 UserLeave(); 224 return hBrush; 225 } 226 227 /* 228 * @unimplemented 229 */ 230 DWORD_PTR APIENTRY 231 NtUserGetThreadState( 232 DWORD Routine) 233 { 234 DWORD_PTR ret = 0; 235 236 TRACE("Enter NtUserGetThreadState\n"); 237 if (Routine != THREADSTATE_GETTHREADINFO) 238 { 239 UserEnterShared(); 240 } 241 else 242 { 243 UserEnterExclusive(); 244 } 245 246 switch (Routine) 247 { 248 case THREADSTATE_GETTHREADINFO: 249 GetW32ThreadInfo(); 250 break; 251 case THREADSTATE_FOCUSWINDOW: 252 ret = (DWORD_PTR)IntGetThreadFocusWindow(); 253 break; 254 case THREADSTATE_CAPTUREWINDOW: 255 /* FIXME: Should use UserEnterShared */ 256 ret = (DWORD_PTR)IntGetCapture(); 257 break; 258 case THREADSTATE_PROGMANWINDOW: 259 ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hProgmanWindow; 260 break; 261 case THREADSTATE_TASKMANWINDOW: 262 ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hTaskManWindow; 263 break; 264 case THREADSTATE_ACTIVEWINDOW: 265 ret = (DWORD_PTR)UserGetActiveWindow(); 266 break; 267 case THREADSTATE_INSENDMESSAGE: 268 { 269 PUSER_SENT_MESSAGE Message = 270 ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->pusmCurrent; 271 TRACE("THREADSTATE_INSENDMESSAGE\n"); 272 273 ret = ISMEX_NOSEND; 274 if (Message) 275 { 276 if (Message->ptiSender) 277 ret = ISMEX_SEND; 278 else 279 { 280 if (Message->CompletionCallback) 281 ret = ISMEX_CALLBACK; 282 else 283 ret = ISMEX_NOTIFY; 284 } 285 /* If ReplyMessage */ 286 if (Message->QS_Flags & QS_SMRESULT) ret |= ISMEX_REPLIED; 287 } 288 289 break; 290 } 291 case THREADSTATE_GETMESSAGETIME: 292 ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast; 293 break; 294 295 case THREADSTATE_UPTIMELASTREAD: 296 { 297 PTHREADINFO pti; 298 pti = PsGetCurrentThreadWin32Thread(); 299 pti->pcti->timeLastRead = EngGetTickCount32(); 300 break; 301 } 302 303 case THREADSTATE_GETINPUTSTATE: 304 ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON); 305 break; 306 307 case THREADSTATE_FOREGROUNDTHREAD: 308 ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue); 309 break; 310 case THREADSTATE_GETCURSOR: 311 ret = (DWORD_PTR) (GetW32ThreadInfo()->MessageQueue->CursorObject ? 312 UserHMGetHandle(GetW32ThreadInfo()->MessageQueue->CursorObject) : 0); 313 break; 314 case THREADSTATE_GETMESSAGEEXTRAINFO: 315 ret = (DWORD_PTR)MsqGetMessageExtraInfo(); 316 break; 317 } 318 319 TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret); 320 UserLeave(); 321 322 return ret; 323 } 324 325 DWORD 326 APIENTRY 327 NtUserSetThreadState( 328 DWORD Set, 329 DWORD Flags) 330 { 331 PTHREADINFO pti; 332 DWORD Ret = 0; 333 // Test the only flags user can change. 334 if (Set & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0; 335 if (Flags & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0; 336 UserEnterExclusive(); 337 pti = PsGetCurrentThreadWin32Thread(); 338 if (pti->MessageQueue) 339 { 340 Ret = pti->MessageQueue->QF_flags; // Get the queue flags. 341 if (Set) 342 pti->MessageQueue->QF_flags |= (Set&Flags); // Set the queue flags. 343 else 344 { 345 if (Flags) pti->MessageQueue->QF_flags &= ~Flags; // Clr the queue flags. 346 } 347 } 348 UserLeave(); 349 return Ret; 350 } 351 352 UINT 353 APIENTRY 354 NtUserGetDoubleClickTime(VOID) 355 { 356 UINT Result; 357 358 TRACE("Enter NtUserGetDoubleClickTime\n"); 359 UserEnterShared(); 360 361 // FIXME: Check if this works on non-interactive winsta 362 Result = gspv.iDblClickTime; 363 364 TRACE("Leave NtUserGetDoubleClickTime, ret=%u\n", Result); 365 UserLeave(); 366 return Result; 367 } 368 369 BOOL 370 APIENTRY 371 NtUserGetGUIThreadInfo( 372 DWORD idThread, /* If NULL use foreground thread */ 373 LPGUITHREADINFO lpgui) 374 { 375 NTSTATUS Status; 376 PTHRDCARETINFO CaretInfo; 377 GUITHREADINFO SafeGui; 378 PDESKTOP Desktop; 379 PUSER_MESSAGE_QUEUE MsgQueue; 380 PTHREADINFO W32Thread, pti; 381 382 DECLARE_RETURN(BOOLEAN); 383 384 TRACE("Enter NtUserGetGUIThreadInfo\n"); 385 UserEnterShared(); 386 387 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD)); 388 if(!NT_SUCCESS(Status)) 389 { 390 SetLastNtError(Status); 391 RETURN( FALSE); 392 } 393 394 if(SafeGui.cbSize != sizeof(GUITHREADINFO)) 395 { 396 EngSetLastError(ERROR_INVALID_PARAMETER); 397 RETURN( FALSE); 398 } 399 400 if (idThread) 401 { 402 pti = PsGetCurrentThreadWin32Thread(); 403 404 // Validate Tread ID 405 W32Thread = IntTID2PTI((HANDLE)(DWORD_PTR)idThread); 406 407 if ( !W32Thread ) 408 { 409 EngSetLastError(ERROR_ACCESS_DENIED); 410 RETURN( FALSE); 411 } 412 413 Desktop = W32Thread->rpdesk; 414 415 // Check Desktop and it must be the same as current. 416 if ( !Desktop || Desktop != pti->rpdesk ) 417 { 418 EngSetLastError(ERROR_ACCESS_DENIED); 419 RETURN( FALSE); 420 } 421 422 if ( W32Thread->MessageQueue ) 423 MsgQueue = W32Thread->MessageQueue; 424 else 425 { 426 if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue; 427 } 428 } 429 else 430 { /* Get the foreground thread */ 431 /* FIXME: Handle NULL queue properly? */ 432 MsgQueue = IntGetFocusMessageQueue(); 433 if(!MsgQueue) 434 { 435 EngSetLastError(ERROR_ACCESS_DENIED); 436 RETURN( FALSE); 437 } 438 } 439 440 CaretInfo = &MsgQueue->CaretInfo; 441 442 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0); 443 /* 444 if (W32Thread->pMenuState->pGlobalPopupMenu) 445 { 446 SafeGui.flags |= GUI_INMENUMODE; 447 448 if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify) 449 SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify); 450 451 if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar) 452 { 453 if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu) 454 { 455 SafeGui.flags |= GUI_SYSTEMMENUMODE; 456 } 457 } 458 else 459 { 460 SafeGui.flags |= GUI_POPUPMENUMODE; 461 } 462 } 463 */ 464 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner; 465 466 if (MsgQueue->MenuOwner) 467 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState; 468 469 if (MsgQueue->MoveSize) 470 SafeGui.flags |= GUI_INMOVESIZE; 471 472 /* FIXME: Add flag GUI_16BITTASK */ 473 474 SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0; 475 SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0; 476 SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0; 477 SafeGui.hwndMoveSize = MsgQueue->MoveSize; 478 SafeGui.hwndCaret = CaretInfo->hWnd; 479 480 SafeGui.rcCaret.left = CaretInfo->Pos.x; 481 SafeGui.rcCaret.top = CaretInfo->Pos.y; 482 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx; 483 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy; 484 485 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO)); 486 if(!NT_SUCCESS(Status)) 487 { 488 SetLastNtError(Status); 489 RETURN( FALSE); 490 } 491 492 RETURN( TRUE); 493 494 CLEANUP: 495 TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_); 496 UserLeave(); 497 END_CLEANUP; 498 } 499 500 501 DWORD 502 APIENTRY 503 NtUserGetGuiResources( 504 HANDLE hProcess, 505 DWORD uiFlags) 506 { 507 PEPROCESS Process; 508 PPROCESSINFO W32Process; 509 NTSTATUS Status; 510 DWORD Ret = 0; 511 DECLARE_RETURN(DWORD); 512 513 TRACE("Enter NtUserGetGuiResources\n"); 514 UserEnterShared(); 515 516 Status = ObReferenceObjectByHandle(hProcess, 517 PROCESS_QUERY_INFORMATION, 518 *PsProcessType, 519 ExGetPreviousMode(), 520 (PVOID*)&Process, 521 NULL); 522 523 if(!NT_SUCCESS(Status)) 524 { 525 SetLastNtError(Status); 526 RETURN( 0); 527 } 528 529 W32Process = (PPROCESSINFO)Process->Win32Process; 530 if(!W32Process) 531 { 532 ObDereferenceObject(Process); 533 EngSetLastError(ERROR_INVALID_PARAMETER); 534 RETURN( 0); 535 } 536 537 switch(uiFlags) 538 { 539 case GR_GDIOBJECTS: 540 { 541 Ret = (DWORD)W32Process->GDIHandleCount; 542 break; 543 } 544 case GR_USEROBJECTS: 545 { 546 Ret = (DWORD)W32Process->UserHandleCount; 547 break; 548 } 549 default: 550 { 551 EngSetLastError(ERROR_INVALID_PARAMETER); 552 break; 553 } 554 } 555 556 ObDereferenceObject(Process); 557 558 RETURN( Ret); 559 560 CLEANUP: 561 TRACE("Leave NtUserGetGuiResources, ret=%lu\n",_ret_); 562 UserLeave(); 563 END_CLEANUP; 564 } 565 566 VOID FASTCALL 567 IntSetWindowState(PWND pWnd, UINT Flag) 568 { 569 UINT bit; 570 if (gptiCurrent->ppi != pWnd->head.pti->ppi) return; 571 bit = 1 << LOWORD(Flag); 572 TRACE("SWS %x\n",bit); 573 switch(HIWORD(Flag)) 574 { 575 case 0: 576 pWnd->state |= bit; 577 break; 578 case 1: 579 pWnd->state2 |= bit; 580 break; 581 case 2: 582 pWnd->ExStyle2 |= bit; 583 break; 584 } 585 } 586 587 VOID FASTCALL 588 IntClearWindowState(PWND pWnd, UINT Flag) 589 { 590 UINT bit; 591 if (gptiCurrent->ppi != pWnd->head.pti->ppi) return; 592 bit = 1 << LOWORD(Flag); 593 TRACE("CWS %x\n",bit); 594 switch(HIWORD(Flag)) 595 { 596 case 0: 597 pWnd->state &= ~bit; 598 break; 599 case 1: 600 pWnd->state2 &= ~bit; 601 break; 602 case 2: 603 pWnd->ExStyle2 &= ~bit; 604 break; 605 } 606 } 607 608 NTSTATUS FASTCALL 609 IntSafeCopyUnicodeString(PUNICODE_STRING Dest, 610 PUNICODE_STRING Source) 611 { 612 NTSTATUS Status; 613 PWSTR Src; 614 615 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING)); 616 if(!NT_SUCCESS(Status)) 617 { 618 return Status; 619 } 620 621 if(Dest->Length > 0x4000) 622 { 623 return STATUS_UNSUCCESSFUL; 624 } 625 626 Src = Dest->Buffer; 627 Dest->Buffer = NULL; 628 Dest->MaximumLength = Dest->Length; 629 630 if(Dest->Length > 0 && Src) 631 { 632 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING); 633 if(!Dest->Buffer) 634 { 635 return STATUS_NO_MEMORY; 636 } 637 638 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length); 639 if(!NT_SUCCESS(Status)) 640 { 641 ExFreePoolWithTag(Dest->Buffer, TAG_STRING); 642 Dest->Buffer = NULL; 643 return Status; 644 } 645 646 647 return STATUS_SUCCESS; 648 } 649 650 /* String is empty */ 651 return STATUS_SUCCESS; 652 } 653 654 NTSTATUS FASTCALL 655 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest, 656 PUNICODE_STRING Source) 657 { 658 NTSTATUS Status; 659 PWSTR Src; 660 661 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING)); 662 if(!NT_SUCCESS(Status)) 663 { 664 return Status; 665 } 666 667 if(Dest->Length > 0x4000) 668 { 669 return STATUS_UNSUCCESSFUL; 670 } 671 672 Src = Dest->Buffer; 673 Dest->Buffer = NULL; 674 Dest->MaximumLength = 0; 675 676 if(Dest->Length > 0 && Src) 677 { 678 Dest->MaximumLength = Dest->Length + sizeof(WCHAR); 679 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING); 680 if(!Dest->Buffer) 681 { 682 return STATUS_NO_MEMORY; 683 } 684 685 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length); 686 if(!NT_SUCCESS(Status)) 687 { 688 ExFreePoolWithTag(Dest->Buffer, TAG_STRING); 689 Dest->Buffer = NULL; 690 return Status; 691 } 692 693 /* Make sure the string is null-terminated */ 694 Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length); 695 *Src = L'\0'; 696 697 return STATUS_SUCCESS; 698 } 699 700 /* String is empty */ 701 return STATUS_SUCCESS; 702 } 703 704 void UserDbgAssertThreadInfo(BOOL showCaller) 705 { 706 PTEB Teb; 707 PPROCESSINFO ppi; 708 PCLIENTINFO pci; 709 PTHREADINFO pti; 710 711 ppi = PsGetCurrentProcessWin32Process(); 712 pti = PsGetCurrentThreadWin32Thread(); 713 Teb = NtCurrentTeb(); 714 pci = GetWin32ClientInfo(); 715 716 ASSERT(Teb); 717 ASSERT(pti); 718 ASSERT(pti->ppi == ppi); 719 ASSERT(pti->pClientInfo == pci); 720 ASSERT(Teb->Win32ThreadInfo == pti); 721 ASSERT(pci->ppi == ppi); 722 ASSERT(pci->fsHooks == pti->fsHooks); 723 ASSERT(pci->ulClientDelta == DesktopHeapGetUserDelta()); 724 if (pti->pcti && pci->pDeskInfo) 725 ASSERT(pci->pClientThreadInfo == (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta)); 726 //if (pti->pcti && IsListEmpty(&pti->SentMessagesListHead)) 727 // ASSERT((pti->pcti->fsChangeBits & QS_SENDMESSAGE) == 0); 728 if (pti->KeyboardLayout) 729 ASSERT(pci->hKL == pti->KeyboardLayout->hkl); 730 if(pti->rpdesk != NULL) 731 ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo); 732 733 /*too bad we still get this assertion*/ 734 735 // Why? Not all flags are passed to the user and doing so could crash the system........ 736 737 /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */ 738 /* if(pci->dwTIFlags != pti->TIF_flags) 739 { 740 ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags); 741 if(showCaller) 742 { 743 DbgPrint("Caller:\n"); 744 KeRosDumpStackFrames(NULL, 10); 745 } 746 pci->dwTIFlags = pti->TIF_flags; 747 } 748 */ 749 } 750 751 void 752 NTAPI 753 UserDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) 754 { 755 UserDbgAssertThreadInfo(FALSE); 756 } 757 758 ULONG_PTR 759 NTAPI 760 UserDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) 761 { 762 /* Make sure that the first syscall is NtUserInitialize */ 763 /* too bad this fails */ 764 // ASSERT(gpepCSRSS); 765 766 UserDbgAssertThreadInfo(TRUE); 767 768 return ulResult; 769 } 770 771 772 PPROCESSINFO 773 GetW32ProcessInfo(VOID) 774 { 775 return (PPROCESSINFO)PsGetCurrentProcessWin32Process(); 776 } 777 778 PTHREADINFO 779 GetW32ThreadInfo(VOID) 780 { 781 UserDbgAssertThreadInfo(TRUE); 782 return (PTHREADINFO)PsGetCurrentThreadWin32Thread(); 783 } 784 785 786 NTSTATUS 787 GetProcessLuid( 788 IN PETHREAD Thread OPTIONAL, 789 IN PEPROCESS Process OPTIONAL, 790 OUT PLUID Luid) 791 { 792 NTSTATUS Status; 793 PACCESS_TOKEN Token = NULL; 794 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 795 BOOLEAN CopyOnOpen, EffectiveOnly; 796 797 if (Thread && Process) 798 return STATUS_INVALID_PARAMETER; 799 800 /* If nothing has been specified, use the current thread */ 801 if (!Thread && !Process) 802 Thread = PsGetCurrentThread(); 803 804 if (Thread) 805 { 806 /* Use a thread token */ 807 ASSERT(!Process); 808 Token = PsReferenceImpersonationToken(Thread, 809 &CopyOnOpen, 810 &EffectiveOnly, 811 &ImpersonationLevel); 812 813 /* If we don't have a thread token, use a process token */ 814 if (!Token) 815 Process = PsGetThreadProcess(Thread); 816 } 817 if (!Token && Process) 818 { 819 /* Use a process token */ 820 Token = PsReferencePrimaryToken(Process); 821 822 /* If we don't have a token, fail */ 823 if (!Token) 824 return STATUS_NO_TOKEN; 825 } 826 ASSERT(Token); 827 828 /* Query the LUID */ 829 Status = SeQueryAuthenticationIdToken(Token, Luid); 830 831 /* Get rid of the token and return */ 832 ObDereferenceObject(Token); 833 return Status; 834 } 835 836 /* EOF */ 837