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