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 case THREADSTATE_UNKNOWN13: 318 ret = FALSE; /* FIXME: See imm32 */ 319 break; 320 } 321 322 TRACE("Leave NtUserGetThreadState, ret=%lu\n", ret); 323 UserLeave(); 324 325 return ret; 326 } 327 328 DWORD 329 APIENTRY 330 NtUserSetThreadState( 331 DWORD Set, 332 DWORD Flags) 333 { 334 PTHREADINFO pti; 335 DWORD Ret = 0; 336 // Test the only flags user can change. 337 if (Set & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0; 338 if (Flags & ~(QF_FF10STATUS|QF_DIALOGACTIVE|QF_TABSWITCHING|QF_FMENUSTATUS|QF_FMENUSTATUSBREAK)) return 0; 339 UserEnterExclusive(); 340 pti = PsGetCurrentThreadWin32Thread(); 341 if (pti->MessageQueue) 342 { 343 Ret = pti->MessageQueue->QF_flags; // Get the queue flags. 344 if (Set) 345 pti->MessageQueue->QF_flags |= (Set&Flags); // Set the queue flags. 346 else 347 { 348 if (Flags) pti->MessageQueue->QF_flags &= ~Flags; // Clr the queue flags. 349 } 350 } 351 UserLeave(); 352 return Ret; 353 } 354 355 UINT 356 APIENTRY 357 NtUserGetDoubleClickTime(VOID) 358 { 359 UINT Result; 360 361 TRACE("Enter NtUserGetDoubleClickTime\n"); 362 UserEnterShared(); 363 364 // FIXME: Check if this works on non-interactive winsta 365 Result = gspv.iDblClickTime; 366 367 TRACE("Leave NtUserGetDoubleClickTime, ret=%u\n", Result); 368 UserLeave(); 369 return Result; 370 } 371 372 BOOL 373 APIENTRY 374 NtUserGetGUIThreadInfo( 375 DWORD idThread, /* If NULL use foreground thread */ 376 LPGUITHREADINFO lpgui) 377 { 378 NTSTATUS Status; 379 PTHRDCARETINFO CaretInfo; 380 GUITHREADINFO SafeGui; 381 PDESKTOP Desktop; 382 PUSER_MESSAGE_QUEUE MsgQueue; 383 PTHREADINFO W32Thread, pti; 384 385 DECLARE_RETURN(BOOLEAN); 386 387 TRACE("Enter NtUserGetGUIThreadInfo\n"); 388 UserEnterShared(); 389 390 Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD)); 391 if(!NT_SUCCESS(Status)) 392 { 393 SetLastNtError(Status); 394 RETURN( FALSE); 395 } 396 397 if(SafeGui.cbSize != sizeof(GUITHREADINFO)) 398 { 399 EngSetLastError(ERROR_INVALID_PARAMETER); 400 RETURN( FALSE); 401 } 402 403 if (idThread) 404 { 405 pti = PsGetCurrentThreadWin32Thread(); 406 407 // Validate Tread ID 408 W32Thread = IntTID2PTI((HANDLE)(DWORD_PTR)idThread); 409 410 if ( !W32Thread ) 411 { 412 EngSetLastError(ERROR_ACCESS_DENIED); 413 RETURN( FALSE); 414 } 415 416 Desktop = W32Thread->rpdesk; 417 418 // Check Desktop and it must be the same as current. 419 if ( !Desktop || Desktop != pti->rpdesk ) 420 { 421 EngSetLastError(ERROR_ACCESS_DENIED); 422 RETURN( FALSE); 423 } 424 425 if ( W32Thread->MessageQueue ) 426 MsgQueue = W32Thread->MessageQueue; 427 else 428 { 429 if ( Desktop ) MsgQueue = Desktop->ActiveMessageQueue; 430 } 431 } 432 else 433 { /* Get the foreground thread */ 434 /* FIXME: Handle NULL queue properly? */ 435 MsgQueue = IntGetFocusMessageQueue(); 436 if(!MsgQueue) 437 { 438 EngSetLastError(ERROR_ACCESS_DENIED); 439 RETURN( FALSE); 440 } 441 } 442 443 CaretInfo = &MsgQueue->CaretInfo; 444 445 SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0); 446 /* 447 if (W32Thread->pMenuState->pGlobalPopupMenu) 448 { 449 SafeGui.flags |= GUI_INMENUMODE; 450 451 if (W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify) 452 SafeGui.hwndMenuOwner = UserHMGetHandle(W32Thread->pMenuState->pGlobalPopupMenu->spwndNotify); 453 454 if (W32Thread->pMenuState->pGlobalPopupMenu->fHasMenuBar) 455 { 456 if (W32Thread->pMenuState->pGlobalPopupMenu->fIsSysMenu) 457 { 458 SafeGui.flags |= GUI_SYSTEMMENUMODE; 459 } 460 } 461 else 462 { 463 SafeGui.flags |= GUI_POPUPMENUMODE; 464 } 465 } 466 */ 467 SafeGui.hwndMenuOwner = MsgQueue->MenuOwner; 468 469 if (MsgQueue->MenuOwner) 470 SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState; 471 472 if (MsgQueue->MoveSize) 473 SafeGui.flags |= GUI_INMOVESIZE; 474 475 /* FIXME: Add flag GUI_16BITTASK */ 476 477 SafeGui.hwndActive = MsgQueue->spwndActive ? UserHMGetHandle(MsgQueue->spwndActive) : 0; 478 SafeGui.hwndFocus = MsgQueue->spwndFocus ? UserHMGetHandle(MsgQueue->spwndFocus) : 0; 479 SafeGui.hwndCapture = MsgQueue->spwndCapture ? UserHMGetHandle(MsgQueue->spwndCapture) : 0; 480 SafeGui.hwndMoveSize = MsgQueue->MoveSize; 481 SafeGui.hwndCaret = CaretInfo->hWnd; 482 483 SafeGui.rcCaret.left = CaretInfo->Pos.x; 484 SafeGui.rcCaret.top = CaretInfo->Pos.y; 485 SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx; 486 SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy; 487 488 Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO)); 489 if(!NT_SUCCESS(Status)) 490 { 491 SetLastNtError(Status); 492 RETURN( FALSE); 493 } 494 495 RETURN( TRUE); 496 497 CLEANUP: 498 TRACE("Leave NtUserGetGUIThreadInfo, ret=%u\n",_ret_); 499 UserLeave(); 500 END_CLEANUP; 501 } 502 503 504 DWORD 505 APIENTRY 506 NtUserGetGuiResources( 507 HANDLE hProcess, 508 DWORD uiFlags) 509 { 510 PEPROCESS Process; 511 PPROCESSINFO W32Process; 512 NTSTATUS Status; 513 DWORD Ret = 0; 514 DECLARE_RETURN(DWORD); 515 516 TRACE("Enter NtUserGetGuiResources\n"); 517 UserEnterShared(); 518 519 Status = ObReferenceObjectByHandle(hProcess, 520 PROCESS_QUERY_INFORMATION, 521 *PsProcessType, 522 ExGetPreviousMode(), 523 (PVOID*)&Process, 524 NULL); 525 526 if(!NT_SUCCESS(Status)) 527 { 528 SetLastNtError(Status); 529 RETURN( 0); 530 } 531 532 W32Process = (PPROCESSINFO)Process->Win32Process; 533 if(!W32Process) 534 { 535 ObDereferenceObject(Process); 536 EngSetLastError(ERROR_INVALID_PARAMETER); 537 RETURN( 0); 538 } 539 540 switch(uiFlags) 541 { 542 case GR_GDIOBJECTS: 543 { 544 Ret = (DWORD)W32Process->GDIHandleCount; 545 break; 546 } 547 case GR_USEROBJECTS: 548 { 549 Ret = (DWORD)W32Process->UserHandleCount; 550 break; 551 } 552 default: 553 { 554 EngSetLastError(ERROR_INVALID_PARAMETER); 555 break; 556 } 557 } 558 559 ObDereferenceObject(Process); 560 561 RETURN( Ret); 562 563 CLEANUP: 564 TRACE("Leave NtUserGetGuiResources, ret=%lu\n",_ret_); 565 UserLeave(); 566 END_CLEANUP; 567 } 568 569 VOID FASTCALL 570 IntSetWindowState(PWND pWnd, UINT Flag) 571 { 572 UINT bit; 573 if (gptiCurrent->ppi != pWnd->head.pti->ppi) return; 574 bit = 1 << LOWORD(Flag); 575 TRACE("SWS %x\n",bit); 576 switch(HIWORD(Flag)) 577 { 578 case 0: 579 pWnd->state |= bit; 580 break; 581 case 1: 582 pWnd->state2 |= bit; 583 break; 584 case 2: 585 pWnd->ExStyle2 |= bit; 586 break; 587 } 588 } 589 590 VOID FASTCALL 591 IntClearWindowState(PWND pWnd, UINT Flag) 592 { 593 UINT bit; 594 if (gptiCurrent->ppi != pWnd->head.pti->ppi) return; 595 bit = 1 << LOWORD(Flag); 596 TRACE("CWS %x\n",bit); 597 switch(HIWORD(Flag)) 598 { 599 case 0: 600 pWnd->state &= ~bit; 601 break; 602 case 1: 603 pWnd->state2 &= ~bit; 604 break; 605 case 2: 606 pWnd->ExStyle2 &= ~bit; 607 break; 608 } 609 } 610 611 NTSTATUS FASTCALL 612 IntSafeCopyUnicodeString(PUNICODE_STRING Dest, 613 PUNICODE_STRING Source) 614 { 615 NTSTATUS Status; 616 PWSTR Src; 617 618 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING)); 619 if(!NT_SUCCESS(Status)) 620 { 621 return Status; 622 } 623 624 if(Dest->Length > 0x4000) 625 { 626 return STATUS_UNSUCCESSFUL; 627 } 628 629 Src = Dest->Buffer; 630 Dest->Buffer = NULL; 631 Dest->MaximumLength = Dest->Length; 632 633 if(Dest->Length > 0 && Src) 634 { 635 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING); 636 if(!Dest->Buffer) 637 { 638 return STATUS_NO_MEMORY; 639 } 640 641 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length); 642 if(!NT_SUCCESS(Status)) 643 { 644 ExFreePoolWithTag(Dest->Buffer, TAG_STRING); 645 Dest->Buffer = NULL; 646 return Status; 647 } 648 649 650 return STATUS_SUCCESS; 651 } 652 653 /* String is empty */ 654 return STATUS_SUCCESS; 655 } 656 657 NTSTATUS FASTCALL 658 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest, 659 PUNICODE_STRING Source) 660 { 661 NTSTATUS Status; 662 PWSTR Src; 663 664 Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING)); 665 if(!NT_SUCCESS(Status)) 666 { 667 return Status; 668 } 669 670 if(Dest->Length > 0x4000) 671 { 672 return STATUS_UNSUCCESSFUL; 673 } 674 675 Src = Dest->Buffer; 676 Dest->Buffer = NULL; 677 Dest->MaximumLength = 0; 678 679 if(Dest->Length > 0 && Src) 680 { 681 Dest->MaximumLength = Dest->Length + sizeof(WCHAR); 682 Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING); 683 if(!Dest->Buffer) 684 { 685 return STATUS_NO_MEMORY; 686 } 687 688 Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length); 689 if(!NT_SUCCESS(Status)) 690 { 691 ExFreePoolWithTag(Dest->Buffer, TAG_STRING); 692 Dest->Buffer = NULL; 693 return Status; 694 } 695 696 /* Make sure the string is null-terminated */ 697 Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length); 698 *Src = L'\0'; 699 700 return STATUS_SUCCESS; 701 } 702 703 /* String is empty */ 704 return STATUS_SUCCESS; 705 } 706 707 void UserDbgAssertThreadInfo(BOOL showCaller) 708 { 709 PTEB Teb; 710 PPROCESSINFO ppi; 711 PCLIENTINFO pci; 712 PTHREADINFO pti; 713 714 ppi = PsGetCurrentProcessWin32Process(); 715 pti = PsGetCurrentThreadWin32Thread(); 716 Teb = NtCurrentTeb(); 717 pci = GetWin32ClientInfo(); 718 719 ASSERT(Teb); 720 ASSERT(pti); 721 ASSERT(pti->ppi == ppi); 722 ASSERT(pti->pClientInfo == pci); 723 ASSERT(Teb->Win32ThreadInfo == pti); 724 ASSERT(pci->ppi == ppi); 725 ASSERT(pci->fsHooks == pti->fsHooks); 726 ASSERT(pci->ulClientDelta == DesktopHeapGetUserDelta()); 727 if (pti->pcti && pci->pDeskInfo) 728 ASSERT(pci->pClientThreadInfo == (PVOID)((ULONG_PTR)pti->pcti - pci->ulClientDelta)); 729 //if (pti->pcti && IsListEmpty(&pti->SentMessagesListHead)) 730 // ASSERT((pti->pcti->fsChangeBits & QS_SENDMESSAGE) == 0); 731 if (pti->KeyboardLayout) 732 ASSERT(pci->hKL == pti->KeyboardLayout->hkl); 733 if(pti->rpdesk != NULL) 734 ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo); 735 736 /*too bad we still get this assertion*/ 737 738 // Why? Not all flags are passed to the user and doing so could crash the system........ 739 740 /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */ 741 /* if(pci->dwTIFlags != pti->TIF_flags) 742 { 743 ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags); 744 if(showCaller) 745 { 746 DbgPrint("Caller:\n"); 747 KeRosDumpStackFrames(NULL, 10); 748 } 749 pci->dwTIFlags = pti->TIF_flags; 750 } 751 */ 752 } 753 754 void 755 NTAPI 756 UserDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments) 757 { 758 UserDbgAssertThreadInfo(FALSE); 759 } 760 761 ULONG_PTR 762 NTAPI 763 UserDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult) 764 { 765 /* Make sure that the first syscall is NtUserInitialize */ 766 /* too bad this fails */ 767 // ASSERT(gpepCSRSS); 768 769 UserDbgAssertThreadInfo(TRUE); 770 771 return ulResult; 772 } 773 774 775 PPROCESSINFO 776 GetW32ProcessInfo(VOID) 777 { 778 return (PPROCESSINFO)PsGetCurrentProcessWin32Process(); 779 } 780 781 PTHREADINFO 782 GetW32ThreadInfo(VOID) 783 { 784 UserDbgAssertThreadInfo(TRUE); 785 return (PTHREADINFO)PsGetCurrentThreadWin32Thread(); 786 } 787 788 789 NTSTATUS 790 GetProcessLuid( 791 IN PETHREAD Thread OPTIONAL, 792 IN PEPROCESS Process OPTIONAL, 793 OUT PLUID Luid) 794 { 795 NTSTATUS Status; 796 PACCESS_TOKEN Token = NULL; 797 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; 798 BOOLEAN CopyOnOpen, EffectiveOnly; 799 800 if (Thread && Process) 801 return STATUS_INVALID_PARAMETER; 802 803 /* If nothing has been specified, use the current thread */ 804 if (!Thread && !Process) 805 Thread = PsGetCurrentThread(); 806 807 if (Thread) 808 { 809 /* Use a thread token */ 810 ASSERT(!Process); 811 Token = PsReferenceImpersonationToken(Thread, 812 &CopyOnOpen, 813 &EffectiveOnly, 814 &ImpersonationLevel); 815 816 /* If we don't have a thread token, use a process token */ 817 if (!Token) 818 Process = PsGetThreadProcess(Thread); 819 } 820 if (!Token && Process) 821 { 822 /* Use a process token */ 823 Token = PsReferencePrimaryToken(Process); 824 825 /* If we don't have a token, fail */ 826 if (!Token) 827 return STATUS_NO_TOKEN; 828 } 829 ASSERT(Token); 830 831 /* Query the LUID */ 832 Status = SeQueryAuthenticationIdToken(Token, Luid); 833 834 /* Get rid of the token and return */ 835 ObDereferenceObject(Token); 836 return Status; 837 } 838 839 /* EOF */ 840