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 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
= CsrNotify(&Request
);
94 if (! NT_SUCCESS(Status
))
96 DPRINT1("Failed to register logon process with CSRSS\n");
108 NtUserCallNoParam(DWORD Routine
)
114 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
115 W32kRegisterPrimitiveMessageQueue();
116 Result
= (DWORD
)TRUE
;
119 case NOPARAM_ROUTINE_DESTROY_CARET
:
120 Result
= (DWORD
)IntDestroyCaret(PsGetCurrentThread()->Tcb
.Win32Thread
);
123 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
124 Result
= (DWORD
)IntInitMessagePumpHook();
127 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
128 Result
= (DWORD
)IntUninitMessagePumpHook();
131 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
132 Result
= (DWORD
)MsqGetMessageExtraInfo();
135 case NOPARAM_ROUTINE_ANYPOPUP
:
136 Result
= (DWORD
)IntAnyPopup();
139 case NOPARAM_ROUTINE_CSRSS_INITIALIZED
:
140 Result
= (DWORD
)CsrInit();
143 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK
:
144 return (DWORD
)IntMsqClearWakeMask();
147 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine
);
148 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
165 case ONEPARAM_ROUTINE_GETMENU
:
167 PWINDOW_OBJECT WindowObject
;
170 WindowObject
= IntGetWindowObject((HWND
)Param
);
173 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
177 Result
= (DWORD
)WindowObject
->IDMenu
;
179 IntReleaseWindowObject(WindowObject
);
183 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
185 PWINDOW_OBJECT WindowObject
;
188 WindowObject
= IntGetWindowObject((HWND
)Param
);
191 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
194 Result
= WindowObject
->Unicode
;
195 IntReleaseWindowObject(WindowObject
);
199 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
200 return (DWORD
)IntWindowFromDC((HDC
)Param
);
202 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
204 PWINDOW_OBJECT WindowObject
;
207 WindowObject
= IntGetWindowObject((HWND
)Param
);
210 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
214 Result
= WindowObject
->ContextHelpId
;
216 IntReleaseWindowObject(WindowObject
);
220 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
222 PWINSTATION_OBJECT WinStaObject
;
226 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
230 if (!NT_SUCCESS(Status
))
234 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
237 ObDereferenceObject(WinStaObject
);
241 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
242 return (DWORD
)IntSwitchCaretShowing((PVOID
)Param
);
244 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
245 return (DWORD
)IntSetCaretBlinkTime((UINT
)Param
);
247 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
248 return (DWORD
)IntEnumClipboardFormats((UINT
)Param
);
250 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
252 PWINDOW_OBJECT WindowObject
;
255 if(!(WindowObject
= IntGetWindowObject((HWND
)Param
)))
257 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
261 Result
= (DWORD
)WindowObject
->Instance
;
262 IntReleaseWindowObject(WindowObject
);
266 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
267 return (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
);
269 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
271 PWINSTATION_OBJECT WinStaObject
;
277 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
281 if (!NT_SUCCESS(Status
))
284 /* FIXME - check if process has WINSTA_READATTRIBUTES */
285 IntGetCursorLocation(WinStaObject
, &Pos
);
287 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
288 if(!NT_SUCCESS(Status
))
290 ObDereferenceObject(WinStaObject
);
291 SetLastNtError(Status
);
295 ObDereferenceObject(WinStaObject
);
300 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
302 PWINDOW_OBJECT WindowObject
;
305 WindowObject
= IntGetWindowObject((HWND
)Param
);
308 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
312 Result
= (DWORD
)IntIsWindowInDestroy(WindowObject
);
314 IntReleaseWindowObject(WindowObject
);
318 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
321 PW32PROCESS Process
= PsGetWin32Process();
325 Enable
= (BOOL
)(Param
!= 0);
329 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
333 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
342 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
343 return (DWORD
)IntMsqSetWakeMask(Param
);
345 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
347 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
363 PWINDOW_OBJECT WindowObject
;
367 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
369 return (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
);
371 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
373 return (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
);
375 case TWOPARAM_ROUTINE_GETDCCOLOR
:
377 return (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
);
379 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
383 Ret
= (DWORD
)IntGetWindowRgnBox((HWND
)Param1
, &rcRect
);
384 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
385 if(!NT_SUCCESS(Status
))
387 SetLastNtError(Status
);
392 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
394 return (DWORD
)IntGetWindowRgn((HWND
)Param1
, (HRGN
)Param2
);
396 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
399 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
405 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
406 MenuObject
->MenuInfo
.Height
= (int)Param2
;
409 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
410 IntReleaseMenuObject(MenuObject
);
413 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
416 SETMENUITEMRECT smir
;
417 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
421 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
423 IntReleaseMenuObject(MenuObject
);
427 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
429 IntReleaseMenuObject(MenuObject
);
433 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
435 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Tcb
.Win32Thread
->MessageQueue
;
438 return (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
);
441 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
445 case TWOPARAM_ROUTINE_UNKNOWN
:
449 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
453 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
457 case TWOPARAM_ROUTINE_VALIDATERGN
:
458 return (DWORD
)NtUserValidateRgn((HWND
) Param1
, (HRGN
) Param2
);
460 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
461 WindowObject
= IntGetWindowObject((HWND
)Param1
);
464 SetLastWin32Error(ERROR_INVALID_HANDLE
);
468 WindowObject
->ContextHelpId
= Param2
;
470 IntReleaseWindowObject(WindowObject
);
473 case TWOPARAM_ROUTINE_SETCARETPOS
:
474 return (DWORD
)IntSetCaretPos((int)Param1
, (int)Param2
);
476 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
481 if(!(WindowObject
= IntGetWindowObject((HWND
)Param1
)))
483 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
489 * According to WINE, Windows' doesn't check the cbSize field
492 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
493 if(!NT_SUCCESS(Status
))
495 IntReleaseWindowObject(WindowObject
);
496 SetLastNtError(Status
);
500 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
502 IntReleaseWindowObject(WindowObject
);
503 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
508 if((Ret
= (DWORD
)IntGetWindowInfo(WindowObject
, &wi
)))
510 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
511 if(!NT_SUCCESS(Status
))
513 IntReleaseWindowObject(WindowObject
);
514 SetLastNtError(Status
);
519 IntReleaseWindowObject(WindowObject
);
523 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
524 return (DWORD
)IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
);
526 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
536 /* FIXME - we should make use of SEH here... */
538 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
539 if(!NT_SUCCESS(Status
))
541 SetLastNtError(Status
);
545 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
548 INT
*Elements
= (INT
*)Buffer
;
549 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
551 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
552 if(NT_SUCCESS(Status
))
554 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
555 if(NT_SUCCESS(Status
))
557 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
560 SetLastNtError(Status
);
563 SetLastNtError(Status
);
570 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
571 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
572 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
583 /* FIXME - we should make use of SEH here... */
585 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
586 if(Buffer
.Pointer
!= NULL
)
590 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
591 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
593 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
594 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
596 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
597 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
606 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
607 if(!NT_SUCCESS(Status
))
609 SetLastNtError(Status
);
614 ExFreePool(Buffer
.Pointer
);
621 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
622 Routine
, Param1
, Param2
);
623 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
637 PWINDOW_OBJECT Window
;
639 Window
= IntGetWindowObject(hWnd
);
642 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
646 /* FIXME: Routine can be 0x53 - 0x5E */
649 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
653 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
655 PMENU_OBJECT MenuObject
;
656 DPRINT1("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
658 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
)) break;
659 MenuObject
= IntGetMenuObject((HMENU
) Window
->IDMenu
);
660 if(MenuObject
== NULL
) break;
661 MenuObject
->MenuInfo
.WndOwner
= hWnd
;
662 MenuObject
->MenuInfo
.Height
= 0;
663 IntReleaseMenuObject(MenuObject
);
664 WinPosSetWindowPos(hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
665 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
670 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
674 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
675 Ret
= IntSetForegroundWindow(Window
);
678 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
683 IntReleaseWindowObject(Window
);
696 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
700 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
712 NtUserGetThreadState(
718 return (DWORD
)IntGetThreadFocusWindow();
724 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
726 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
728 static LOGFONTW DefaultFont
= {
729 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
730 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
731 L
"Bitstream Vera Sans"
734 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
736 QueryTable
[0].Name
= lpValueName
;
737 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
738 QueryTable
[0].EntryContext
= font
;
740 Status
= RtlQueryRegistryValues(
742 L
"Control Panel\\Desktop\\WindowMetrics",
747 if (!NT_SUCCESS(Status
))
749 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
754 IntSystemParametersInfo(
760 PWINSTATION_OBJECT WinStaObject
;
763 static BOOL bInitialized
= FALSE
;
764 static LOGFONTW IconFont
;
765 static NONCLIENTMETRICSW pMetrics
;
766 static BOOL GradientCaptions
= TRUE
;
767 static UINT FocusBorderHeight
= 1;
768 static UINT FocusBorderWidth
= 1;
772 ZeroMemory(&IconFont
, sizeof(LOGFONTW
));
773 ZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
775 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
776 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
777 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
778 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
779 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
780 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
782 pMetrics
.iBorderWidth
= 1;
783 pMetrics
.iScrollWidth
= NtUserGetSystemMetrics(SM_CXVSCROLL
);
784 pMetrics
.iScrollHeight
= NtUserGetSystemMetrics(SM_CYHSCROLL
);
785 pMetrics
.iCaptionWidth
= NtUserGetSystemMetrics(SM_CXSIZE
);
786 pMetrics
.iCaptionHeight
= NtUserGetSystemMetrics(SM_CYSIZE
);
787 pMetrics
.iSmCaptionWidth
= NtUserGetSystemMetrics(SM_CXSMSIZE
);
788 pMetrics
.iSmCaptionHeight
= NtUserGetSystemMetrics(SM_CYSMSIZE
);
789 pMetrics
.iMenuWidth
= NtUserGetSystemMetrics(SM_CXMENUSIZE
);
790 pMetrics
.iMenuHeight
= NtUserGetSystemMetrics(SM_CYMENUSIZE
);
791 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
798 case SPI_SETDOUBLECLKWIDTH
:
799 case SPI_SETDOUBLECLKHEIGHT
:
800 case SPI_SETDOUBLECLICKTIME
:
801 case SPI_SETDESKWALLPAPER
:
802 case SPI_GETDESKWALLPAPER
:
804 PSYSTEM_CURSORINFO CurInfo
;
806 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
810 if(!NT_SUCCESS(Status
))
812 SetLastNtError(Status
);
818 case SPI_SETDOUBLECLKWIDTH
:
819 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
820 /* FIXME limit the maximum value? */
821 CurInfo
->DblClickWidth
= uiParam
;
823 case SPI_SETDOUBLECLKHEIGHT
:
824 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
825 /* FIXME limit the maximum value? */
826 CurInfo
->DblClickHeight
= uiParam
;
828 case SPI_SETDOUBLECLICKTIME
:
829 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
830 /* FIXME limit the maximum time to 1000 ms? */
831 CurInfo
->DblClickSpeed
= uiParam
;
833 case SPI_SETDESKWALLPAPER
:
835 /* This function expects different parameters than the user mode version!
837 We let the user mode code load the bitmap, it passed the handle to
838 the bitmap. We'll change it's ownership to system and replace it with
839 the current wallpaper bitmap */
840 HBITMAP hOldBitmap
, hNewBitmap
;
843 hNewBitmap
= *(HBITMAP
*)pvParam
;
844 if(hNewBitmap
!= NULL
)
847 /* try to get the size of the wallpaper */
848 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
850 ObDereferenceObject(WinStaObject
);
853 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
854 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
856 BITMAPOBJ_UnlockBitmap(bmp
);
858 /* change the bitmap's ownership */
859 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
861 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
862 if(hOldBitmap
!= NULL
)
864 /* delete the old wallpaper */
865 NtGdiDeleteObject(hOldBitmap
);
869 case SPI_GETDESKWALLPAPER
:
870 /* This function expects different parameters than the user mode version!
872 We basically return the current wallpaper handle - if any. The user
873 mode version should load the string from the registry and return it
874 without calling this function */
876 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
880 /* FIXME save the value to the registry */
882 ObDereferenceObject(WinStaObject
);
885 case SPI_SETWORKAREA
:
888 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
892 /* FIXME - Set last error */
898 Desktop
->WorkArea
= *rc
;
902 case SPI_GETWORKAREA
:
904 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
908 /* FIXME - Set last error */
913 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
917 case SPI_SETGRADIENTCAPTIONS
:
919 GradientCaptions
= (pvParam
!= NULL
);
920 /* FIXME - should be checked if the color depth is higher than 8bpp? */
923 case SPI_GETGRADIENTCAPTIONS
:
926 BOOL Ret
= GradientCaptions
;
928 hDC
= IntGetScreenDC();
931 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
934 *((PBOOL
)pvParam
) = Ret
;
939 case SPI_SETFONTSMOOTHING
:
941 IntEnableFontRendering(uiParam
!= 0);
944 case SPI_GETFONTSMOOTHING
:
947 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
950 case SPI_GETICONTITLELOGFONT
:
953 *((LOGFONTW
*)pvParam
) = IconFont
;
956 case SPI_GETNONCLIENTMETRICS
:
959 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
962 case SPI_GETFOCUSBORDERHEIGHT
:
965 *((UINT
*)pvParam
) = FocusBorderHeight
;
968 case SPI_GETFOCUSBORDERWIDTH
:
971 *((UINT
*)pvParam
) = FocusBorderWidth
;
974 case SPI_SETFOCUSBORDERHEIGHT
:
976 FocusBorderHeight
= (UINT
)pvParam
;
979 case SPI_SETFOCUSBORDERWIDTH
:
981 FocusBorderWidth
= (UINT
)pvParam
;
987 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
988 uiAction
, uiParam
, pvParam
, fWinIni
);
1000 NtUserSystemParametersInfo(
1010 case SPI_SETDOUBLECLKWIDTH
:
1011 case SPI_SETDOUBLECLKHEIGHT
:
1012 case SPI_SETDOUBLECLICKTIME
:
1013 case SPI_SETGRADIENTCAPTIONS
:
1014 case SPI_SETFONTSMOOTHING
:
1015 case SPI_SETFOCUSBORDERHEIGHT
:
1016 case SPI_SETFOCUSBORDERWIDTH
:
1018 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1020 case SPI_SETWORKAREA
:
1023 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1024 if(!NT_SUCCESS(Status
))
1026 SetLastNtError(Status
);
1029 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
);
1031 case SPI_GETWORKAREA
:
1035 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1040 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1041 if(!NT_SUCCESS(Status
))
1043 SetLastNtError(Status
);
1048 case SPI_GETFONTSMOOTHING
:
1049 case SPI_GETGRADIENTCAPTIONS
:
1050 case SPI_GETFOCUSBORDERHEIGHT
:
1051 case SPI_GETFOCUSBORDERWIDTH
:
1055 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1060 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1061 if(!NT_SUCCESS(Status
))
1063 SetLastNtError(Status
);
1068 case SPI_SETDESKWALLPAPER
:
1070 /* !!! As opposed to the user mode version this version accepts a handle
1072 HBITMAP hbmWallpaper
;
1074 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1075 if(!NT_SUCCESS(Status
))
1077 SetLastNtError(Status
);
1080 return IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1082 case SPI_GETDESKWALLPAPER
:
1084 /* !!! As opposed to the user mode version this version returns a handle
1086 HBITMAP hbmWallpaper
;
1089 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1091 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1092 if(!NT_SUCCESS(Status
))
1094 SetLastNtError(Status
);
1099 case SPI_GETICONTITLELOGFONT
:
1103 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1108 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1109 if(!NT_SUCCESS(Status
))
1111 SetLastNtError(Status
);
1116 case SPI_GETNONCLIENTMETRICS
:
1118 NONCLIENTMETRICSW metrics
;
1120 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1121 if(!NT_SUCCESS(Status
))
1123 SetLastNtError(Status
);
1126 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1128 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1132 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1137 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1138 if(!NT_SUCCESS(Status
))
1140 SetLastNtError(Status
);
1151 NtUserGetDoubleClickTime(VOID
)
1155 PWINSTATION_OBJECT WinStaObject
;
1156 PSYSTEM_CURSORINFO CurInfo
;
1158 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1162 if (!NT_SUCCESS(Status
))
1163 return (DWORD
)FALSE
;
1165 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1166 Result
= CurInfo
->DblClickSpeed
;
1168 ObDereferenceObject(WinStaObject
);
1174 NtUserGetGUIThreadInfo(
1176 LPGUITHREADINFO lpgui
)
1179 PTHRDCARETINFO CaretInfo
;
1180 GUITHREADINFO SafeGui
;
1181 PDESKTOP_OBJECT Desktop
;
1182 PUSER_MESSAGE_QUEUE MsgQueue
;
1183 PETHREAD Thread
= NULL
;
1185 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1186 if(!NT_SUCCESS(Status
))
1188 SetLastNtError(Status
);
1192 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1194 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1200 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1201 if(!NT_SUCCESS(Status
))
1203 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1206 Desktop
= Thread
->Tcb
.Win32Thread
->Desktop
;
1210 /* get the foreground thread */
1211 PW32THREAD W32Thread
= PsGetCurrentThread()->Tcb
.Win32Thread
;
1212 Desktop
= W32Thread
->Desktop
;
1215 MsgQueue
= Desktop
->ActiveMessageQueue
;
1218 Thread
= MsgQueue
->Thread
;
1223 if(!Thread
|| !Desktop
)
1225 if(idThread
&& Thread
)
1226 ObDereferenceObject(Thread
);
1227 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1231 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1232 CaretInfo
= MsgQueue
->CaretInfo
;
1234 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1235 if(MsgQueue
->MenuOwner
)
1236 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1237 if(MsgQueue
->MoveSize
)
1238 SafeGui
.flags
|= GUI_INMOVESIZE
;
1240 /* FIXME add flag GUI_16BITTASK */
1242 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1243 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1244 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1245 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1246 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1247 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1249 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1250 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1251 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1252 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1255 ObDereferenceObject(Thread
);
1257 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1258 if(!NT_SUCCESS(Status
))
1260 SetLastNtError(Status
);
1270 NtUserGetGuiResources(
1275 PW32PROCESS W32Process
;
1279 Status
= ObReferenceObjectByHandle(hProcess
,
1280 PROCESS_QUERY_INFORMATION
,
1282 ExGetPreviousMode(),
1286 if(!NT_SUCCESS(Status
))
1288 SetLastNtError(Status
);
1292 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1295 ObDereferenceObject(Process
);
1296 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1304 Ret
= (DWORD
)W32Process
->GDIObjects
;
1307 case GR_USEROBJECTS
:
1309 Ret
= (DWORD
)W32Process
->UserObjects
;
1314 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1319 ObDereferenceObject(Process
);
1325 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1326 PUNICODE_STRING Source
)
1331 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1332 if(!NT_SUCCESS(Status
))
1337 if(Dest
->Length
> 0x4000)
1339 return STATUS_UNSUCCESSFUL
;
1343 Dest
->Buffer
= NULL
;
1345 if(Dest
->Length
> 0 && Src
)
1347 Dest
->MaximumLength
= Dest
->Length
;
1348 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1351 return STATUS_NO_MEMORY
;
1354 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1355 if(!NT_SUCCESS(Status
))
1357 ExFreePool(Dest
->Buffer
);
1358 Dest
->Buffer
= NULL
;
1363 return STATUS_SUCCESS
;
1366 /* string is empty */
1367 return STATUS_SUCCESS
;
1371 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1372 PUNICODE_STRING Source
)
1377 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1378 if(!NT_SUCCESS(Status
))
1383 if(Dest
->Length
> 0x4000)
1385 return STATUS_UNSUCCESSFUL
;
1389 Dest
->Buffer
= NULL
;
1391 if(Dest
->Length
> 0 && Src
)
1393 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1394 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1397 return STATUS_NO_MEMORY
;
1400 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1401 if(!NT_SUCCESS(Status
))
1403 ExFreePool(Dest
->Buffer
);
1404 Dest
->Buffer
= NULL
;
1408 /* make sure the string is null-terminated */
1409 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1412 return STATUS_SUCCESS
;
1415 /* string is empty */
1416 return STATUS_SUCCESS
;
1420 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1422 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1423 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1425 /* The unicode_string is already nul terminated. Just reuse it. */
1426 *Dest
= Src
->Buffer
;
1427 return STATUS_SUCCESS
;
1430 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1433 return STATUS_NO_MEMORY
;
1435 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1436 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1438 return STATUS_SUCCESS
;
1442 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1444 if (NullTerminated
!= UnicodeString
->Buffer
)
1446 ExFreePool(NullTerminated
);
1451 NtUserUpdatePerUserSystemParameters(
1456 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);