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