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
)
26 pThread
= PsGetWin32Thread();
27 if( pThread
&& pThread
->MessageQueue
)
29 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
30 IntReferenceMessageQueue(pmPrimitiveMessageQueue
);
31 DPRINT( "Installed primitive input queue.\n" );
36 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
40 VOID
W32kUnregisterPrimitiveMessageQueue(VOID
)
42 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
43 IntDereferenceMessageQueue(pmPrimitiveMessageQueue
);
44 pmPrimitiveMessageQueue
= NULL
;
47 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue()
49 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
50 return pmPrimitiveMessageQueue
;
54 co_IntRegisterLogonProcess(HANDLE ProcessId
, BOOL Register
)
58 CSR_API_MESSAGE Request
;
60 Status
= PsLookupProcessByProcessId(ProcessId
,
62 if (!NT_SUCCESS(Status
))
64 SetLastWin32Error(RtlNtStatusToDosError(Status
));
70 /* Register the logon process */
71 if (LogonProcess
!= NULL
)
73 ObDereferenceObject(Process
);
77 LogonProcess
= (PW32PROCESS
)Process
->Win32Process
;
81 /* Deregister the logon process */
82 if (LogonProcess
!= (PW32PROCESS
)Process
->Win32Process
)
84 ObDereferenceObject(Process
);
91 ObDereferenceObject(Process
);
93 Request
.Type
= MAKE_CSR_API(REGISTER_LOGON_PROCESS
, CSR_GUI
);
94 Request
.Data
.RegisterLogonProcessRequest
.ProcessId
= ProcessId
;
95 Request
.Data
.RegisterLogonProcessRequest
.Register
= Register
;
97 Status
= co_CsrNotify(&Request
);
98 if (! NT_SUCCESS(Status
))
100 DPRINT1("Failed to register logon process with CSRSS\n");
112 NtUserCallNoParam(DWORD Routine
)
115 DECLARE_RETURN(DWORD
);
117 DPRINT("Enter NtUserCallNoParam\n");
118 UserEnterExclusive();
122 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
123 W32kRegisterPrimitiveMessageQueue();
124 Result
= (DWORD
)TRUE
;
127 case NOPARAM_ROUTINE_DESTROY_CARET
:
128 Result
= (DWORD
)co_IntDestroyCaret(PsGetCurrentThread()->Tcb
.Win32Thread
);
131 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
132 Result
= (DWORD
)IntInitMessagePumpHook();
135 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
136 Result
= (DWORD
)IntUninitMessagePumpHook();
139 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
140 Result
= (DWORD
)MsqGetMessageExtraInfo();
143 case NOPARAM_ROUTINE_ANYPOPUP
:
144 Result
= (DWORD
)IntAnyPopup();
147 case NOPARAM_ROUTINE_CSRSS_INITIALIZED
:
148 Result
= (DWORD
)CsrInit();
151 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK
:
152 RETURN( (DWORD
)IntMsqClearWakeMask());
155 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine
);
156 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
162 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_
);
176 DECLARE_RETURN(DWORD
);
178 DPRINT("Enter NtUserCallOneParam\n");
179 UserEnterExclusive();
183 case ONEPARAM_ROUTINE_GETMENU
:
185 PWINDOW_OBJECT Window
;
188 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
193 Result
= (DWORD
)Window
->IDMenu
;
198 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
200 PWINDOW_OBJECT Window
;
203 Window
= UserGetWindowObject((HWND
)Param
);
208 Result
= Window
->Unicode
;
212 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
213 RETURN( (DWORD
)IntWindowFromDC((HDC
)Param
));
215 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
217 PWINDOW_OBJECT Window
;
220 Window
= UserGetWindowObject((HWND
)Param
);
226 Result
= Window
->ContextHelpId
;
231 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
233 PWINSTATION_OBJECT WinSta
;
237 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
241 if (!NT_SUCCESS(Status
))
242 RETURN( (DWORD
)FALSE
);
245 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
248 ObDereferenceObject(WinSta
);
252 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
253 RETURN( (DWORD
)IntSwitchCaretShowing((PVOID
)Param
));
255 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
256 RETURN( (DWORD
)IntSetCaretBlinkTime((UINT
)Param
));
258 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
259 RETURN( (DWORD
)IntEnumClipboardFormats((UINT
)Param
));
261 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
263 PWINDOW_OBJECT Window
;
266 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
271 Result
= (DWORD
)Window
->Instance
;
275 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
276 RETURN( (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
));
278 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
280 PWINSTATION_OBJECT WinSta
;
285 RETURN( (DWORD
)FALSE
);
286 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
290 if (!NT_SUCCESS(Status
))
291 RETURN( (DWORD
)FALSE
);
293 /* FIXME - check if process has WINSTA_READATTRIBUTES */
294 IntGetCursorLocation(WinSta
, &Pos
);
296 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
297 if(!NT_SUCCESS(Status
))
299 ObDereferenceObject(WinSta
);
300 SetLastNtError(Status
);
304 ObDereferenceObject(WinSta
);
306 RETURN( (DWORD
)TRUE
);
309 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
311 PWINDOW_OBJECT Window
;
314 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
319 Result
= (DWORD
)IntIsWindowInDestroy(Window
);
324 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
327 PW32PROCESS Process
= PsGetWin32Process();
331 Enable
= (BOOL
)(Param
!= 0);
335 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
339 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
348 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
349 RETURN( (DWORD
)IntMsqSetWakeMask(Param
));
351 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
352 RETURN( UserGetKeyboardType(Param
));
354 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
355 RETURN( (DWORD
)UserGetKeyboardLayout(Param
));
357 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
359 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
363 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_
);
380 PWINDOW_OBJECT Window
;
381 DECLARE_RETURN(DWORD
);
383 DPRINT("Enter NtUserCallTwoParam\n");
384 UserEnterExclusive();
388 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
390 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
));
392 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
394 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
));
396 case TWOPARAM_ROUTINE_GETDCCOLOR
:
398 RETURN( (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
));
400 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
404 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
405 if (!Window
) RETURN(ERROR
);
407 Ret
= (DWORD
)IntGetWindowRgnBox(Window
, &rcRect
);
408 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
409 if(!NT_SUCCESS(Status
))
411 SetLastNtError(Status
);
416 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
418 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
419 if (!Window
) RETURN(ERROR
);
421 RETURN( (DWORD
)IntGetWindowRgn(Window
, (HRGN
)Param2
));
423 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
426 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
432 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
433 MenuObject
->MenuInfo
.Height
= (int)Param2
;
436 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
437 IntReleaseMenuObject(MenuObject
);
440 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
443 SETMENUITEMRECT smir
;
444 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
448 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
450 IntReleaseMenuObject(MenuObject
);
454 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
456 IntReleaseMenuObject(MenuObject
);
460 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
462 PUSER_MESSAGE_QUEUE MsgQueue
= ((PW32THREAD
)PsGetCurrentThread()->Tcb
.Win32Thread
)->MessageQueue
;
465 RETURN( (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
));
468 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
472 case TWOPARAM_ROUTINE_UNKNOWN
:
476 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
478 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
479 if (!Window
) RETURN(0);
481 RETURN( (DWORD
)IntShowOwnedPopups(Window
, (BOOL
) Param2
));
484 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
486 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
487 PWINDOW_OBJECT Window
;
488 DPRINT1("ROS_SHOWWINDOW\n");
490 if (!(Window
= UserGetWindowObject((HWND
)Param1
)))
497 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
501 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
504 Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
506 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
509 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
513 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
515 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
517 RETURN( (DWORD
)FALSE
);
520 Window
->ContextHelpId
= Param2
;
522 RETURN( (DWORD
)TRUE
);
524 case TWOPARAM_ROUTINE_SETCARETPOS
:
525 RETURN( (DWORD
)co_IntSetCaretPos((int)Param1
, (int)Param2
));
527 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
532 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
539 * According to WINE, Windows' doesn't check the cbSize field
542 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
543 if(!NT_SUCCESS(Status
))
545 SetLastNtError(Status
);
549 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
551 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
556 if((Ret
= (DWORD
)IntGetWindowInfo(Window
, &wi
)))
558 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
559 if(!NT_SUCCESS(Status
))
561 SetLastNtError(Status
);
569 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
570 RETURN( (DWORD
)co_IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
));
572 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
583 /* FIXME - we should make use of SEH here... */
585 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
586 if(!NT_SUCCESS(Status
))
588 SetLastNtError(Status
);
592 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
595 INT
*Elements
= (INT
*)Buffer
;
596 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
598 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
599 if(NT_SUCCESS(Status
))
601 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
602 if(NT_SUCCESS(Status
))
604 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
607 SetLastNtError(Status
);
610 SetLastNtError(Status
);
619 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
620 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
621 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
632 /* FIXME - we should make use of SEH here... */
634 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
635 if(Buffer
.Pointer
!= NULL
)
639 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
640 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
642 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
643 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
645 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
646 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
655 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
656 if(!NT_SUCCESS(Status
))
658 SetLastNtError(Status
);
663 ExFreePool(Buffer
.Pointer
);
669 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
670 Routine
, Param1
, Param2
);
671 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
675 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_
);
691 PWINDOW_OBJECT Window
;
692 USER_REFERENCE_ENTRY Ref
;
693 DECLARE_RETURN(BOOLEAN
);
695 DPRINT("Enter NtUserCallHwndLock\n");
696 UserEnterExclusive();
698 if (!(Window
= UserGetWindowObject(hWnd
)))
702 UserRefObjectCo(Window
, &Ref
);
704 /* FIXME: Routine can be 0x53 - 0x5E */
707 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
708 co_WinPosArrangeIconicWindows(Window
);
711 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
714 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
716 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
))
719 if(!(Menu
= UserGetMenuObject((HMENU
) Window
->IDMenu
)))
722 Menu
->MenuInfo
.WndOwner
= hWnd
;
723 Menu
->MenuInfo
.Height
= 0;
725 co_WinPosSetWindowPos(Window
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
726 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
732 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
736 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
737 Ret
= co_IntSetForegroundWindow(Window
);
740 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
745 UserDerefObjectCo(Window
);
750 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
766 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
769 * Nothing too hard...validate the hWnd and save it in the Desktop Info
771 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
774 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
777 * Nothing too hard...validate the hWnd and save it in the Desktop Info
779 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
790 NtUserGetThreadState(
793 DECLARE_RETURN(DWORD
);
795 DPRINT("Enter NtUserGetThreadState\n");
801 RETURN( (DWORD
)IntGetThreadFocusWindow());
806 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
812 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
814 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
816 /* Firefox 1.0.7 depends on the lfHeight value being negative */
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
= ((PW32THREAD
)Thread
->Tcb
.Win32Thread
)->Desktop
;
1340 /* get the foreground thread */
1341 PW32THREAD W32Thread
= (PW32THREAD
)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_
);