3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Misc User funcs
6 * FILE: subsys/win32k/ntuser/misc.c
7 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
17 /* registered Logon process */
18 PW32PROCESS LogonProcess
= NULL
;
20 VOID
W32kRegisterPrimitiveMessageQueue(VOID
)
22 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
23 if( !pmPrimitiveMessageQueue
) {
25 pThread
= PsGetWin32Thread();
26 if( pThread
&& pThread
->MessageQueue
) {
27 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
28 IntReferenceMessageQueue(pmPrimitiveMessageQueue
);
29 DPRINT( "Installed primitive input queue.\n" );
32 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
36 VOID
W32kUnregisterPrimitiveMessageQueue(VOID
)
38 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
39 IntDereferenceMessageQueue(pmPrimitiveMessageQueue
);
40 pmPrimitiveMessageQueue
= NULL
;
43 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue()
45 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
46 return pmPrimitiveMessageQueue
;
50 co_IntRegisterLogonProcess(HANDLE ProcessId
, BOOL Register
)
54 CSR_API_MESSAGE Request
;
56 Status
= PsLookupProcessByProcessId(ProcessId
,
58 if (!NT_SUCCESS(Status
))
60 SetLastWin32Error(RtlNtStatusToDosError(Status
));
66 /* Register the logon process */
67 if (LogonProcess
!= NULL
)
69 ObDereferenceObject(Process
);
73 LogonProcess
= (PW32PROCESS
)Process
->Win32Process
;
77 /* Deregister the logon process */
78 if (LogonProcess
!= (PW32PROCESS
)Process
->Win32Process
)
80 ObDereferenceObject(Process
);
87 ObDereferenceObject(Process
);
89 Request
.Type
= MAKE_CSR_API(REGISTER_LOGON_PROCESS
, CSR_GUI
);
90 Request
.Data
.RegisterLogonProcessRequest
.ProcessId
= ProcessId
;
91 Request
.Data
.RegisterLogonProcessRequest
.Register
= Register
;
93 Status
= co_CsrNotify(&Request
);
94 if (! NT_SUCCESS(Status
))
96 DPRINT1("Failed to register logon process with CSRSS\n");
108 NtUserCallNoParam(DWORD Routine
)
111 DECLARE_RETURN(DWORD
);
113 DPRINT("Enter NtUserCallNoParam\n");
114 UserEnterExclusive();
118 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
119 W32kRegisterPrimitiveMessageQueue();
120 Result
= (DWORD
)TRUE
;
123 case NOPARAM_ROUTINE_DESTROY_CARET
:
124 Result
= (DWORD
)co_IntDestroyCaret(PsGetCurrentThread()->Tcb
.Win32Thread
);
127 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
128 Result
= (DWORD
)IntInitMessagePumpHook();
131 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
132 Result
= (DWORD
)IntUninitMessagePumpHook();
135 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
136 Result
= (DWORD
)MsqGetMessageExtraInfo();
139 case NOPARAM_ROUTINE_ANYPOPUP
:
140 Result
= (DWORD
)IntAnyPopup();
143 case NOPARAM_ROUTINE_CSRSS_INITIALIZED
:
144 Result
= (DWORD
)CsrInit();
147 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK
:
148 RETURN( (DWORD
)IntMsqClearWakeMask());
151 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine
);
152 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
158 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_
);
172 DECLARE_RETURN(DWORD
);
174 DPRINT("Enter NtUserCallOneParam\n");
175 UserEnterExclusive();
179 case ONEPARAM_ROUTINE_GETMENU
:
181 PWINDOW_OBJECT WindowObject
;
184 WindowObject
= IntGetWindowObject((HWND
)Param
);
187 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
191 Result
= (DWORD
)WindowObject
->IDMenu
;
193 IntReleaseWindowObject(WindowObject
);
197 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
199 PWINDOW_OBJECT WindowObject
;
202 WindowObject
= IntGetWindowObject((HWND
)Param
);
205 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
208 Result
= WindowObject
->Unicode
;
209 IntReleaseWindowObject(WindowObject
);
213 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
214 RETURN( (DWORD
)IntWindowFromDC((HDC
)Param
));
216 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
218 PWINDOW_OBJECT WindowObject
;
221 WindowObject
= IntGetWindowObject((HWND
)Param
);
224 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
228 Result
= WindowObject
->ContextHelpId
;
230 IntReleaseWindowObject(WindowObject
);
234 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
236 PWINSTATION_OBJECT WinStaObject
;
240 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
244 if (!NT_SUCCESS(Status
))
245 RETURN( (DWORD
)FALSE
);
248 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
251 ObDereferenceObject(WinStaObject
);
255 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
256 RETURN( (DWORD
)IntSwitchCaretShowing((PVOID
)Param
));
258 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
259 RETURN( (DWORD
)IntSetCaretBlinkTime((UINT
)Param
));
261 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
262 RETURN( (DWORD
)IntEnumClipboardFormats((UINT
)Param
));
264 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
266 PWINDOW_OBJECT WindowObject
;
269 if(!(WindowObject
= IntGetWindowObject((HWND
)Param
)))
271 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
275 Result
= (DWORD
)WindowObject
->Instance
;
276 IntReleaseWindowObject(WindowObject
);
280 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
281 RETURN( (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
));
283 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
285 PWINSTATION_OBJECT WinStaObject
;
290 RETURN( (DWORD
)FALSE
);
291 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
295 if (!NT_SUCCESS(Status
))
296 RETURN( (DWORD
)FALSE
);
298 /* FIXME - check if process has WINSTA_READATTRIBUTES */
299 IntGetCursorLocation(WinStaObject
, &Pos
);
301 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
302 if(!NT_SUCCESS(Status
))
304 ObDereferenceObject(WinStaObject
);
305 SetLastNtError(Status
);
309 ObDereferenceObject(WinStaObject
);
311 RETURN( (DWORD
)TRUE
);
314 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
316 PWINDOW_OBJECT WindowObject
;
319 WindowObject
= IntGetWindowObject((HWND
)Param
);
322 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
326 Result
= (DWORD
)IntIsWindowInDestroy(WindowObject
);
328 IntReleaseWindowObject(WindowObject
);
332 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
335 PW32PROCESS Process
= PsGetWin32Process();
339 Enable
= (BOOL
)(Param
!= 0);
343 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
347 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
356 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
357 RETURN( (DWORD
)IntMsqSetWakeMask(Param
));
359 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
360 RETURN( UserGetKeyboardType(Param
));
362 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
363 RETURN( (DWORD
)UserGetKeyboardLayout(Param
));
365 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
367 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
371 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_
);
388 PWINDOW_OBJECT WindowObject
;
389 DECLARE_RETURN(DWORD
);
391 DPRINT("Enter NtUserCallTwoParam\n");
392 UserEnterExclusive();
396 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
398 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
));
400 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
402 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
));
404 case TWOPARAM_ROUTINE_GETDCCOLOR
:
406 RETURN( (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
));
408 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
412 Ret
= (DWORD
)IntGetWindowRgnBox((HWND
)Param1
, &rcRect
);
413 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
414 if(!NT_SUCCESS(Status
))
416 SetLastNtError(Status
);
421 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
423 RETURN( (DWORD
)IntGetWindowRgn((HWND
)Param1
, (HRGN
)Param2
));
425 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
428 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
434 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
435 MenuObject
->MenuInfo
.Height
= (int)Param2
;
438 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
439 IntReleaseMenuObject(MenuObject
);
442 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
445 SETMENUITEMRECT smir
;
446 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
450 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
452 IntReleaseMenuObject(MenuObject
);
456 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
458 IntReleaseMenuObject(MenuObject
);
462 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
464 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Tcb
.Win32Thread
->MessageQueue
;
467 RETURN( (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
));
470 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
474 case TWOPARAM_ROUTINE_UNKNOWN
:
478 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
479 RETURN( (DWORD
)IntShowOwnedPopups((HWND
) Param1
, (BOOL
) Param2
));
481 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
483 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
484 PWINDOW_OBJECT Window
= IntGetWindowObject((HWND
)Param1
);
485 DPRINT1("ROS_SHOWWINDOW\n");
488 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
493 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
495 IntReleaseWindowObject(Window
);
498 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
500 else Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
501 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
502 IntReleaseWindowObject(Window
);
505 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
509 case TWOPARAM_ROUTINE_VALIDATERGN
:
510 RETURN( (DWORD
)UserValidateRgn((HWND
) Param1
, (HRGN
) Param2
));
512 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
513 WindowObject
= IntGetWindowObject((HWND
)Param1
);
516 SetLastWin32Error(ERROR_INVALID_HANDLE
);
517 RETURN( (DWORD
)FALSE
);
520 WindowObject
->ContextHelpId
= Param2
;
522 IntReleaseWindowObject(WindowObject
);
523 RETURN( (DWORD
)TRUE
);
525 case TWOPARAM_ROUTINE_SETCARETPOS
:
526 RETURN( (DWORD
)co_IntSetCaretPos((int)Param1
, (int)Param2
));
528 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
533 if(!(WindowObject
= IntGetWindowObject((HWND
)Param1
)))
535 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
541 * According to WINE, Windows' doesn't check the cbSize field
544 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
545 if(!NT_SUCCESS(Status
))
547 IntReleaseWindowObject(WindowObject
);
548 SetLastNtError(Status
);
552 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
554 IntReleaseWindowObject(WindowObject
);
555 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
560 if((Ret
= (DWORD
)IntGetWindowInfo(WindowObject
, &wi
)))
562 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
563 if(!NT_SUCCESS(Status
))
565 IntReleaseWindowObject(WindowObject
);
566 SetLastNtError(Status
);
571 IntReleaseWindowObject(WindowObject
);
575 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
576 RETURN( (DWORD
)co_IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
));
578 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
588 /* FIXME - we should make use of SEH here... */
590 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
591 if(!NT_SUCCESS(Status
))
593 SetLastNtError(Status
);
597 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
600 INT
*Elements
= (INT
*)Buffer
;
601 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
603 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
604 if(NT_SUCCESS(Status
))
606 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
607 if(NT_SUCCESS(Status
))
609 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
612 SetLastNtError(Status
);
615 SetLastNtError(Status
);
624 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
625 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
626 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
637 /* FIXME - we should make use of SEH here... */
639 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
640 if(Buffer
.Pointer
!= NULL
)
644 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
645 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
647 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
648 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
650 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
651 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
660 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
661 if(!NT_SUCCESS(Status
))
663 SetLastNtError(Status
);
668 ExFreePool(Buffer
.Pointer
);
674 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
675 Routine
, Param1
, Param2
);
676 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
680 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_
);
696 PWINDOW_OBJECT Window
;
697 DECLARE_RETURN(BOOLEAN
);
699 DPRINT("Enter NtUserCallHwndLock\n");
700 UserEnterExclusive();
702 Window
= IntGetWindowObject(hWnd
);
705 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
709 /* FIXME: Routine can be 0x53 - 0x5E */
712 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
713 co_WinPosArrangeIconicWindows(Window
);
716 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
718 PMENU_OBJECT MenuObject
;
719 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
721 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
)) break;
722 MenuObject
= IntGetMenuObject((HMENU
) Window
->IDMenu
);
723 if(MenuObject
== NULL
) break;
724 MenuObject
->MenuInfo
.WndOwner
= hWnd
;
725 MenuObject
->MenuInfo
.Height
= 0;
726 IntReleaseMenuObject(MenuObject
);
727 co_WinPosSetWindowPos(hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
728 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
733 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
737 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
738 Ret
= co_IntSetForegroundWindow(Window
);
741 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
746 IntReleaseWindowObject(Window
);
751 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
767 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
770 * Nothing too hard...validate the hWnd and save it in the Desktop Info
772 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
775 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
778 * Nothing too hard...validate the hWnd and save it in the Desktop Info
780 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
791 NtUserGetThreadState(
794 DECLARE_RETURN(DWORD
);
796 DPRINT("Enter NtUserGetThreadState\n");
802 RETURN( (DWORD
)IntGetThreadFocusWindow());
807 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
813 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
815 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
817 static LOGFONTW DefaultFont
= {
818 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
819 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
820 L
"Bitstream Vera Sans"
823 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
825 QueryTable
[0].Name
= lpValueName
;
826 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
827 QueryTable
[0].EntryContext
= font
;
829 Status
= RtlQueryRegistryValues(
831 L
"Control Panel\\Desktop\\WindowMetrics",
836 if (!NT_SUCCESS(Status
))
838 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
843 IntSystemParametersInfo(
849 PWINSTATION_OBJECT WinStaObject
;
852 static BOOL bInitialized
= FALSE
;
853 static LOGFONTW IconFont
;
854 static NONCLIENTMETRICSW pMetrics
;
855 static BOOL GradientCaptions
= TRUE
;
856 static UINT FocusBorderHeight
= 1;
857 static UINT FocusBorderWidth
= 1;
861 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
862 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
864 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
865 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
866 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
867 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
868 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
869 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
871 pMetrics
.iBorderWidth
= 1;
872 pMetrics
.iScrollWidth
= UserGetSystemMetrics(SM_CXVSCROLL
);
873 pMetrics
.iScrollHeight
= UserGetSystemMetrics(SM_CYHSCROLL
);
874 pMetrics
.iCaptionWidth
= UserGetSystemMetrics(SM_CXSIZE
);
875 pMetrics
.iCaptionHeight
= UserGetSystemMetrics(SM_CYSIZE
);
876 pMetrics
.iSmCaptionWidth
= UserGetSystemMetrics(SM_CXSMSIZE
);
877 pMetrics
.iSmCaptionHeight
= UserGetSystemMetrics(SM_CYSMSIZE
);
878 pMetrics
.iMenuWidth
= UserGetSystemMetrics(SM_CXMENUSIZE
);
879 pMetrics
.iMenuHeight
= UserGetSystemMetrics(SM_CYMENUSIZE
);
880 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
887 case SPI_SETDOUBLECLKWIDTH
:
888 case SPI_SETDOUBLECLKHEIGHT
:
889 case SPI_SETDOUBLECLICKTIME
:
890 case SPI_SETDESKWALLPAPER
:
891 case SPI_GETDESKWALLPAPER
:
893 PSYSTEM_CURSORINFO CurInfo
;
895 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
899 if(!NT_SUCCESS(Status
))
901 SetLastNtError(Status
);
907 case SPI_SETDOUBLECLKWIDTH
:
908 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
909 /* FIXME limit the maximum value? */
910 CurInfo
->DblClickWidth
= uiParam
;
912 case SPI_SETDOUBLECLKHEIGHT
:
913 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
914 /* FIXME limit the maximum value? */
915 CurInfo
->DblClickHeight
= uiParam
;
917 case SPI_SETDOUBLECLICKTIME
:
918 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
919 /* FIXME limit the maximum time to 1000 ms? */
920 CurInfo
->DblClickSpeed
= uiParam
;
922 case SPI_SETDESKWALLPAPER
:
924 /* This function expects different parameters than the user mode version!
926 We let the user mode code load the bitmap, it passed the handle to
927 the bitmap. We'll change it's ownership to system and replace it with
928 the current wallpaper bitmap */
929 HBITMAP hOldBitmap
, hNewBitmap
;
932 hNewBitmap
= *(HBITMAP
*)pvParam
;
933 if(hNewBitmap
!= NULL
)
936 /* try to get the size of the wallpaper */
937 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
939 ObDereferenceObject(WinStaObject
);
942 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
943 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
945 BITMAPOBJ_UnlockBitmap(bmp
);
947 /* change the bitmap's ownership */
948 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
950 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
951 if(hOldBitmap
!= NULL
)
953 /* delete the old wallpaper */
954 NtGdiDeleteObject(hOldBitmap
);
958 case SPI_GETDESKWALLPAPER
:
959 /* This function expects different parameters than the user mode version!
961 We basically return the current wallpaper handle - if any. The user
962 mode version should load the string from the registry and return it
963 without calling this function */
965 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
969 /* FIXME save the value to the registry */
971 ObDereferenceObject(WinStaObject
);
974 case SPI_SETWORKAREA
:
977 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
981 /* FIXME - Set last error */
987 Desktop
->WorkArea
= *rc
;
991 case SPI_GETWORKAREA
:
993 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
997 /* FIXME - Set last error */
1002 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
1006 case SPI_SETGRADIENTCAPTIONS
:
1008 GradientCaptions
= (pvParam
!= NULL
);
1009 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1012 case SPI_GETGRADIENTCAPTIONS
:
1015 BOOL Ret
= GradientCaptions
;
1017 hDC
= IntGetScreenDC();
1020 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
1023 *((PBOOL
)pvParam
) = Ret
;
1028 case SPI_SETFONTSMOOTHING
:
1030 IntEnableFontRendering(uiParam
!= 0);
1033 case SPI_GETFONTSMOOTHING
:
1036 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
1039 case SPI_GETICONTITLELOGFONT
:
1042 *((LOGFONTW
*)pvParam
) = IconFont
;
1045 case SPI_GETNONCLIENTMETRICS
:
1048 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1051 case SPI_GETFOCUSBORDERHEIGHT
:
1054 *((UINT
*)pvParam
) = FocusBorderHeight
;
1057 case SPI_GETFOCUSBORDERWIDTH
:
1060 *((UINT
*)pvParam
) = FocusBorderWidth
;
1063 case SPI_SETFOCUSBORDERHEIGHT
:
1065 FocusBorderHeight
= (UINT
)pvParam
;
1068 case SPI_SETFOCUSBORDERWIDTH
:
1070 FocusBorderWidth
= (UINT
)pvParam
;
1076 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1077 uiAction
, uiParam
, pvParam
, fWinIni
);
1088 UserSystemParametersInfo(
1098 case SPI_SETDOUBLECLKWIDTH
:
1099 case SPI_SETDOUBLECLKHEIGHT
:
1100 case SPI_SETDOUBLECLICKTIME
:
1101 case SPI_SETGRADIENTCAPTIONS
:
1102 case SPI_SETFONTSMOOTHING
:
1103 case SPI_SETFOCUSBORDERHEIGHT
:
1104 case SPI_SETFOCUSBORDERWIDTH
:
1106 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1108 case SPI_SETWORKAREA
:
1111 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1112 if(!NT_SUCCESS(Status
))
1114 SetLastNtError(Status
);
1117 return( (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
));
1119 case SPI_GETWORKAREA
:
1123 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1128 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1129 if(!NT_SUCCESS(Status
))
1131 SetLastNtError(Status
);
1136 case SPI_GETFONTSMOOTHING
:
1137 case SPI_GETGRADIENTCAPTIONS
:
1138 case SPI_GETFOCUSBORDERHEIGHT
:
1139 case SPI_GETFOCUSBORDERWIDTH
:
1143 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1148 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1149 if(!NT_SUCCESS(Status
))
1151 SetLastNtError(Status
);
1156 case SPI_SETDESKWALLPAPER
:
1158 /* !!! As opposed to the user mode version this version accepts a handle
1160 HBITMAP hbmWallpaper
;
1162 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1163 if(!NT_SUCCESS(Status
))
1165 SetLastNtError(Status
);
1168 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
));
1170 case SPI_GETDESKWALLPAPER
:
1172 /* !!! As opposed to the user mode version this version returns a handle
1174 HBITMAP hbmWallpaper
;
1177 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1179 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1180 if(!NT_SUCCESS(Status
))
1182 SetLastNtError(Status
);
1187 case SPI_GETICONTITLELOGFONT
:
1191 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1196 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1197 if(!NT_SUCCESS(Status
))
1199 SetLastNtError(Status
);
1204 case SPI_GETNONCLIENTMETRICS
:
1206 NONCLIENTMETRICSW metrics
;
1208 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1209 if(!NT_SUCCESS(Status
))
1211 SetLastNtError(Status
);
1214 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1216 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1220 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1225 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1226 if(!NT_SUCCESS(Status
))
1228 SetLastNtError(Status
);
1245 NtUserSystemParametersInfo(
1251 DECLARE_RETURN(BOOLEAN
);
1253 DPRINT("Enter NtUserSystemParametersInfo\n");
1254 UserEnterExclusive();
1256 RETURN( UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
));
1259 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_
);
1268 NtUserGetDoubleClickTime(VOID
)
1272 PWINSTATION_OBJECT WinStaObject
;
1273 PSYSTEM_CURSORINFO CurInfo
;
1274 DECLARE_RETURN(UINT
);
1276 DPRINT("Enter NtUserGetDoubleClickTime\n");
1279 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1283 if (!NT_SUCCESS(Status
))
1284 RETURN( (DWORD
)FALSE
);
1286 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1287 Result
= CurInfo
->DblClickSpeed
;
1289 ObDereferenceObject(WinStaObject
);
1293 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_
);
1300 NtUserGetGUIThreadInfo(
1301 DWORD idThread
, /* if NULL use foreground thread */
1302 LPGUITHREADINFO lpgui
)
1305 PTHRDCARETINFO CaretInfo
;
1306 GUITHREADINFO SafeGui
;
1307 PDESKTOP_OBJECT Desktop
;
1308 PUSER_MESSAGE_QUEUE MsgQueue
;
1309 PETHREAD Thread
= NULL
;
1310 DECLARE_RETURN(BOOLEAN
);
1312 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1315 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1316 if(!NT_SUCCESS(Status
))
1318 SetLastNtError(Status
);
1322 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1324 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1330 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1331 if(!NT_SUCCESS(Status
))
1333 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1336 Desktop
= Thread
->Tcb
.Win32Thread
->Desktop
;
1340 /* get the foreground thread */
1341 PW32THREAD W32Thread
= PsGetCurrentThread()->Tcb
.Win32Thread
;
1342 Desktop
= W32Thread
->Desktop
;
1345 MsgQueue
= Desktop
->ActiveMessageQueue
;
1348 Thread
= MsgQueue
->Thread
;
1353 if(!Thread
|| !Desktop
)
1355 if(idThread
&& Thread
)
1356 ObDereferenceObject(Thread
);
1357 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1361 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1362 CaretInfo
= MsgQueue
->CaretInfo
;
1364 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1365 if(MsgQueue
->MenuOwner
)
1366 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1367 if(MsgQueue
->MoveSize
)
1368 SafeGui
.flags
|= GUI_INMOVESIZE
;
1370 /* FIXME add flag GUI_16BITTASK */
1372 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1373 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1374 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1375 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1376 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1377 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1379 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1380 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1381 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1382 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1385 ObDereferenceObject(Thread
);
1387 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1388 if(!NT_SUCCESS(Status
))
1390 SetLastNtError(Status
);
1397 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
1405 NtUserGetGuiResources(
1410 PW32PROCESS W32Process
;
1413 DECLARE_RETURN(DWORD
);
1415 DPRINT("Enter NtUserGetGuiResources\n");
1418 Status
= ObReferenceObjectByHandle(hProcess
,
1419 PROCESS_QUERY_INFORMATION
,
1421 ExGetPreviousMode(),
1425 if(!NT_SUCCESS(Status
))
1427 SetLastNtError(Status
);
1431 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1434 ObDereferenceObject(Process
);
1435 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1443 Ret
= (DWORD
)W32Process
->GDIObjects
;
1446 case GR_USEROBJECTS
:
1448 Ret
= (DWORD
)W32Process
->UserObjects
;
1453 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1458 ObDereferenceObject(Process
);
1463 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
1469 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1470 PUNICODE_STRING Source
)
1475 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1476 if(!NT_SUCCESS(Status
))
1481 if(Dest
->Length
> 0x4000)
1483 return STATUS_UNSUCCESSFUL
;
1487 Dest
->Buffer
= NULL
;
1489 if(Dest
->Length
> 0 && Src
)
1491 Dest
->MaximumLength
= Dest
->Length
;
1492 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1495 return STATUS_NO_MEMORY
;
1498 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1499 if(!NT_SUCCESS(Status
))
1501 ExFreePool(Dest
->Buffer
);
1502 Dest
->Buffer
= NULL
;
1507 return STATUS_SUCCESS
;
1510 /* string is empty */
1511 return STATUS_SUCCESS
;
1515 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1516 PUNICODE_STRING Source
)
1521 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1522 if(!NT_SUCCESS(Status
))
1527 if(Dest
->Length
> 0x4000)
1529 return STATUS_UNSUCCESSFUL
;
1533 Dest
->Buffer
= NULL
;
1535 if(Dest
->Length
> 0 && Src
)
1537 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1538 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1541 return STATUS_NO_MEMORY
;
1544 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1545 if(!NT_SUCCESS(Status
))
1547 ExFreePool(Dest
->Buffer
);
1548 Dest
->Buffer
= NULL
;
1552 /* make sure the string is null-terminated */
1553 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1556 return STATUS_SUCCESS
;
1559 /* string is empty */
1560 return STATUS_SUCCESS
;
1564 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1566 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1567 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1569 /* The unicode_string is already nul terminated. Just reuse it. */
1570 *Dest
= Src
->Buffer
;
1571 return STATUS_SUCCESS
;
1574 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1577 return STATUS_NO_MEMORY
;
1579 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1580 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1582 return STATUS_SUCCESS
;
1586 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1588 if (NullTerminated
!= UnicodeString
->Buffer
)
1590 ExFreePool(NullTerminated
);
1595 NtUserUpdatePerUserSystemParameters(
1600 DECLARE_RETURN(BOOLEAN
);
1602 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1603 UserEnterExclusive();
1605 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);
1609 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_
);