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