Merge from amd64-branch:
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / simplecall.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: NtUserCallXxx call stubs
5 * FILE: subsystem/win32/win32k/ntuser/simplecall.c
6 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
7 * REVISION HISTORY:
8 * 2008/03/20 Split from misc.c
9 */
10
11 #include <w32k.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16
17 /* registered Logon process */
18 PPROCESSINFO LogonProcess = NULL;
19
20 BOOL FASTCALL
21 co_IntRegisterLogonProcess(HANDLE ProcessId, BOOL Register)
22 {
23 PEPROCESS Process;
24 NTSTATUS Status;
25 CSR_API_MESSAGE Request;
26
27 Status = PsLookupProcessByProcessId(ProcessId,
28 &Process);
29 if (!NT_SUCCESS(Status))
30 {
31 SetLastWin32Error(RtlNtStatusToDosError(Status));
32 return FALSE;
33 }
34
35 if (Register)
36 {
37 /* Register the logon process */
38 if (LogonProcess != NULL)
39 {
40 ObDereferenceObject(Process);
41 return FALSE;
42 }
43
44 LogonProcess = (PPROCESSINFO)Process->Win32Process;
45 }
46 else
47 {
48 /* Deregister the logon process */
49 if (LogonProcess != (PPROCESSINFO)Process->Win32Process)
50 {
51 ObDereferenceObject(Process);
52 return FALSE;
53 }
54
55 LogonProcess = NULL;
56 }
57
58 ObDereferenceObject(Process);
59
60 Request.Type = MAKE_CSR_API(REGISTER_LOGON_PROCESS, CSR_GUI);
61 Request.Data.RegisterLogonProcessRequest.ProcessId = ProcessId;
62 Request.Data.RegisterLogonProcessRequest.Register = Register;
63
64 Status = co_CsrNotify(&Request);
65 if (! NT_SUCCESS(Status))
66 {
67 DPRINT1("Failed to register logon process with CSRSS\n");
68 return FALSE;
69 }
70
71 return TRUE;
72 }
73
74 /*
75 * @unimplemented
76 */
77 DWORD_PTR
78 APIENTRY
79 NtUserCallNoParam(DWORD Routine)
80 {
81 DWORD_PTR Result = 0;
82 DECLARE_RETURN(DWORD_PTR);
83
84 DPRINT("Enter NtUserCallNoParam\n");
85 UserEnterExclusive();
86
87 switch(Routine)
88 {
89 case NOPARAM_ROUTINE_CREATEMENU:
90 Result = (DWORD_PTR)UserCreateMenu(FALSE);
91 break;
92
93 case NOPARAM_ROUTINE_CREATEMENUPOPUP:
94 Result = (DWORD_PTR)UserCreateMenu(TRUE);
95 break;
96
97 case NOPARAM_ROUTINE_DESTROY_CARET:
98 Result = (DWORD_PTR)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
99 break;
100
101 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
102 Result = (DWORD_PTR)IntInitMessagePumpHook();
103 break;
104
105 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
106 Result = (DWORD_PTR)IntUninitMessagePumpHook();
107 break;
108
109 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO:
110 Result = (DWORD_PTR)MsqGetMessageExtraInfo();
111 break;
112
113 case NOPARAM_ROUTINE_ANYPOPUP:
114 Result = (DWORD_PTR)IntAnyPopup();
115 break;
116
117 case NOPARAM_ROUTINE_CSRSS_INITIALIZED:
118 Result = (DWORD_PTR)CsrInit();
119 break;
120
121 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
122 RETURN( (DWORD_PTR)IntMsqClearWakeMask());
123
124 default:
125 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine);
126 SetLastWin32Error(ERROR_INVALID_PARAMETER);
127 break;
128 }
129 RETURN(Result);
130
131 CLEANUP:
132 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_);
133 UserLeave();
134 END_CLEANUP;
135 }
136
137
138 /*
139 * @implemented
140 */
141 DWORD_PTR
142 APIENTRY
143 NtUserCallOneParam(
144 DWORD_PTR Param,
145 DWORD Routine)
146 {
147 DECLARE_RETURN(DWORD_PTR);
148
149 DPRINT("Enter NtUserCallOneParam\n");
150
151 UserEnterExclusive();
152
153 switch(Routine)
154 {
155 case ONEPARAM_ROUTINE_POSTQUITMESSAGE:
156 {
157 PTHREADINFO pti;
158 pti = PsGetCurrentThreadWin32Thread();
159 MsqPostQuitMessage(pti->MessageQueue, Param);
160 RETURN(TRUE);
161 }
162 case ONEPARAM_ROUTINE_SHOWCURSOR:
163 RETURN( (DWORD_PTR)UserShowCursor((BOOL)Param) );
164
165 case ONEPARAM_ROUTINE_GETDESKTOPMAPPING:
166 {
167 PTHREADINFO ti;
168 ti = GetW32ThreadInfo();
169 if (ti != NULL)
170 {
171 /* Try convert the pointer to a user mode pointer if the desktop is
172 mapped into the process */
173 RETURN((DWORD_PTR)DesktopHeapAddressToUser((PVOID)Param));
174 }
175 else
176 {
177 RETURN(0);
178 }
179 }
180
181 case ONEPARAM_ROUTINE_WINDOWFROMDC:
182 RETURN( (DWORD_PTR)IntWindowFromDC((HDC)Param));
183
184 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
185 {
186 DWORD_PTR Result;
187
188 Result = gspv.bMouseBtnSwap;
189 gspv.bMouseBtnSwap = Param ? TRUE : FALSE;
190 gpsi->aiSysMet[SM_SWAPBUTTON] = gspv.bMouseBtnSwap;
191 RETURN(Result);
192 }
193
194 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING:
195 RETURN( (DWORD_PTR)IntSwitchCaretShowing((PVOID)Param));
196
197 case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
198 RETURN( (DWORD_PTR)IntSetCaretBlinkTime((UINT)Param));
199
200 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
201 RETURN( (DWORD_PTR)MsqSetMessageExtraInfo((LPARAM)Param));
202
203 case ONEPARAM_ROUTINE_CREATECURICONHANDLE:
204 {
205 PCURICON_OBJECT CurIcon;
206
207 if (!(CurIcon = IntCreateCurIconHandle()))
208 {
209 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
210 RETURN(0);
211 }
212
213 RETURN((DWORD_PTR)CurIcon->Self);
214 }
215
216 case ONEPARAM_ROUTINE_GETCURSORPOSITION:
217 {
218 BOOL ret = TRUE;
219
220
221 _SEH2_TRY
222 {
223 ProbeForWrite((POINT*)Param,sizeof(POINT),1);
224 RtlCopyMemory((POINT*)Param,&gpsi->ptCursor,sizeof(POINT));
225 }
226 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
227 {
228 SetLastNtError(_SEH2_GetExceptionCode());
229 ret = FALSE;
230 }
231 _SEH2_END;
232
233 RETURN (ret);
234 }
235
236 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
237 {
238 PWINDOW_OBJECT Window;
239 DWORD_PTR Result;
240
241 if(!(Window = UserGetWindowObject((HWND)Param)))
242 {
243 RETURN( FALSE);
244 }
245
246 Result = (DWORD_PTR)IntIsWindowInDestroy(Window);
247
248 RETURN( Result);
249 }
250
251 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
252 {
253 BOOL Enable;
254 PPROCESSINFO Process = PsGetCurrentProcessWin32Process();
255
256 if(Process != NULL)
257 {
258 Enable = (BOOL)(Param != 0);
259
260 if(Enable)
261 {
262 Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
263 }
264 else
265 {
266 Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
267 }
268
269 RETURN( TRUE);
270 }
271
272 RETURN( FALSE);
273 }
274
275 case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
276 RETURN( (DWORD_PTR)IntMsqSetWakeMask(Param));
277
278 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
279 RETURN( UserGetKeyboardType(Param));
280
281 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
282 RETURN( (DWORD_PTR)UserGetKeyboardLayout(Param));
283
284 case ONEPARAM_ROUTINE_RELEASEDC:
285 RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));
286
287 case ONEPARAM_ROUTINE_REALIZEPALETTE:
288 RETURN (UserRealizePalette((HDC) Param));
289
290 case ONEPARAM_ROUTINE_GETQUEUESTATUS:
291 {
292 DWORD Ret;
293 WORD changed_bits, wake_bits;
294 Ret = IntGetQueueStatus(FALSE);
295 changed_bits = LOWORD(Ret);
296 wake_bits = HIWORD(Ret);
297 RETURN( MAKELONG(changed_bits & Param, wake_bits & Param));
298 }
299 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
300 /* FIXME: Should use UserEnterShared */
301 RETURN(IntEnumClipboardFormats(Param));
302
303 case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
304 IntUserManualGuiCheck(Param);
305 RETURN(TRUE);
306
307 case ONEPARAM_ROUTINE_GETCURSORPOS:
308 {
309 BOOL Ret = TRUE;
310 PPOINTL pptl;
311 PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
312 if (pti->hdesk != InputDesktopHandle) RETURN(FALSE);
313 _SEH2_TRY
314 {
315 pptl = (PPOINTL)Param;
316 *pptl = gpsi->ptCursor;
317 }
318 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
319 {
320 Ret = FALSE;
321 }
322 _SEH2_END;
323 RETURN(Ret);
324 }
325 }
326 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
327 Routine, Param);
328 SetLastWin32Error(ERROR_INVALID_PARAMETER);
329 RETURN( 0);
330
331 CLEANUP:
332 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_);
333 UserLeave();
334 END_CLEANUP;
335 }
336
337
338 /*
339 * @implemented
340 */
341 DWORD_PTR
342 APIENTRY
343 NtUserCallTwoParam(
344 DWORD_PTR Param1,
345 DWORD_PTR Param2,
346 DWORD Routine)
347 {
348 NTSTATUS Status;
349 PWINDOW_OBJECT Window;
350 DECLARE_RETURN(DWORD_PTR);
351
352 DPRINT("Enter NtUserCallTwoParam\n");
353 UserEnterExclusive();
354
355 switch(Routine)
356 {
357 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX:
358 {
359 DWORD_PTR Ret;
360 RECTL rcRect;
361 Window = UserGetWindowObject((HWND)Param1);
362 if (!Window) RETURN(ERROR);
363
364 Ret = (DWORD_PTR)IntGetWindowRgnBox(Window, &rcRect);
365 Status = MmCopyToCaller((PVOID)Param2, &rcRect, sizeof(RECT));
366 if(!NT_SUCCESS(Status))
367 {
368 SetLastNtError(Status);
369 RETURN( ERROR);
370 }
371 RETURN( Ret);
372 }
373 case TWOPARAM_ROUTINE_GETWINDOWRGN:
374 {
375 Window = UserGetWindowObject((HWND)Param1);
376 if (!Window) RETURN(ERROR);
377
378 RETURN( (DWORD_PTR)IntGetWindowRgn(Window, (HRGN)Param2));
379 }
380 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
381 {
382 DWORD_PTR Ret;
383 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
384 if(!MenuObject)
385 RETURN( 0);
386
387 if(Param2 > 0)
388 {
389 Ret = (MenuObject->MenuInfo.Height == (int)Param2);
390 MenuObject->MenuInfo.Height = (int)Param2;
391 }
392 else
393 Ret = (DWORD_PTR)MenuObject->MenuInfo.Height;
394 IntReleaseMenuObject(MenuObject);
395 RETURN( Ret);
396 }
397
398 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
399 {
400 PUSER_MESSAGE_QUEUE MsgQueue = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue;
401
402 ASSERT(MsgQueue);
403 RETURN( (DWORD_PTR)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
404 }
405
406 case TWOPARAM_ROUTINE_ENABLEWINDOW:
407 UNIMPLEMENTED
408 RETURN( 0);
409
410 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
411 {
412 Window = UserGetWindowObject((HWND)Param1);
413 if (!Window) RETURN(0);
414
415 RETURN( (DWORD_PTR)IntShowOwnedPopups(Window, (BOOL) Param2));
416 }
417
418 case TWOPARAM_ROUTINE_ROS_UPDATEUISTATE:
419 {
420 WPARAM wParam;
421 Window = UserGetWindowObject((HWND)Param1);
422 if (!Window) RETURN(0);
423
424 /* Unpack wParam */
425 wParam = MAKEWPARAM((Param2 >> 3) & 0x3,
426 Param2 & (UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE));
427
428 RETURN( UserUpdateUiState(Window->Wnd, wParam) );
429 }
430
431 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
432 UNIMPLEMENTED
433 RETURN( 0);
434
435
436 case TWOPARAM_ROUTINE_SETCARETPOS:
437 RETURN( (DWORD_PTR)co_IntSetCaretPos((int)Param1, (int)Param2));
438
439 case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
440 RETURN( (DWORD_PTR)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
441
442 case TWOPARAM_ROUTINE_SETCURSORPOS:
443 RETURN( (DWORD_PTR)UserSetCursorPos((int)Param1, (int)Param2));
444
445 }
446 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
447 Routine, Param1, Param2);
448 SetLastWin32Error(ERROR_INVALID_PARAMETER);
449 RETURN( 0);
450
451 CLEANUP:
452 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
453 UserLeave();
454 END_CLEANUP;
455 }
456
457
458 /*
459 * @unimplemented
460 */
461 BOOL
462 APIENTRY
463 NtUserCallHwndLock(
464 HWND hWnd,
465 DWORD Routine)
466 {
467 BOOL Ret = 0;
468 PWINDOW_OBJECT Window;
469 PWND Wnd;
470 USER_REFERENCE_ENTRY Ref;
471 DECLARE_RETURN(BOOLEAN);
472
473 DPRINT("Enter NtUserCallHwndLock\n");
474 UserEnterExclusive();
475
476 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
477 {
478 RETURN( FALSE);
479 }
480 UserRefObjectCo(Window, &Ref);
481
482 Wnd = Window->Wnd;
483
484 /* FIXME: Routine can be 0x53 - 0x5E */
485 switch (Routine)
486 {
487 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
488 co_WinPosArrangeIconicWindows(Window);
489 break;
490
491 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
492 {
493 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
494 Ret = TRUE;
495 if ((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
496 co_WinPosSetWindowPos( Window,
497 HWND_DESKTOP,
498 0,0,0,0,
499 SWP_NOSIZE|
500 SWP_NOMOVE|
501 SWP_NOZORDER|
502 SWP_NOACTIVATE|
503 SWP_FRAMECHANGED );
504 break;
505 }
506
507 case HWNDLOCK_ROUTINE_REDRAWFRAME:
508 co_WinPosSetWindowPos( Window,
509 HWND_DESKTOP,
510 0,0,0,0,
511 SWP_NOSIZE|
512 SWP_NOMOVE|
513 SWP_NOZORDER|
514 SWP_NOACTIVATE|
515 SWP_FRAMECHANGED );
516 Ret = TRUE;
517 break;
518
519 case HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK:
520 co_WinPosSetWindowPos( Window,
521 HWND_DESKTOP,
522 0,0,0,0,
523 SWP_NOSIZE|
524 SWP_NOMOVE|
525 SWP_NOZORDER|
526 SWP_NOACTIVATE|
527 SWP_FRAMECHANGED );
528 if (!IntGetOwner(Window) && !IntGetParent(Window))
529 {
530 co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
531 }
532 Ret = TRUE;
533 break;
534
535 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
536 Ret = co_IntSetForegroundWindow(Window);
537 break;
538
539 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
540 Ret = co_UserRedrawWindow( Window, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
541 break;
542 }
543
544 UserDerefObjectCo(Window);
545
546 RETURN( Ret);
547
548 CLEANUP:
549 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_);
550 UserLeave();
551 END_CLEANUP;
552 }
553
554 /*
555 * @unimplemented
556 */
557 HWND
558 APIENTRY
559 NtUserCallHwndOpt(
560 HWND hWnd,
561 DWORD Routine)
562 {
563 switch (Routine)
564 {
565 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
566 GetW32ThreadInfo()->pDeskInfo->hProgmanWindow = hWnd;
567 break;
568
569 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
570 GetW32ThreadInfo()->pDeskInfo->hTaskManWindow = hWnd;
571 break;
572 }
573
574 return hWnd;
575 }
576
577 DWORD
578 APIENTRY
579 NtUserCallHwnd(
580 HWND hWnd,
581 DWORD Routine)
582 {
583 switch (Routine)
584 {
585 case HWND_ROUTINE_GETWNDCONTEXTHLPID:
586 {
587 PWINDOW_OBJECT Window;
588 PPROPERTY HelpId;
589 USER_REFERENCE_ENTRY Ref;
590
591 UserEnterExclusive();
592
593 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
594 {
595 UserLeave();
596 return 0;
597 }
598 UserRefObjectCo(Window, &Ref);
599
600 HelpId = IntGetProp(Window, gpsi->atomContextHelpIdProp);
601
602 UserDerefObjectCo(Window);
603 UserLeave();
604 return (DWORD)HelpId;
605 }
606 case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW:
607 if (IntIsWindow(hWnd))
608 return IntRegisterShellHookWindow(hWnd);
609 return FALSE;
610 break;
611 case HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW:
612 if (IntIsWindow(hWnd))
613 return IntDeRegisterShellHookWindow(hWnd);
614 return FALSE;
615 }
616 UNIMPLEMENTED;
617
618 return 0;
619 }
620
621 DWORD
622 APIENTRY
623 NtUserCallHwndParam(
624 HWND hWnd,
625 DWORD Param,
626 DWORD Routine)
627 {
628
629 switch (Routine)
630 {
631 case HWNDPARAM_ROUTINE_KILLSYSTEMTIMER:
632 return IntKillTimer(hWnd, (UINT_PTR)Param, TRUE);
633
634 case HWNDPARAM_ROUTINE_SETWNDCONTEXTHLPID:
635 {
636 PWINDOW_OBJECT Window;
637
638 UserEnterExclusive();
639 if(!(Window = UserGetWindowObject(hWnd)))
640 {
641 UserLeave();
642 return FALSE;
643 }
644
645 if ( Param )
646 IntSetProp(Window, gpsi->atomContextHelpIdProp, (HANDLE)Param);
647 else
648 IntRemoveProp(Window, gpsi->atomContextHelpIdProp);
649
650 UserLeave();
651 return TRUE;
652 }
653
654 case HWNDPARAM_ROUTINE_SETDIALOGPOINTER:
655 {
656 PWINDOW_OBJECT Window;
657 PWND pWnd;
658 USER_REFERENCE_ENTRY Ref;
659
660 UserEnterExclusive();
661
662 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
663 {
664 UserLeave();
665 return 0;
666 }
667 UserRefObjectCo(Window, &Ref);
668
669 pWnd = Window->Wnd;
670 if (pWnd->head.pti->ppi == PsGetCurrentProcessWin32Process() &&
671 pWnd->cbwndExtra == DLGWINDOWEXTRA &&
672 !(pWnd->state & WNDS_SERVERSIDEWINDOWPROC))
673 {
674 if (Param)
675 {
676 if (!pWnd->fnid) pWnd->fnid = FNID_DIALOG;
677 pWnd->state |= WNDS_DIALOGWINDOW;
678 }
679 else
680 {
681 pWnd->fnid |= FNID_DESTROY;
682 pWnd->state &= ~WNDS_DIALOGWINDOW;
683 }
684 }
685
686 UserDerefObjectCo(Window);
687 UserLeave();
688 return 0;
689 }
690 }
691
692 UNIMPLEMENTED;
693
694 return 0;
695 }
696
697 DWORD
698 APIENTRY
699 NtUserCallHwndParamLock(
700 HWND hWnd,
701 DWORD Param,
702 DWORD Routine)
703 {
704 DWORD Ret = 0;
705 PWINDOW_OBJECT Window;
706 PWND Wnd;
707 USER_REFERENCE_ENTRY Ref;
708 DECLARE_RETURN(DWORD);
709
710 DPRINT1("Enter NtUserCallHwndParamLock\n");
711 UserEnterExclusive();
712
713 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
714 {
715 RETURN( FALSE);
716 }
717 UserRefObjectCo(Window, &Ref);
718
719 Wnd = Window->Wnd;
720
721 switch (Routine)
722 {
723 case TWOPARAM_ROUTINE_VALIDATERGN:
724 Ret = (DWORD)co_UserRedrawWindow( Window, NULL, (HRGN)Param, RDW_VALIDATE);
725 break;
726 }
727
728 UserDerefObjectCo(Window);
729
730 RETURN( Ret);
731
732 CLEANUP:
733 DPRINT1("Leave NtUserCallHwndParamLock, ret=%i\n",_ret_);
734 UserLeave();
735 END_CLEANUP;
736
737 }
738
739 /* EOF */