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