- Patch by Smiley <johnyadams@hotmail.com>: remove redundant system calls when window...
[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
78 APIENTRY
79 NtUserCallNoParam(DWORD Routine)
80 {
81 DWORD Result = 0;
82 DECLARE_RETURN(DWORD);
83
84 DPRINT("Enter NtUserCallNoParam\n");
85 UserEnterExclusive();
86
87 switch(Routine)
88 {
89 case NOPARAM_ROUTINE_CREATEMENU:
90 Result = (DWORD)UserCreateMenu(FALSE);
91 break;
92
93 case NOPARAM_ROUTINE_CREATEMENUPOPUP:
94 Result = (DWORD)UserCreateMenu(TRUE);
95 break;
96
97 case NOPARAM_ROUTINE_DESTROY_CARET:
98 Result = (DWORD)co_IntDestroyCaret(PsGetCurrentThread()->Tcb.Win32Thread);
99 break;
100
101 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP:
102 Result = (DWORD)IntInitMessagePumpHook();
103 break;
104
105 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP:
106 Result = (DWORD)IntUninitMessagePumpHook();
107 break;
108
109 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO:
110 Result = (DWORD)MsqGetMessageExtraInfo();
111 break;
112
113 case NOPARAM_ROUTINE_ANYPOPUP:
114 Result = (DWORD)IntAnyPopup();
115 break;
116
117 case NOPARAM_ROUTINE_CSRSS_INITIALIZED:
118 Result = (DWORD)CsrInit();
119 break;
120
121 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK:
122 RETURN( (DWORD)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
142 APIENTRY
143 NtUserCallOneParam(
144 DWORD Param,
145 DWORD Routine)
146 {
147 DECLARE_RETURN(DWORD);
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)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)DesktopHeapAddressToUser((PVOID)Param));
174 }
175 else
176 {
177 RETURN(0);
178 }
179 }
180
181 case ONEPARAM_ROUTINE_WINDOWFROMDC:
182 RETURN( (DWORD)IntWindowFromDC((HDC)Param));
183
184 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON:
185 {
186 DWORD 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)IntSwitchCaretShowing((PVOID)Param));
196
197 case ONEPARAM_ROUTINE_SETCARETBLINKTIME:
198 RETURN( (DWORD)IntSetCaretBlinkTime((UINT)Param));
199
200 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO:
201 RETURN( (DWORD)MsqSetMessageExtraInfo((LPARAM)Param));
202
203 case ONEPARAM_ROUTINE_CREATECURICONHANDLE:
204 {
205 PCURICON_OBJECT CurIcon;
206 PWINSTATION_OBJECT WinSta;
207
208 WinSta = IntGetWinStaObj();
209 if(WinSta == NULL)
210 {
211 RETURN(0);
212 }
213
214 if (!(CurIcon = IntCreateCurIconHandle(WinSta)))
215 {
216 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
217 ObDereferenceObject(WinSta);
218 RETURN(0);
219 }
220
221 ObDereferenceObject(WinSta);
222 RETURN((DWORD)CurIcon->Self);
223 }
224
225 case ONEPARAM_ROUTINE_GETCURSORPOSITION:
226 {
227 PWINSTATION_OBJECT WinSta;
228 NTSTATUS Status;
229 POINT Pos;
230
231 if(!Param)
232 RETURN( (DWORD)FALSE);
233 Status = IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation,
234 KernelMode,
235 0,
236 &WinSta);
237 if (!NT_SUCCESS(Status))
238 RETURN( (DWORD)FALSE);
239
240 /* FIXME - check if process has WINSTA_READATTRIBUTES */
241 IntGetCursorLocation(WinSta, &Pos);
242
243 Status = MmCopyToCaller((PPOINT)Param, &Pos, sizeof(POINT));
244 if(!NT_SUCCESS(Status))
245 {
246 ObDereferenceObject(WinSta);
247 SetLastNtError(Status);
248 RETURN( FALSE);
249 }
250
251 ObDereferenceObject(WinSta);
252
253 RETURN( (DWORD)TRUE);
254 }
255
256 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY:
257 {
258 PWINDOW_OBJECT Window;
259 DWORD Result;
260
261 if(!(Window = UserGetWindowObject((HWND)Param)))
262 {
263 RETURN( FALSE);
264 }
265
266 Result = (DWORD)IntIsWindowInDestroy(Window);
267
268 RETURN( Result);
269 }
270
271 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING:
272 {
273 BOOL Enable;
274 PPROCESSINFO Process = PsGetCurrentProcessWin32Process();
275
276 if(Process != NULL)
277 {
278 Enable = (BOOL)(Param != 0);
279
280 if(Enable)
281 {
282 Process->W32PF_flags &= ~W32PF_NOWINDOWGHOSTING;
283 }
284 else
285 {
286 Process->W32PF_flags |= W32PF_NOWINDOWGHOSTING;
287 }
288
289 RETURN( TRUE);
290 }
291
292 RETURN( FALSE);
293 }
294
295 case ONEPARAM_ROUTINE_MSQSETWAKEMASK:
296 RETURN( (DWORD)IntMsqSetWakeMask(Param));
297
298 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE:
299 RETURN( UserGetKeyboardType(Param));
300
301 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT:
302 RETURN( (DWORD)UserGetKeyboardLayout(Param));
303
304 case ONEPARAM_ROUTINE_RELEASEDC:
305 RETURN (UserReleaseDC(NULL, (HDC) Param, FALSE));
306
307 case ONEPARAM_ROUTINE_REALIZEPALETTE:
308 RETURN (UserRealizePalette((HDC) Param));
309
310 case ONEPARAM_ROUTINE_GETQUEUESTATUS:
311 {
312 DWORD Ret;
313 WORD changed_bits, wake_bits;
314 Ret = IntGetQueueStatus(FALSE);
315 changed_bits = LOWORD(Ret);
316 wake_bits = HIWORD(Ret);
317 RETURN( MAKELONG(changed_bits & Param, wake_bits & Param));
318 }
319 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS:
320 /* FIXME: Should use UserEnterShared */
321 RETURN(IntEnumClipboardFormats(Param));
322
323 case ONEPARAM_ROUTINE_CSRSS_GUICHECK:
324 IntUserManualGuiCheck(Param);
325 RETURN(TRUE);
326
327 case ONEPARAM_ROUTINE_GETCURSORPOS:
328 {
329 BOOL Ret = TRUE;
330 PPOINTL pptl;
331 PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
332 if (pti->hDesktop != InputDesktopHandle) RETURN(FALSE);
333 _SEH2_TRY
334 {
335 pptl = (PPOINTL)Param;
336 *pptl = gpsi->ptCursor;
337 }
338 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
339 {
340 Ret = FALSE;
341 }
342 _SEH2_END;
343 RETURN(Ret);
344 }
345 }
346 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
347 Routine, Param);
348 SetLastWin32Error(ERROR_INVALID_PARAMETER);
349 RETURN( 0);
350
351 CLEANUP:
352 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_);
353 UserLeave();
354 END_CLEANUP;
355 }
356
357
358 /*
359 * @implemented
360 */
361 DWORD
362 APIENTRY
363 NtUserCallTwoParam(
364 DWORD Param1,
365 DWORD Param2,
366 DWORD Routine)
367 {
368 NTSTATUS Status;
369 PWINDOW_OBJECT Window;
370 DECLARE_RETURN(DWORD);
371
372 DPRINT("Enter NtUserCallTwoParam\n");
373 UserEnterExclusive();
374
375 switch(Routine)
376 {
377 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX:
378 {
379 DWORD Ret;
380 RECTL rcRect;
381 Window = UserGetWindowObject((HWND)Param1);
382 if (!Window) RETURN(ERROR);
383
384 Ret = (DWORD)IntGetWindowRgnBox(Window, &rcRect);
385 Status = MmCopyToCaller((PVOID)Param2, &rcRect, sizeof(RECT));
386 if(!NT_SUCCESS(Status))
387 {
388 SetLastNtError(Status);
389 RETURN( ERROR);
390 }
391 RETURN( Ret);
392 }
393 case TWOPARAM_ROUTINE_GETWINDOWRGN:
394 {
395 Window = UserGetWindowObject((HWND)Param1);
396 if (!Window) RETURN(ERROR);
397
398 RETURN( (DWORD)IntGetWindowRgn(Window, (HRGN)Param2));
399 }
400 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT:
401 {
402 DWORD Ret;
403 PMENU_OBJECT MenuObject = IntGetMenuObject((HMENU)Param1);
404 if(!MenuObject)
405 RETURN( 0);
406
407 if(Param2 > 0)
408 {
409 Ret = (MenuObject->MenuInfo.Height == (int)Param2);
410 MenuObject->MenuInfo.Height = (int)Param2;
411 }
412 else
413 Ret = (DWORD)MenuObject->MenuInfo.Height;
414 IntReleaseMenuObject(MenuObject);
415 RETURN( Ret);
416 }
417
418 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE:
419 {
420 PUSER_MESSAGE_QUEUE MsgQueue = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->MessageQueue;
421
422 ASSERT(MsgQueue);
423 RETURN( (DWORD)MsqSetStateWindow(MsgQueue, (ULONG)Param1, (HWND)Param2));
424 }
425
426 case TWOPARAM_ROUTINE_ENABLEWINDOW:
427 UNIMPLEMENTED
428 RETURN( 0);
429
430 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS:
431 {
432 Window = UserGetWindowObject((HWND)Param1);
433 if (!Window) RETURN(0);
434
435 RETURN( (DWORD)IntShowOwnedPopups(Window, (BOOL) Param2));
436 }
437
438 case TWOPARAM_ROUTINE_ROS_UPDATEUISTATE:
439 {
440 WPARAM wParam;
441 Window = UserGetWindowObject((HWND)Param1);
442 if (!Window) RETURN(0);
443
444 /* Unpack wParam */
445 wParam = MAKEWPARAM((Param2 >> 3) & 0x3,
446 Param2 & (UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE));
447
448 RETURN( UserUpdateUiState(Window->Wnd, wParam) );
449 }
450
451 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW:
452 UNIMPLEMENTED
453 RETURN( 0);
454
455
456 case TWOPARAM_ROUTINE_SETCARETPOS:
457 RETURN( (DWORD)co_IntSetCaretPos((int)Param1, (int)Param2));
458
459 case TWOPARAM_ROUTINE_REGISTERLOGONPROC:
460 RETURN( (DWORD)co_IntRegisterLogonProcess((HANDLE)Param1, (BOOL)Param2));
461 }
462 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
463 Routine, Param1, Param2);
464 SetLastWin32Error(ERROR_INVALID_PARAMETER);
465 RETURN( 0);
466
467 CLEANUP:
468 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_);
469 UserLeave();
470 END_CLEANUP;
471 }
472
473
474 /*
475 * @unimplemented
476 */
477 BOOL
478 APIENTRY
479 NtUserCallHwndLock(
480 HWND hWnd,
481 DWORD Routine)
482 {
483 BOOL Ret = 0;
484 PWINDOW_OBJECT Window;
485 PWND Wnd;
486 USER_REFERENCE_ENTRY Ref;
487 DECLARE_RETURN(BOOLEAN);
488
489 DPRINT("Enter NtUserCallHwndLock\n");
490 UserEnterExclusive();
491
492 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
493 {
494 RETURN( FALSE);
495 }
496 UserRefObjectCo(Window, &Ref);
497
498 Wnd = Window->Wnd;
499
500 /* FIXME: Routine can be 0x53 - 0x5E */
501 switch (Routine)
502 {
503 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS:
504 co_WinPosArrangeIconicWindows(Window);
505 break;
506
507 case HWNDLOCK_ROUTINE_DRAWMENUBAR:
508 {
509 PMENU_OBJECT Menu;
510 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
511 Ret = FALSE;
512 if (!((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
513 break;
514
515 if(!(Menu = UserGetMenuObject((HMENU) Wnd->IDMenu)))
516 break;
517
518 Menu->MenuInfo.WndOwner = hWnd;
519 Menu->MenuInfo.Height = 0;
520
521 co_WinPosSetWindowPos( Window,
522 HWND_DESKTOP,
523 0,0,0,0,
524 SWP_NOSIZE|
525 SWP_NOMOVE|
526 SWP_NOZORDER|
527 SWP_NOACTIVATE|
528 SWP_FRAMECHANGED );
529
530 Ret = TRUE;
531 break;
532 }
533
534 case HWNDLOCK_ROUTINE_REDRAWFRAME:
535 co_WinPosSetWindowPos( Window,
536 HWND_DESKTOP,
537 0,0,0,0,
538 SWP_NOSIZE|
539 SWP_NOMOVE|
540 SWP_NOZORDER|
541 SWP_NOACTIVATE|
542 SWP_FRAMECHANGED );
543 Ret = TRUE;
544 break;
545
546 case HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK:
547 co_WinPosSetWindowPos( Window,
548 HWND_DESKTOP,
549 0,0,0,0,
550 SWP_NOSIZE|
551 SWP_NOMOVE|
552 SWP_NOZORDER|
553 SWP_NOACTIVATE|
554 SWP_FRAMECHANGED );
555 if (!IntGetOwner(Window) && !IntGetParent(Window))
556 {
557 co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
558 }
559 Ret = TRUE;
560 break;
561
562 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW:
563 Ret = co_IntSetForegroundWindow(Window);
564 break;
565
566 case HWNDLOCK_ROUTINE_UPDATEWINDOW:
567 Ret = co_UserRedrawWindow( Window, NULL, 0, RDW_UPDATENOW | RDW_ALLCHILDREN);
568 break;
569 }
570
571 UserDerefObjectCo(Window);
572
573 RETURN( Ret);
574
575 CLEANUP:
576 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_);
577 UserLeave();
578 END_CLEANUP;
579 }
580
581 /*
582 * @unimplemented
583 */
584 HWND
585 APIENTRY
586 NtUserCallHwndOpt(
587 HWND hWnd,
588 DWORD Routine)
589 {
590 switch (Routine)
591 {
592 case HWNDOPT_ROUTINE_SETPROGMANWINDOW:
593 GetW32ThreadInfo()->pDeskInfo->hProgmanWindow = hWnd;
594 break;
595
596 case HWNDOPT_ROUTINE_SETTASKMANWINDOW:
597 GetW32ThreadInfo()->pDeskInfo->hTaskManWindow = hWnd;
598 break;
599 }
600
601 return hWnd;
602 }
603
604 DWORD
605 APIENTRY
606 NtUserCallHwnd(
607 HWND hWnd,
608 DWORD Routine)
609 {
610 switch (Routine)
611 {
612 case HWND_ROUTINE_GETWNDCONTEXTHLPID:
613 {
614 PWINDOW_OBJECT Window;
615 PPROPERTY HelpId;
616 USER_REFERENCE_ENTRY Ref;
617
618 UserEnterExclusive();
619
620 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
621 {
622 UserLeave();
623 return 0;
624 }
625 UserRefObjectCo(Window, &Ref);
626
627 HelpId = IntGetProp(Window, gpsi->atomContextHelpIdProp);
628
629 UserDerefObjectCo(Window);
630 UserLeave();
631 return (DWORD)HelpId;
632 }
633 case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW:
634 if (IntIsWindow(hWnd))
635 return IntRegisterShellHookWindow(hWnd);
636 return FALSE;
637 break;
638 case HWND_ROUTINE_DEREGISTERSHELLHOOKWINDOW:
639 if (IntIsWindow(hWnd))
640 return IntDeRegisterShellHookWindow(hWnd);
641 return FALSE;
642 }
643 UNIMPLEMENTED;
644
645 return 0;
646 }
647
648 DWORD
649 APIENTRY
650 NtUserCallHwndParam(
651 HWND hWnd,
652 DWORD Param,
653 DWORD Routine)
654 {
655
656 switch (Routine)
657 {
658 case HWNDPARAM_ROUTINE_KILLSYSTEMTIMER:
659 return IntKillTimer(hWnd, (UINT_PTR)Param, TRUE);
660
661 case HWNDPARAM_ROUTINE_SETWNDCONTEXTHLPID:
662 {
663 PWINDOW_OBJECT Window;
664
665 UserEnterExclusive();
666 if(!(Window = UserGetWindowObject(hWnd)))
667 {
668 UserLeave();
669 return FALSE;
670 }
671
672 if ( Param )
673 IntSetProp(Window, gpsi->atomContextHelpIdProp, (HANDLE)Param);
674 else
675 IntRemoveProp(Window, gpsi->atomContextHelpIdProp);
676
677 UserLeave();
678 return TRUE;
679 }
680
681 case HWNDPARAM_ROUTINE_SETDIALOGPOINTER:
682 {
683 PWINDOW_OBJECT Window;
684 PWND pWnd;
685 USER_REFERENCE_ENTRY Ref;
686
687 UserEnterExclusive();
688
689 if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
690 {
691 UserLeave();
692 return 0;
693 }
694 UserRefObjectCo(Window, &Ref);
695
696 pWnd = Window->Wnd;
697 if (pWnd->head.pti->ppi == PsGetCurrentProcessWin32Process() &&
698 pWnd->cbwndExtra == DLGWINDOWEXTRA &&
699 !(pWnd->state & WNDS_SERVERSIDEWINDOWPROC))
700 {
701 if (Param)
702 {
703 if (!pWnd->fnid) pWnd->fnid = FNID_DIALOG;
704 pWnd->state |= WNDS_DIALOGWINDOW;
705 }
706 else
707 {
708 pWnd->fnid |= FNID_DESTROY;
709 pWnd->state &= ~WNDS_DIALOGWINDOW;
710 }
711 }
712
713 UserDerefObjectCo(Window);
714 UserLeave();
715 return 0;
716 }
717 }
718
719 UNIMPLEMENTED;
720
721 return 0;
722 }
723
724 DWORD
725 APIENTRY
726 NtUserCallHwndParamLock(
727 HWND hWnd,
728 DWORD Param,
729 DWORD Routine)
730 {
731 UNIMPLEMENTED;
732
733 return 0;
734 }
735
736 /* EOF */