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