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