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