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