xref: /reactos/win32ss/user/ntuser/simplecall.c (revision f59c58d8)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * PURPOSE:          NtUserCallXxx call stubs
5  * FILE:             win32ss/user/ntuser/simplecall.c
6  * PROGRAMERS:       Ge van Geldorp (ge@gse.nl)
7  *                   Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
8  */
9 
10 #include <win32k.h>
11 
12 DBG_DEFAULT_CHANNEL(UserMisc);
13 
14 /* Registered logon process ID */
15 HANDLE gpidLogon = 0;
16 
17 BOOL FASTCALL
18 co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
19 {
20     NTSTATUS Status;
21     PEPROCESS Process;
22 
23     Status = PsLookupProcessByProcessId(ProcessId, &Process);
24     if (!NT_SUCCESS(Status))
25     {
26         EngSetLastError(RtlNtStatusToDosError(Status));
27         return FALSE;
28     }
29 
30     ProcessId = Process->UniqueProcessId;
31 
32     ObDereferenceObject(Process);
33 
34     if (Register)
35     {
36         /* Register the logon process */
37         if (gpidLogon != 0)
38             return FALSE;
39 
40         gpidLogon = ProcessId;
41     }
42     else
43     {
44         /* Deregister the logon process */
45         if (gpidLogon != ProcessId)
46             return FALSE;
47 
48         gpidLogon = 0;
49     }
50 
51     return TRUE;
52 }
53 
54 /*
55  * @unimplemented
56  */
57 DWORD_PTR
58 APIENTRY
59 NtUserCallNoParam(DWORD Routine)
60 {
61     DWORD_PTR Result = 0;
62 
63     TRACE("Enter NtUserCallNoParam\n");
64     UserEnterExclusive();
65 
66     switch (Routine)
67     {
68         case NOPARAM_ROUTINE_CREATEMENU:
69             Result = (DWORD_PTR)UserCreateMenu(GetW32ThreadInfo()->rpdesk, FALSE);
70             break;
71 
72         case NOPARAM_ROUTINE_CREATEMENUPOPUP:
73             Result = (DWORD_PTR)UserCreateMenu(GetW32ThreadInfo()->rpdesk, TRUE);
74             break;
75 
76         case NOPARAM_ROUTINE_DESTROY_CARET:
77             Result = (DWORD_PTR)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
78             break;
79 
80         case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
81             Result = (DWORD_PTR)IntInitMessagePumpHook();
82             break;
83 
84         case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
85             Result = (DWORD_PTR)IntUninitMessagePumpHook();
86             break;
87 
88         case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
89             Result = (DWORD_PTR)IntMsqClearWakeMask();
90             break;
91 
92         case NOPARAM_ROUTINE_GETMSESSAGEPOS:
93         {
94             PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
95             Result = (DWORD_PTR)MAKELONG(pti->ptLast.x, pti->ptLast.y);
96             break;
97         }
98 
99         case NOPARAM_ROUTINE_RELEASECAPTURE:
100             Result = (DWORD_PTR)IntReleaseCapture();
101             break;
102 
103         case NOPARAM_ROUTINE_LOADUSERAPIHOOK:
104             Result = UserLoadApiHook();
105             break;
106 
107         case NOPARAM_ROUTINE_ZAPACTIVEANDFOUS:
108         {
109             PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
110             TRACE("Zapping the Active and Focus window out of the Queue!\n");
111             pti->MessageQueue->spwndFocus = NULL;
112             pti->MessageQueue->spwndActive = NULL;
113             Result = 0;
114             break;
115         }
116 
117         /* this is a ReactOS only case and is needed for gui-on-demand */
118         case NOPARAM_ROUTINE_ISCONSOLEMODE:
119             Result = (ScreenDeviceContext == NULL);
120             break;
121 
122         case NOPARAM_ROUTINE_UPDATEPERUSERIMMENABLING:
123             gpsi->dwSRVIFlags |= SRVINFO_IMM32; // Always set.
124             Result = TRUE; // Always return TRUE.
125             break;
126 
127         default:
128             ERR("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
129             EngSetLastError(ERROR_INVALID_PARAMETER);
130             break;
131     }
132 
133     TRACE("Leave NtUserCallNoParam, ret=%p\n",(PVOID)Result);
134     UserLeave();
135 
136     return Result;
137 }
138 
139 
140 /*
141  * @implemented
142  */
143 DWORD_PTR
144 APIENTRY
145 NtUserCallOneParam(
146     DWORD_PTR Param,
147     DWORD Routine)
148 {
149     DWORD_PTR Result;
150 
151     TRACE("Enter NtUserCallOneParam\n");
152 
153     UserEnterExclusive();
154 
155     switch (Routine)
156     {
157         case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
158         {
159             PTHREADINFO pti;
160             pti = PsGetCurrentThreadWin32Thread();
161             MsqPostQuitMessage(pti, Param);
162             Result = TRUE;
163             break;
164         }
165 
166         case ONEPARAM_ROUTINE_BEGINDEFERWNDPOS:
167         {
168             PSMWP psmwp;
169             HDWP hDwp = NULL;
170             INT count = (INT)Param;
171 
172             if (count < 0)
173             {
174                 EngSetLastError(ERROR_INVALID_PARAMETER);
175                 Result = 0;
176                 break;
177             }
178 
179             /* Windows allows zero count, in which case it allocates context for 8 moves */
180             if (count == 0) count = 8;
181 
182             psmwp = (PSMWP)UserCreateObject(gHandleTable,
183                                             NULL,
184                                             NULL,
185                                             (PHANDLE)&hDwp,
186                                             TYPE_SETWINDOWPOS,
187                                             sizeof(SMWP));
188             if (!psmwp)
189             {
190                 Result = 0;
191                 break;
192             }
193 
194             psmwp->acvr = ExAllocatePoolWithTag(PagedPool, count * sizeof(CVR), USERTAG_SWP);
195             if (!psmwp->acvr)
196             {
197                 UserDeleteObject(hDwp, TYPE_SETWINDOWPOS);
198                 Result = 0;
199                 break;
200             }
201 
202             RtlZeroMemory(psmwp->acvr, count * sizeof(CVR));
203             psmwp->bHandle = TRUE;
204             psmwp->ccvr = 0;          // actualCount
205             psmwp->ccvrAlloc = count; // suggestedCount
206             Result = (DWORD_PTR)hDwp;
207             break;
208         }
209 
210         case ONEPARAM_ROUTINE_SHOWCURSOR:
211             Result = (DWORD_PTR)UserShowCursor((BOOL)Param);
212             break;
213 
214         case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
215         {
216             PTHREADINFO ti;
217             ti = GetW32ThreadInfo();
218             if (ti != NULL)
219             {
220                 /* Try convert the pointer to a user mode pointer if the desktop is
221                    mapped into the process */
222                 Result = (DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param);
223             }
224             else
225             {
226                 Result = 0;
227             }
228             break;
229         }
230 
231         case ONEPARAM_ROUTINE_WINDOWFROMDC:
232             Result = (DWORD_PTR)IntWindowFromDC((HDC)Param);
233             break;
234 
235         case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
236         {
237             Result = gspv.bMouseBtnSwap;
238             gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
239             gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
240             break;
241         }
242 
243         case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
244             Result = (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param);
245             break;
246 
247         case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
248             Result = (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param);
249             break;
250 
251         case ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT:
252         {
253             if (!(Result = (DWORD_PTR)IntCreateCurIconHandle((DWORD)Param)))
254             {
255                 EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
256                 Result = 0;
257             }
258             break;
259         }
260 
261         case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
262         {
263             BOOL Enable;
264             PPROCESSINFO Process = PsGetCurrentProcessWin32Process();
265 
266             if (Process != NULL)
267             {
268                 Enable = (BOOL)(Param != 0);
269 
270                 if (Enable)
271                 {
272                     Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
273                 }
274                 else
275                 {
276                     Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
277                 }
278 
279                 Result = TRUE;
280                 break;
281             }
282 
283             Result = FALSE;
284             break;
285         }
286 
287         case ONEPARAM_ROUTINE_GETINPUTEVENT:
288             Result = (DWORD_PTR)IntMsqSetWakeMask(Param);
289             break;
290 
291         case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
292             Result = UserGetKeyboardType(Param);
293             break;
294 
295         case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
296             Result = (DWORD_PTR)UserGetKeyboardLayout(Param);
297             break;
298 
299         case ONEPARAM_ROUTINE_RELEASEDC:
300             Result = UserReleaseDC(NULL, (HDC) Param, FALSE);
301             break;
302 
303         case ONEPARAM_ROUTINE_REALIZEPALETTE:
304             Result = UserRealizePalette((HDC) Param);
305             break;
306 
307         case ONEPARAM_ROUTINE_GETQUEUESTATUS:
308         {
309             Result = IntGetQueueStatus((DWORD)Param);
310             break;
311         }
312 
313         case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
314             /* FIXME: Should use UserEnterShared */
315             Result = UserEnumClipboardFormats(Param);
316             break;
317 
318         case ONEPARAM_ROUTINE_GETCURSORPOS:
319         {
320             PPOINTL pptl;
321             PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
322             Result = TRUE;
323             if (pti->rpdesk != IntGetActiveDesktop())
324             {
325                 Result = FALSE;
326                 break;
327             }
328             _SEH2_TRY
329             {
330                 ProbeForWrite((POINT*)Param,sizeof(POINT),1);
331                pptl = (PPOINTL)Param;
332                *pptl = gpsi->ptCursor;
333             }
334             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
335             {
336                 Result = FALSE;
337             }
338             _SEH2_END;
339             break;
340         }
341 
342         case ONEPARAM_ROUTINE_SETPROCDEFLAYOUT:
343         {
344             PPROCESSINFO ppi;
345             if (Param & LAYOUT_ORIENTATIONMASK || Param == LAYOUT_LTR)
346             {
347                 ppi = PsGetCurrentProcessWin32Process();
348                 ppi->dwLayout = Param;
349                 Result = TRUE;
350                 break;
351             }
352             EngSetLastError(ERROR_INVALID_PARAMETER);
353             Result = FALSE;
354             break;
355         }
356 
357         case ONEPARAM_ROUTINE_GETPROCDEFLAYOUT:
358         {
359             PPROCESSINFO ppi;
360             PDWORD pdwLayout;
361             Result = TRUE;
362 
363             if (PsGetCurrentProcess() == gpepCSRSS)
364             {
365                 EngSetLastError(ERROR_INVALID_ACCESS);
366                 Result = FALSE;
367                 break;
368             }
369 
370             ppi = PsGetCurrentProcessWin32Process();
371             _SEH2_TRY
372             {
373                pdwLayout = (PDWORD)Param;
374                *pdwLayout = ppi->dwLayout;
375             }
376             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
377             {
378                 SetLastNtError(_SEH2_GetExceptionCode());
379                 Result = FALSE;
380             }
381             _SEH2_END;
382             break;
383         }
384 
385         case ONEPARAM_ROUTINE_REPLYMESSAGE:
386             Result = co_MsqReplyMessage((LRESULT)Param);
387             break;
388 
389         case ONEPARAM_ROUTINE_MESSAGEBEEP:
390             /* TODO: Implement sound sentry */
391             Result = UserPostMessage(hwndSAS, WM_LOGONNOTIFY, LN_MESSAGE_BEEP, Param);
392            break;
393 
394         case ONEPARAM_ROUTINE_CREATESYSTEMTHREADS:
395             Result = UserSystemThreadProc(Param);
396             break;
397 
398         case ONEPARAM_ROUTINE_LOCKFOREGNDWINDOW:
399             Result = (DWORD_PTR)IntLockSetForegroundWindow(Param);
400             break;
401 
402         case ONEPARAM_ROUTINE_ALLOWSETFOREGND:
403             Result = (DWORD_PTR)IntAllowSetForegroundWindow(Param);
404             break;
405 
406         default:
407             ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
408                 Routine, Param);
409             EngSetLastError(ERROR_INVALID_PARAMETER);
410             Result = 0;
411             break;
412     }
413 
414    TRACE("Leave NtUserCallOneParam, ret=%p\n", (PVOID)Result);
415    UserLeave();
416 
417    return Result;
418 }
419 
420 
421 /*
422  * @implemented
423  */
424 DWORD_PTR
425 APIENTRY
426 NtUserCallTwoParam(
427     DWORD_PTR Param1,
428     DWORD_PTR Param2,
429     DWORD Routine)
430 {
431     PWND Window;
432     DWORD_PTR Ret;
433     TRACE("Enter NtUserCallTwoParam\n");
434     UserEnterExclusive();
435 
436     switch (Routine)
437     {
438         case TWOPARAM_ROUTINE_REDRAWTITLE:
439         {
440             Window = UserGetWindowObject((HWND)Param1);
441             Ret = (DWORD_PTR)UserPaintCaption(Window, (INT)Param2);
442             break;
443         }
444 
445         case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
446         {
447             PMENU MenuObject = IntGetMenuObject((HMENU)Param1);
448             if (!MenuObject)
449             {
450                 Ret = 0;
451                 break;
452             }
453 
454             if (Param2 > 0)
455             {
456                 Ret = (MenuObject->cyMenu == (int)Param2);
457                 MenuObject->cyMenu = (int)Param2;
458             }
459             else
460                 Ret = (DWORD_PTR)MenuObject->cyMenu;
461             IntReleaseMenuObject(MenuObject);
462             break;
463         }
464 
465         case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
466         {
467             PTHREADINFO pti = (PTHREADINFO)PsGetCurrentThreadWin32Thread();
468             ASSERT(pti->MessageQueue);
469             Ret = (DWORD_PTR)MsqSetStateWindow(pti, (ULONG)Param1, (HWND)Param2);
470             break;
471         }
472 
473         case TWOPARAM_ROUTINE_ENABLEWINDOW:
474             Ret = IntEnableWindow((HWND)Param1, (BOOL)Param2);
475             break;
476 
477         case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
478         {
479             Window = UserGetWindowObject((HWND)Param1);
480             if (!Window)
481             {
482                 Ret = 0;
483                 break;
484             }
485 
486             Ret = (DWORD_PTR)IntShowOwnedPopups(Window, (BOOL)Param2);
487             break;
488         }
489 
490         case TWOPARAM_ROUTINE_ROS_UPDATEUISTATE:
491         {
492             WPARAM wParam;
493             Window = UserGetWindowObject((HWND)Param1);
494             if (!Window)
495             {
496                 Ret = 0;
497                 break;
498             }
499 
500             /* Unpack wParam */
501             wParam = MAKEWPARAM((Param2 >> 3) & 0x3,
502                                 Param2 & (UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE));
503 
504             Ret = UserUpdateUiState(Window, wParam);
505             break;
506         }
507 
508         case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
509         {
510             HWND hwnd = (HWND)Param1;
511             BOOL fAltTab = (BOOL)Param2;
512             Ret = 0;
513             Window = UserGetWindowObject(hwnd);
514             if (!Window)
515                 break;
516 
517             if (gpqForeground && !fAltTab)
518             {
519                 PWND pwndActive = gpqForeground->spwndActive;
520                 if (pwndActive && !(pwndActive->ExStyle & WS_EX_TOPMOST))
521                 {
522                     co_WinPosSetWindowPos(pwndActive, HWND_BOTTOM, 0, 0, 0, 0,
523                                           SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE |
524                                           SWP_ASYNCWINDOWPOS);
525                 }
526 
527                 UserSetActiveWindow(Window);
528                 break;
529             }
530 
531             co_IntSetForegroundWindowMouse(Window);
532 
533             if (fAltTab && (Window->style & WS_MINIMIZE))
534             {
535                 MSG msg = { Window->head.h, WM_SYSCOMMAND, SC_RESTORE, 0 };
536                 MsqPostMessage(Window->head.pti, &msg, FALSE, QS_POSTMESSAGE, 0, 0);
537             }
538             break;
539         }
540 
541         case TWOPARAM_ROUTINE_SETCARETPOS:
542             Ret = (DWORD_PTR)co_IntSetCaretPos((int)Param1, (int)Param2);
543             break;
544 
545         case TWOPARAM_ROUTINE_REGISTERLOGONPROCESS:
546             Ret = (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2);
547             break;
548 
549         case TWOPARAM_ROUTINE_SETCURSORPOS:
550             Ret = (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2, 0, 0, FALSE);
551             break;
552 
553         case TWOPARAM_ROUTINE_UNHOOKWINDOWSHOOK:
554             Ret = IntUnhookWindowsHook((int)Param1, (HOOKPROC)Param2);
555             break;
556 
557         default:
558             ERR("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
559                 Routine, Param1, Param2);
560             EngSetLastError(ERROR_INVALID_PARAMETER);
561             Ret = 0;
562     }
563 
564 
565     TRACE("Leave NtUserCallTwoParam, ret=%p\n", (PVOID)Ret);
566     UserLeave();
567 
568     return Ret;
569 }
570 
571 
572 /*
573  * @unimplemented
574  */
575 BOOL
576 APIENTRY
577 NtUserCallHwndLock(
578     HWND hWnd,
579     DWORD Routine)
580 {
581     BOOL Ret = FALSE;
582     PWND Window;
583     USER_REFERENCE_ENTRY Ref;
584 
585     TRACE("Enter NtUserCallHwndLock\n");
586     UserEnterExclusive();
587 
588     if (!(Window = UserGetWindowObject(hWnd)))
589     {
590         Ret = FALSE;
591         goto Exit;
592     }
593 
594     UserRefObjectCo(Window, &Ref);
595 
596     /* FIXME: Routine can be 0x53 - 0x5E */
597     switch (Routine)
598     {
599         case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
600             co_WinPosArrangeIconicWindows(Window);
601             break;
602 
603         case HWNDLOCK_ROUTINE_DRAWMENUBAR:
604         {
605             TRACE("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
606             Ret = TRUE;
607             if ((Window->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
608                 co_WinPosSetWindowPos(Window,
609                                       HWND_DESKTOP,
610                                       0, 0, 0, 0,
611                                       SWP_NOSIZE |
612                                       SWP_NOMOVE |
613                                       SWP_NOZORDER |
614                                       SWP_NOACTIVATE |
615                                       SWP_FRAMECHANGED);
616             break;
617         }
618 
619         case HWNDLOCK_ROUTINE_REDRAWFRAME:
620             co_WinPosSetWindowPos(Window,
621                                   HWND_DESKTOP,
622                                   0, 0, 0, 0,
623                                   SWP_NOSIZE |
624                                   SWP_NOMOVE |
625                                   SWP_NOZORDER |
626                                   SWP_NOACTIVATE |
627                                   SWP_FRAMECHANGED);
628             Ret = TRUE;
629             break;
630 
631         case HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK:
632             co_WinPosSetWindowPos(Window,
633                                   HWND_DESKTOP,
634                                   0, 0, 0, 0,
635                                   SWP_NOSIZE |
636                                   SWP_NOMOVE |
637                                   SWP_NOZORDER |
638                                   SWP_NOACTIVATE |
639                                   SWP_FRAMECHANGED);
640             if (!Window->spwndOwner && !IntGetParent(Window))
641             {
642                 co_IntShellHookNotify(HSHELL_REDRAW, (WPARAM)hWnd, FALSE); // FIXME Flashing?
643             }
644             Ret = TRUE;
645             break;
646 
647         case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
648             TRACE("co_IntSetForegroundWindow 1 0x%p\n", hWnd);
649             Ret = co_IntSetForegroundWindow(Window);
650             TRACE("co_IntSetForegroundWindow 2 0x%p\n", hWnd);
651             break;
652 
653         case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE:
654             TRACE("co_IntSetForegroundWindow M 1 0x%p\n", hWnd);
655             Ret = co_IntSetForegroundWindowMouse(Window);
656             TRACE("co_IntSetForegroundWindow M 2 0x%p\n", hWnd);
657             break;
658 
659         case HWNDLOCK_ROUTINE_UPDATEWINDOW:
660             co_IntUpdateWindows(Window, RDW_ALLCHILDREN, FALSE);
661             Ret = TRUE;
662             break;
663 
664         case HWNDLOCK_ROUTINE_CHECKIMESHOWSTATUSINTHRD:
665             // TODO:
666             break;
667     }
668 
669     UserDerefObjectCo(Window);
670 
671 Exit:
672     TRACE("Leave NtUserCallHwndLock, ret=%u\n", Ret);
673     UserLeave();
674 
675     return Ret;
676 }
677 
678 /*
679  * @unimplemented
680  */
681 HWND
682 APIENTRY
683 NtUserCallHwndOpt(
684     HWND hWnd,
685     DWORD Routine)
686 {
687     switch (Routine)
688     {
689         case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
690             GetW32ThreadInfo()->pDeskInfo->hProgmanWindow = hWnd;
691             break;
692 
693         case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
694             GetW32ThreadInfo()->pDeskInfo->hTaskManWindow = hWnd;
695             break;
696     }
697 
698     return hWnd;
699 }
700 
701 DWORD
702 APIENTRY
703 NtUserCallHwnd(
704     HWND hWnd,
705     DWORD Routine)
706 {
707     switch (Routine)
708     {
709         case HWND_ROUTINE_GETWNDCONTEXTHLPID:
710         {
711             PWND Window;
712             DWORD HelpId;
713 
714             UserEnterShared();
715 
716             if (!(Window = UserGetWindowObject(hWnd)))
717             {
718                 UserLeave();
719                 return 0;
720             }
721 
722             HelpId = (DWORD)(DWORD_PTR)UserGetProp(Window, gpsi->atomContextHelpIdProp, TRUE);
723 
724             UserLeave();
725             return HelpId;
726         }
727 
728         case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW:
729             if (IntIsWindow(hWnd))
730                 return IntRegisterShellHookWindow(hWnd);
731             return FALSE;
732             break;
733 
734         case HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW:
735             if (IntIsWindow(hWnd))
736                 return IntDeRegisterShellHookWindow(hWnd);
737             return FALSE;
738 
739         case HWND_ROUTINE_SETMSGBOX:
740         {
741             PWND Window;
742             UserEnterExclusive();
743             if ((Window = UserGetWindowObject(hWnd)))
744             {
745                 Window->state |= WNDS_MSGBOX;
746             }
747             UserLeave();
748             return FALSE;
749         }
750     }
751 
752     STUB;
753 
754     return 0;
755 }
756 
757 DWORD
758 APIENTRY
759 NtUserCallHwndParam(
760     HWND hWnd,
761     DWORD_PTR Param,
762     DWORD Routine)
763 {
764 
765     switch (Routine)
766     {
767         case HWNDPARAM_ROUTINE_KILLSYSTEMTIMER:
768         {
769             DWORD ret;
770 
771             UserEnterExclusive();
772             ret = IntKillTimer(UserGetWindowObject(hWnd), (UINT_PTR)Param, TRUE);
773             UserLeave();
774             return ret;
775         }
776 
777         case HWNDPARAM_ROUTINE_SETWNDCONTEXTHLPID:
778         {
779             PWND Window;
780 
781             UserEnterExclusive();
782             if (!(Window = UserGetWindowObject(hWnd)))
783             {
784                 UserLeave();
785                 return FALSE;
786             }
787 
788             if (Param)
789                 UserSetProp(Window, gpsi->atomContextHelpIdProp, (HANDLE)Param, TRUE);
790             else
791                 UserRemoveProp(Window, gpsi->atomContextHelpIdProp, TRUE);
792 
793             UserLeave();
794             return TRUE;
795         }
796 
797         case HWNDPARAM_ROUTINE_SETDIALOGPOINTER:
798         {
799             PWND pWnd;
800             USER_REFERENCE_ENTRY Ref;
801 
802             UserEnterExclusive();
803 
804             if (!(pWnd = UserGetWindowObject(hWnd)))
805             {
806                 UserLeave();
807                 return 0;
808             }
809             UserRefObjectCo(pWnd, &Ref);
810 
811             if (pWnd->head.pti->ppi == PsGetCurrentProcessWin32Process() &&
812                 pWnd->cbwndExtra >= DLGWINDOWEXTRA &&
813                 !(pWnd->state & WNDS_SERVERSIDEWINDOWPROC))
814             {
815                 pWnd->DialogPointer = (PVOID)Param;
816                 if (Param)
817                 {
818                     if (!pWnd->fnid) pWnd->fnid = FNID_DIALOG;
819                     pWnd->state |= WNDS_DIALOGWINDOW;
820                 }
821                 else
822                 {
823                     pWnd->fnid |= FNID_DESTROY;
824                     pWnd->state &= ~WNDS_DIALOGWINDOW;
825                 }
826             }
827 
828             UserDerefObjectCo(pWnd);
829             UserLeave();
830             return 0;
831         }
832 
833         case HWNDPARAM_ROUTINE_ROS_NOTIFYWINEVENT:
834         {
835             PWND pWnd;
836             PNOTIFYEVENT pne;
837             UserEnterExclusive();
838             pne = (PNOTIFYEVENT)Param;
839             if (hWnd)
840                 pWnd = UserGetWindowObject(hWnd);
841             else
842                 pWnd = NULL;
843             IntNotifyWinEvent(pne->event, pWnd, pne->idObject, pne->idChild, pne->flags);
844             UserLeave();
845             return 0;
846         }
847 
848         case HWNDPARAM_ROUTINE_CLEARWINDOWSTATE:
849         {
850             PWND pWnd;
851             UserEnterExclusive();
852             pWnd = UserGetWindowObject(hWnd);
853             if (pWnd) IntClearWindowState(pWnd, (UINT)Param);
854             UserLeave();
855             return 0;
856         }
857 
858         case HWNDPARAM_ROUTINE_SETWINDOWSTATE:
859         {
860             PWND pWnd;
861             UserEnterExclusive();
862             pWnd = UserGetWindowObject(hWnd);
863             if (pWnd) IntSetWindowState(pWnd, (UINT)Param);
864             UserLeave();
865             return 0;
866         }
867     }
868 
869     STUB;
870 
871     return 0;
872 }
873 
874 DWORD
875 APIENTRY
876 NtUserCallHwndParamLock(
877     HWND hWnd,
878     DWORD_PTR Param,
879     DWORD Routine)
880 {
881     DWORD Ret = FALSE;
882     PWND Window;
883     USER_REFERENCE_ENTRY Ref;
884 
885     TRACE("Enter NtUserCallHwndParamLock\n");
886     UserEnterExclusive();
887 
888     if (!(Window = UserGetWindowObject(hWnd)))
889     {
890         Ret = FALSE;
891         goto Exit;
892     }
893 
894     UserRefObjectCo(Window, &Ref);
895 
896     switch (Routine)
897     {
898         case X_ROUTINE_IMESHOWSTATUSCHANGE:
899         {
900             // TODO:
901             break;
902         }
903         case TWOPARAM_ROUTINE_VALIDATERGN:
904         {
905             PREGION Rgn = REGION_LockRgn((HRGN)Param);
906             Ret = (DWORD)co_UserRedrawWindow(Window, NULL, Rgn, RDW_VALIDATE);
907             if (Rgn) REGION_UnlockRgn(Rgn);
908             break;
909         }
910     }
911 
912     UserDerefObjectCo(Window);
913 
914 Exit:
915 
916     TRACE("Leave NtUserCallHwndParamLock, ret=%lu\n", Ret);
917     UserLeave();
918 
919     return Ret;
920 }
921 
922 /* EOF */
923