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
= 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 DECLARE_RETURN(BOOLEAN
);
694 DPRINT("Enter NtUserCallHwndLock\n");
695 UserEnterExclusive();
697 if (!(Window
= UserGetWindowObject(hWnd
)))
701 UserRefObjectCo(Window
);
703 /* FIXME: Routine can be 0x53 - 0x5E */
706 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
707 co_WinPosArrangeIconicWindows(Window
);
710 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
713 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
715 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
))
718 if(!(Menu
= UserGetMenuObject((HMENU
) Window
->IDMenu
)))
721 Menu
->MenuInfo
.WndOwner
= hWnd
;
722 Menu
->MenuInfo
.Height
= 0;
724 co_WinPosSetWindowPos(Window
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
725 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
731 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
735 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
736 Ret
= co_IntSetForegroundWindow(Window
);
739 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
744 UserDerefObjectCo(Window
);
749 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
765 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
768 * Nothing too hard...validate the hWnd and save it in the Desktop Info
770 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
773 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
776 * Nothing too hard...validate the hWnd and save it in the Desktop Info
778 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
789 NtUserGetThreadState(
792 DECLARE_RETURN(DWORD
);
794 DPRINT("Enter NtUserGetThreadState\n");
800 RETURN( (DWORD
)IntGetThreadFocusWindow());
805 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
811 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
813 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
815 static LOGFONTW DefaultFont
= {
816 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
817 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
818 L
"Bitstream Vera Sans"
821 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
823 QueryTable
[0].Name
= lpValueName
;
824 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
825 QueryTable
[0].EntryContext
= font
;
827 Status
= RtlQueryRegistryValues(
829 L
"Control Panel\\Desktop\\WindowMetrics",
834 if (!NT_SUCCESS(Status
))
836 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
841 IntSystemParametersInfo(
847 PWINSTATION_OBJECT WinStaObject
;
850 static BOOL bInitialized
= FALSE
;
851 static LOGFONTW IconFont
;
852 static NONCLIENTMETRICSW pMetrics
;
853 static BOOL GradientCaptions
= TRUE
;
854 static UINT FocusBorderHeight
= 1;
855 static UINT FocusBorderWidth
= 1;
859 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
860 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
862 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
863 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
864 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
865 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
866 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
867 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
869 pMetrics
.iBorderWidth
= 1;
870 pMetrics
.iScrollWidth
= UserGetSystemMetrics(SM_CXVSCROLL
);
871 pMetrics
.iScrollHeight
= UserGetSystemMetrics(SM_CYHSCROLL
);
872 pMetrics
.iCaptionWidth
= UserGetSystemMetrics(SM_CXSIZE
);
873 pMetrics
.iCaptionHeight
= UserGetSystemMetrics(SM_CYSIZE
);
874 pMetrics
.iSmCaptionWidth
= UserGetSystemMetrics(SM_CXSMSIZE
);
875 pMetrics
.iSmCaptionHeight
= UserGetSystemMetrics(SM_CYSMSIZE
);
876 pMetrics
.iMenuWidth
= UserGetSystemMetrics(SM_CXMENUSIZE
);
877 pMetrics
.iMenuHeight
= UserGetSystemMetrics(SM_CYMENUSIZE
);
878 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
885 case SPI_SETDOUBLECLKWIDTH
:
886 case SPI_SETDOUBLECLKHEIGHT
:
887 case SPI_SETDOUBLECLICKTIME
:
888 case SPI_SETDESKWALLPAPER
:
889 case SPI_GETDESKWALLPAPER
:
891 PSYSTEM_CURSORINFO CurInfo
;
893 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
897 if(!NT_SUCCESS(Status
))
899 SetLastNtError(Status
);
905 case SPI_SETDOUBLECLKWIDTH
:
906 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
907 /* FIXME limit the maximum value? */
908 CurInfo
->DblClickWidth
= uiParam
;
910 case SPI_SETDOUBLECLKHEIGHT
:
911 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
912 /* FIXME limit the maximum value? */
913 CurInfo
->DblClickHeight
= uiParam
;
915 case SPI_SETDOUBLECLICKTIME
:
916 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
917 /* FIXME limit the maximum time to 1000 ms? */
918 CurInfo
->DblClickSpeed
= uiParam
;
920 case SPI_SETDESKWALLPAPER
:
922 /* This function expects different parameters than the user mode version!
924 We let the user mode code load the bitmap, it passed the handle to
925 the bitmap. We'll change it's ownership to system and replace it with
926 the current wallpaper bitmap */
927 HBITMAP hOldBitmap
, hNewBitmap
;
930 hNewBitmap
= *(HBITMAP
*)pvParam
;
931 if(hNewBitmap
!= NULL
)
934 /* try to get the size of the wallpaper */
935 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
937 ObDereferenceObject(WinStaObject
);
940 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
941 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
943 BITMAPOBJ_UnlockBitmap(bmp
);
945 /* change the bitmap's ownership */
946 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
948 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
949 if(hOldBitmap
!= NULL
)
951 /* delete the old wallpaper */
952 NtGdiDeleteObject(hOldBitmap
);
956 case SPI_GETDESKWALLPAPER
:
957 /* This function expects different parameters than the user mode version!
959 We basically return the current wallpaper handle - if any. The user
960 mode version should load the string from the registry and return it
961 without calling this function */
963 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
967 /* FIXME save the value to the registry */
969 ObDereferenceObject(WinStaObject
);
972 case SPI_SETWORKAREA
:
975 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
979 /* FIXME - Set last error */
985 Desktop
->WorkArea
= *rc
;
989 case SPI_GETWORKAREA
:
991 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
995 /* FIXME - Set last error */
1000 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
1004 case SPI_SETGRADIENTCAPTIONS
:
1006 GradientCaptions
= (pvParam
!= NULL
);
1007 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1010 case SPI_GETGRADIENTCAPTIONS
:
1013 BOOL Ret
= GradientCaptions
;
1015 hDC
= IntGetScreenDC();
1018 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
1021 *((PBOOL
)pvParam
) = Ret
;
1026 case SPI_SETFONTSMOOTHING
:
1028 IntEnableFontRendering(uiParam
!= 0);
1031 case SPI_GETFONTSMOOTHING
:
1034 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
1037 case SPI_GETICONTITLELOGFONT
:
1040 *((LOGFONTW
*)pvParam
) = IconFont
;
1043 case SPI_GETNONCLIENTMETRICS
:
1046 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1049 case SPI_GETFOCUSBORDERHEIGHT
:
1052 *((UINT
*)pvParam
) = FocusBorderHeight
;
1055 case SPI_GETFOCUSBORDERWIDTH
:
1058 *((UINT
*)pvParam
) = FocusBorderWidth
;
1061 case SPI_SETFOCUSBORDERHEIGHT
:
1063 FocusBorderHeight
= (UINT
)pvParam
;
1066 case SPI_SETFOCUSBORDERWIDTH
:
1068 FocusBorderWidth
= (UINT
)pvParam
;
1074 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1075 uiAction
, uiParam
, pvParam
, fWinIni
);
1086 UserSystemParametersInfo(
1096 case SPI_SETDOUBLECLKWIDTH
:
1097 case SPI_SETDOUBLECLKHEIGHT
:
1098 case SPI_SETDOUBLECLICKTIME
:
1099 case SPI_SETGRADIENTCAPTIONS
:
1100 case SPI_SETFONTSMOOTHING
:
1101 case SPI_SETFOCUSBORDERHEIGHT
:
1102 case SPI_SETFOCUSBORDERWIDTH
:
1104 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1106 case SPI_SETWORKAREA
:
1109 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1110 if(!NT_SUCCESS(Status
))
1112 SetLastNtError(Status
);
1115 return( (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
));
1117 case SPI_GETWORKAREA
:
1121 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1126 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1127 if(!NT_SUCCESS(Status
))
1129 SetLastNtError(Status
);
1134 case SPI_GETFONTSMOOTHING
:
1135 case SPI_GETGRADIENTCAPTIONS
:
1136 case SPI_GETFOCUSBORDERHEIGHT
:
1137 case SPI_GETFOCUSBORDERWIDTH
:
1141 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1146 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1147 if(!NT_SUCCESS(Status
))
1149 SetLastNtError(Status
);
1154 case SPI_SETDESKWALLPAPER
:
1156 /* !!! As opposed to the user mode version this version accepts a handle
1158 HBITMAP hbmWallpaper
;
1160 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1161 if(!NT_SUCCESS(Status
))
1163 SetLastNtError(Status
);
1166 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
));
1168 case SPI_GETDESKWALLPAPER
:
1170 /* !!! As opposed to the user mode version this version returns a handle
1172 HBITMAP hbmWallpaper
;
1175 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1177 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1178 if(!NT_SUCCESS(Status
))
1180 SetLastNtError(Status
);
1185 case SPI_GETICONTITLELOGFONT
:
1189 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1194 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1195 if(!NT_SUCCESS(Status
))
1197 SetLastNtError(Status
);
1202 case SPI_GETNONCLIENTMETRICS
:
1204 NONCLIENTMETRICSW metrics
;
1206 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1207 if(!NT_SUCCESS(Status
))
1209 SetLastNtError(Status
);
1212 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1214 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1218 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1223 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1224 if(!NT_SUCCESS(Status
))
1226 SetLastNtError(Status
);
1243 NtUserSystemParametersInfo(
1249 DECLARE_RETURN(BOOLEAN
);
1251 DPRINT("Enter NtUserSystemParametersInfo\n");
1252 UserEnterExclusive();
1254 RETURN( UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
));
1257 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_
);
1266 NtUserGetDoubleClickTime(VOID
)
1270 PWINSTATION_OBJECT WinStaObject
;
1271 PSYSTEM_CURSORINFO CurInfo
;
1272 DECLARE_RETURN(UINT
);
1274 DPRINT("Enter NtUserGetDoubleClickTime\n");
1277 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1281 if (!NT_SUCCESS(Status
))
1282 RETURN( (DWORD
)FALSE
);
1284 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1285 Result
= CurInfo
->DblClickSpeed
;
1287 ObDereferenceObject(WinStaObject
);
1291 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_
);
1298 NtUserGetGUIThreadInfo(
1299 DWORD idThread
, /* if NULL use foreground thread */
1300 LPGUITHREADINFO lpgui
)
1303 PTHRDCARETINFO CaretInfo
;
1304 GUITHREADINFO SafeGui
;
1305 PDESKTOP_OBJECT Desktop
;
1306 PUSER_MESSAGE_QUEUE MsgQueue
;
1307 PETHREAD Thread
= NULL
;
1308 DECLARE_RETURN(BOOLEAN
);
1310 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1313 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1314 if(!NT_SUCCESS(Status
))
1316 SetLastNtError(Status
);
1320 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1322 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1328 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1329 if(!NT_SUCCESS(Status
))
1331 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1334 Desktop
= Thread
->Tcb
.Win32Thread
->Desktop
;
1338 /* get the foreground thread */
1339 PW32THREAD W32Thread
= PsGetCurrentThread()->Tcb
.Win32Thread
;
1340 Desktop
= W32Thread
->Desktop
;
1343 MsgQueue
= Desktop
->ActiveMessageQueue
;
1346 Thread
= MsgQueue
->Thread
;
1351 if(!Thread
|| !Desktop
)
1353 if(idThread
&& Thread
)
1354 ObDereferenceObject(Thread
);
1355 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1359 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1360 CaretInfo
= MsgQueue
->CaretInfo
;
1362 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1363 if(MsgQueue
->MenuOwner
)
1364 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1365 if(MsgQueue
->MoveSize
)
1366 SafeGui
.flags
|= GUI_INMOVESIZE
;
1368 /* FIXME add flag GUI_16BITTASK */
1370 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1371 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1372 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1373 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1374 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1375 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1377 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1378 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1379 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1380 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1383 ObDereferenceObject(Thread
);
1385 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1386 if(!NT_SUCCESS(Status
))
1388 SetLastNtError(Status
);
1395 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
1403 NtUserGetGuiResources(
1408 PW32PROCESS W32Process
;
1411 DECLARE_RETURN(DWORD
);
1413 DPRINT("Enter NtUserGetGuiResources\n");
1416 Status
= ObReferenceObjectByHandle(hProcess
,
1417 PROCESS_QUERY_INFORMATION
,
1419 ExGetPreviousMode(),
1423 if(!NT_SUCCESS(Status
))
1425 SetLastNtError(Status
);
1429 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1432 ObDereferenceObject(Process
);
1433 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1441 Ret
= (DWORD
)W32Process
->GDIObjects
;
1444 case GR_USEROBJECTS
:
1446 Ret
= (DWORD
)W32Process
->UserObjects
;
1451 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1456 ObDereferenceObject(Process
);
1461 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
1467 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1468 PUNICODE_STRING Source
)
1473 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1474 if(!NT_SUCCESS(Status
))
1479 if(Dest
->Length
> 0x4000)
1481 return STATUS_UNSUCCESSFUL
;
1485 Dest
->Buffer
= NULL
;
1487 if(Dest
->Length
> 0 && Src
)
1489 Dest
->MaximumLength
= Dest
->Length
;
1490 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1493 return STATUS_NO_MEMORY
;
1496 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1497 if(!NT_SUCCESS(Status
))
1499 ExFreePool(Dest
->Buffer
);
1500 Dest
->Buffer
= NULL
;
1505 return STATUS_SUCCESS
;
1508 /* string is empty */
1509 return STATUS_SUCCESS
;
1513 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1514 PUNICODE_STRING Source
)
1519 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1520 if(!NT_SUCCESS(Status
))
1525 if(Dest
->Length
> 0x4000)
1527 return STATUS_UNSUCCESSFUL
;
1531 Dest
->Buffer
= NULL
;
1533 if(Dest
->Length
> 0 && Src
)
1535 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1536 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1539 return STATUS_NO_MEMORY
;
1542 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1543 if(!NT_SUCCESS(Status
))
1545 ExFreePool(Dest
->Buffer
);
1546 Dest
->Buffer
= NULL
;
1550 /* make sure the string is null-terminated */
1551 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1554 return STATUS_SUCCESS
;
1557 /* string is empty */
1558 return STATUS_SUCCESS
;
1562 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1564 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1565 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1567 /* The unicode_string is already nul terminated. Just reuse it. */
1568 *Dest
= Src
->Buffer
;
1569 return STATUS_SUCCESS
;
1572 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1575 return STATUS_NO_MEMORY
;
1577 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1578 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1580 return STATUS_SUCCESS
;
1584 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1586 if (NullTerminated
!= UnicodeString
->Buffer
)
1588 ExFreePool(NullTerminated
);
1593 NtUserUpdatePerUserSystemParameters(
1598 DECLARE_RETURN(BOOLEAN
);
1600 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1601 UserEnterExclusive();
1603 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);
1607 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_
);