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 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
346 return NtUserGetKeyboardType(Param
);
348 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
349 return (DWORD
)NtUserGetKeyboardLayout(Param
);
351 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
353 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
369 PWINDOW_OBJECT WindowObject
;
373 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
375 return (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
);
377 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
379 return (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
);
381 case TWOPARAM_ROUTINE_GETDCCOLOR
:
383 return (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
);
385 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
389 Ret
= (DWORD
)IntGetWindowRgnBox((HWND
)Param1
, &rcRect
);
390 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
391 if(!NT_SUCCESS(Status
))
393 SetLastNtError(Status
);
398 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
400 return (DWORD
)IntGetWindowRgn((HWND
)Param1
, (HRGN
)Param2
);
402 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
405 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
411 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
412 MenuObject
->MenuInfo
.Height
= (int)Param2
;
415 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
416 IntReleaseMenuObject(MenuObject
);
419 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
422 SETMENUITEMRECT smir
;
423 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
427 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
429 IntReleaseMenuObject(MenuObject
);
433 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
435 IntReleaseMenuObject(MenuObject
);
439 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
441 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Tcb
.Win32Thread
->MessageQueue
;
444 return (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
);
447 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
451 case TWOPARAM_ROUTINE_UNKNOWN
:
455 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
456 return (DWORD
)IntShowOwnedPopups((HWND
) Param1
, (BOOL
) Param2
);
458 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
460 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
461 PWINDOW_OBJECT Window
= IntGetWindowObject((HWND
)Param1
);
462 DPRINT1("ROS_SHOWWINDOW\n");
465 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
470 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
472 IntReleaseWindowObject(Window
);
475 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
477 else Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
478 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
479 IntReleaseWindowObject(Window
);
482 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
486 case TWOPARAM_ROUTINE_VALIDATERGN
:
487 return (DWORD
)NtUserValidateRgn((HWND
) Param1
, (HRGN
) Param2
);
489 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
490 WindowObject
= IntGetWindowObject((HWND
)Param1
);
493 SetLastWin32Error(ERROR_INVALID_HANDLE
);
497 WindowObject
->ContextHelpId
= Param2
;
499 IntReleaseWindowObject(WindowObject
);
502 case TWOPARAM_ROUTINE_SETCARETPOS
:
503 return (DWORD
)IntSetCaretPos((int)Param1
, (int)Param2
);
505 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
510 if(!(WindowObject
= IntGetWindowObject((HWND
)Param1
)))
512 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
518 * According to WINE, Windows' doesn't check the cbSize field
521 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
522 if(!NT_SUCCESS(Status
))
524 IntReleaseWindowObject(WindowObject
);
525 SetLastNtError(Status
);
529 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
531 IntReleaseWindowObject(WindowObject
);
532 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
537 if((Ret
= (DWORD
)IntGetWindowInfo(WindowObject
, &wi
)))
539 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
540 if(!NT_SUCCESS(Status
))
542 IntReleaseWindowObject(WindowObject
);
543 SetLastNtError(Status
);
548 IntReleaseWindowObject(WindowObject
);
552 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
553 return (DWORD
)IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
);
555 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
565 /* FIXME - we should make use of SEH here... */
567 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
568 if(!NT_SUCCESS(Status
))
570 SetLastNtError(Status
);
574 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
577 INT
*Elements
= (INT
*)Buffer
;
578 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
580 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
581 if(NT_SUCCESS(Status
))
583 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
584 if(NT_SUCCESS(Status
))
586 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
589 SetLastNtError(Status
);
592 SetLastNtError(Status
);
601 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
602 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
603 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
614 /* FIXME - we should make use of SEH here... */
616 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
617 if(Buffer
.Pointer
!= NULL
)
621 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
622 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
624 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
625 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
627 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
628 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
637 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
638 if(!NT_SUCCESS(Status
))
640 SetLastNtError(Status
);
645 ExFreePool(Buffer
.Pointer
);
651 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
652 Routine
, Param1
, Param2
);
653 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
668 PWINDOW_OBJECT Window
;
670 Window
= IntGetWindowObject(hWnd
);
673 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
677 /* FIXME: Routine can be 0x53 - 0x5E */
680 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
681 WinPosArrangeIconicWindows(Window
);
684 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
686 PMENU_OBJECT MenuObject
;
687 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
689 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
)) break;
690 MenuObject
= IntGetMenuObject((HMENU
) Window
->IDMenu
);
691 if(MenuObject
== NULL
) break;
692 MenuObject
->MenuInfo
.WndOwner
= hWnd
;
693 MenuObject
->MenuInfo
.Height
= 0;
694 IntReleaseMenuObject(MenuObject
);
695 WinPosSetWindowPos(hWnd
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
696 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
701 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
705 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
706 Ret
= IntSetForegroundWindow(Window
);
709 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
714 IntReleaseWindowObject(Window
);
730 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
733 * Nothing too hard...validate the hWnd and save it in the Desktop Info
735 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
738 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
741 * Nothing too hard...validate the hWnd and save it in the Desktop Info
743 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
754 NtUserGetThreadState(
760 return (DWORD
)IntGetThreadFocusWindow();
766 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
768 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
770 static LOGFONTW DefaultFont
= {
771 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
772 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
773 L
"Bitstream Vera Sans"
776 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
778 QueryTable
[0].Name
= lpValueName
;
779 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
780 QueryTable
[0].EntryContext
= font
;
782 Status
= RtlQueryRegistryValues(
784 L
"Control Panel\\Desktop\\WindowMetrics",
789 if (!NT_SUCCESS(Status
))
791 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
796 IntSystemParametersInfo(
802 PWINSTATION_OBJECT WinStaObject
;
805 static BOOL bInitialized
= FALSE
;
806 static LOGFONTW IconFont
;
807 static NONCLIENTMETRICSW pMetrics
;
808 static BOOL GradientCaptions
= TRUE
;
809 static UINT FocusBorderHeight
= 1;
810 static UINT FocusBorderWidth
= 1;
814 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
815 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
817 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
818 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
819 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
820 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
821 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
822 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
824 pMetrics
.iBorderWidth
= 1;
825 pMetrics
.iScrollWidth
= NtUserGetSystemMetrics(SM_CXVSCROLL
);
826 pMetrics
.iScrollHeight
= NtUserGetSystemMetrics(SM_CYHSCROLL
);
827 pMetrics
.iCaptionWidth
= NtUserGetSystemMetrics(SM_CXSIZE
);
828 pMetrics
.iCaptionHeight
= NtUserGetSystemMetrics(SM_CYSIZE
);
829 pMetrics
.iSmCaptionWidth
= NtUserGetSystemMetrics(SM_CXSMSIZE
);
830 pMetrics
.iSmCaptionHeight
= NtUserGetSystemMetrics(SM_CYSMSIZE
);
831 pMetrics
.iMenuWidth
= NtUserGetSystemMetrics(SM_CXMENUSIZE
);
832 pMetrics
.iMenuHeight
= NtUserGetSystemMetrics(SM_CYMENUSIZE
);
833 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
840 case SPI_SETDOUBLECLKWIDTH
:
841 case SPI_SETDOUBLECLKHEIGHT
:
842 case SPI_SETDOUBLECLICKTIME
:
843 case SPI_SETDESKWALLPAPER
:
844 case SPI_GETDESKWALLPAPER
:
846 PSYSTEM_CURSORINFO CurInfo
;
848 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
852 if(!NT_SUCCESS(Status
))
854 SetLastNtError(Status
);
860 case SPI_SETDOUBLECLKWIDTH
:
861 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
862 /* FIXME limit the maximum value? */
863 CurInfo
->DblClickWidth
= uiParam
;
865 case SPI_SETDOUBLECLKHEIGHT
:
866 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
867 /* FIXME limit the maximum value? */
868 CurInfo
->DblClickHeight
= uiParam
;
870 case SPI_SETDOUBLECLICKTIME
:
871 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
872 /* FIXME limit the maximum time to 1000 ms? */
873 CurInfo
->DblClickSpeed
= uiParam
;
875 case SPI_SETDESKWALLPAPER
:
877 /* This function expects different parameters than the user mode version!
879 We let the user mode code load the bitmap, it passed the handle to
880 the bitmap. We'll change it's ownership to system and replace it with
881 the current wallpaper bitmap */
882 HBITMAP hOldBitmap
, hNewBitmap
;
885 hNewBitmap
= *(HBITMAP
*)pvParam
;
886 if(hNewBitmap
!= NULL
)
889 /* try to get the size of the wallpaper */
890 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
892 ObDereferenceObject(WinStaObject
);
895 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
896 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
898 BITMAPOBJ_UnlockBitmap(bmp
);
900 /* change the bitmap's ownership */
901 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
903 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
904 if(hOldBitmap
!= NULL
)
906 /* delete the old wallpaper */
907 NtGdiDeleteObject(hOldBitmap
);
911 case SPI_GETDESKWALLPAPER
:
912 /* This function expects different parameters than the user mode version!
914 We basically return the current wallpaper handle - if any. The user
915 mode version should load the string from the registry and return it
916 without calling this function */
918 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
922 /* FIXME save the value to the registry */
924 ObDereferenceObject(WinStaObject
);
927 case SPI_SETWORKAREA
:
930 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
934 /* FIXME - Set last error */
940 Desktop
->WorkArea
= *rc
;
944 case SPI_GETWORKAREA
:
946 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
950 /* FIXME - Set last error */
955 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
959 case SPI_SETGRADIENTCAPTIONS
:
961 GradientCaptions
= (pvParam
!= NULL
);
962 /* FIXME - should be checked if the color depth is higher than 8bpp? */
965 case SPI_GETGRADIENTCAPTIONS
:
968 BOOL Ret
= GradientCaptions
;
970 hDC
= IntGetScreenDC();
973 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
976 *((PBOOL
)pvParam
) = Ret
;
981 case SPI_SETFONTSMOOTHING
:
983 IntEnableFontRendering(uiParam
!= 0);
986 case SPI_GETFONTSMOOTHING
:
989 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
992 case SPI_GETICONTITLELOGFONT
:
995 *((LOGFONTW
*)pvParam
) = IconFont
;
998 case SPI_GETNONCLIENTMETRICS
:
1001 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1004 case SPI_GETFOCUSBORDERHEIGHT
:
1007 *((UINT
*)pvParam
) = FocusBorderHeight
;
1010 case SPI_GETFOCUSBORDERWIDTH
:
1013 *((UINT
*)pvParam
) = FocusBorderWidth
;
1016 case SPI_SETFOCUSBORDERHEIGHT
:
1018 FocusBorderHeight
= (UINT
)pvParam
;
1021 case SPI_SETFOCUSBORDERWIDTH
:
1023 FocusBorderWidth
= (UINT
)pvParam
;
1029 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1030 uiAction
, uiParam
, pvParam
, fWinIni
);
1042 NtUserSystemParametersInfo(
1052 case SPI_SETDOUBLECLKWIDTH
:
1053 case SPI_SETDOUBLECLKHEIGHT
:
1054 case SPI_SETDOUBLECLICKTIME
:
1055 case SPI_SETGRADIENTCAPTIONS
:
1056 case SPI_SETFONTSMOOTHING
:
1057 case SPI_SETFOCUSBORDERHEIGHT
:
1058 case SPI_SETFOCUSBORDERWIDTH
:
1060 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1062 case SPI_SETWORKAREA
:
1065 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1066 if(!NT_SUCCESS(Status
))
1068 SetLastNtError(Status
);
1071 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
);
1073 case SPI_GETWORKAREA
:
1077 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1082 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1083 if(!NT_SUCCESS(Status
))
1085 SetLastNtError(Status
);
1090 case SPI_GETFONTSMOOTHING
:
1091 case SPI_GETGRADIENTCAPTIONS
:
1092 case SPI_GETFOCUSBORDERHEIGHT
:
1093 case SPI_GETFOCUSBORDERWIDTH
:
1097 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1102 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1103 if(!NT_SUCCESS(Status
))
1105 SetLastNtError(Status
);
1110 case SPI_SETDESKWALLPAPER
:
1112 /* !!! As opposed to the user mode version this version accepts a handle
1114 HBITMAP hbmWallpaper
;
1116 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1117 if(!NT_SUCCESS(Status
))
1119 SetLastNtError(Status
);
1122 return IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1124 case SPI_GETDESKWALLPAPER
:
1126 /* !!! As opposed to the user mode version this version returns a handle
1128 HBITMAP hbmWallpaper
;
1131 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1133 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1134 if(!NT_SUCCESS(Status
))
1136 SetLastNtError(Status
);
1141 case SPI_GETICONTITLELOGFONT
:
1145 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1150 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1151 if(!NT_SUCCESS(Status
))
1153 SetLastNtError(Status
);
1158 case SPI_GETNONCLIENTMETRICS
:
1160 NONCLIENTMETRICSW metrics
;
1162 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1163 if(!NT_SUCCESS(Status
))
1165 SetLastNtError(Status
);
1168 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1170 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1174 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1179 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1180 if(!NT_SUCCESS(Status
))
1182 SetLastNtError(Status
);
1193 NtUserGetDoubleClickTime(VOID
)
1197 PWINSTATION_OBJECT WinStaObject
;
1198 PSYSTEM_CURSORINFO CurInfo
;
1200 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1204 if (!NT_SUCCESS(Status
))
1205 return (DWORD
)FALSE
;
1207 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1208 Result
= CurInfo
->DblClickSpeed
;
1210 ObDereferenceObject(WinStaObject
);
1216 NtUserGetGUIThreadInfo(
1218 LPGUITHREADINFO lpgui
)
1221 PTHRDCARETINFO CaretInfo
;
1222 GUITHREADINFO SafeGui
;
1223 PDESKTOP_OBJECT Desktop
;
1224 PUSER_MESSAGE_QUEUE MsgQueue
;
1225 PETHREAD Thread
= NULL
;
1227 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1228 if(!NT_SUCCESS(Status
))
1230 SetLastNtError(Status
);
1234 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1236 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1242 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1243 if(!NT_SUCCESS(Status
))
1245 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1248 Desktop
= Thread
->Tcb
.Win32Thread
->Desktop
;
1252 /* get the foreground thread */
1253 PW32THREAD W32Thread
= PsGetCurrentThread()->Tcb
.Win32Thread
;
1254 Desktop
= W32Thread
->Desktop
;
1257 MsgQueue
= Desktop
->ActiveMessageQueue
;
1260 Thread
= MsgQueue
->Thread
;
1265 if(!Thread
|| !Desktop
)
1267 if(idThread
&& Thread
)
1268 ObDereferenceObject(Thread
);
1269 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1273 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1274 CaretInfo
= MsgQueue
->CaretInfo
;
1276 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1277 if(MsgQueue
->MenuOwner
)
1278 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1279 if(MsgQueue
->MoveSize
)
1280 SafeGui
.flags
|= GUI_INMOVESIZE
;
1282 /* FIXME add flag GUI_16BITTASK */
1284 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1285 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1286 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1287 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1288 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1289 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1291 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1292 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1293 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1294 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1297 ObDereferenceObject(Thread
);
1299 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1300 if(!NT_SUCCESS(Status
))
1302 SetLastNtError(Status
);
1312 NtUserGetGuiResources(
1317 PW32PROCESS W32Process
;
1321 Status
= ObReferenceObjectByHandle(hProcess
,
1322 PROCESS_QUERY_INFORMATION
,
1324 ExGetPreviousMode(),
1328 if(!NT_SUCCESS(Status
))
1330 SetLastNtError(Status
);
1334 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1337 ObDereferenceObject(Process
);
1338 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1346 Ret
= (DWORD
)W32Process
->GDIObjects
;
1349 case GR_USEROBJECTS
:
1351 Ret
= (DWORD
)W32Process
->UserObjects
;
1356 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1361 ObDereferenceObject(Process
);
1367 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1368 PUNICODE_STRING Source
)
1373 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1374 if(!NT_SUCCESS(Status
))
1379 if(Dest
->Length
> 0x4000)
1381 return STATUS_UNSUCCESSFUL
;
1385 Dest
->Buffer
= NULL
;
1387 if(Dest
->Length
> 0 && Src
)
1389 Dest
->MaximumLength
= Dest
->Length
;
1390 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1393 return STATUS_NO_MEMORY
;
1396 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1397 if(!NT_SUCCESS(Status
))
1399 ExFreePool(Dest
->Buffer
);
1400 Dest
->Buffer
= NULL
;
1405 return STATUS_SUCCESS
;
1408 /* string is empty */
1409 return STATUS_SUCCESS
;
1413 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1414 PUNICODE_STRING Source
)
1419 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1420 if(!NT_SUCCESS(Status
))
1425 if(Dest
->Length
> 0x4000)
1427 return STATUS_UNSUCCESSFUL
;
1431 Dest
->Buffer
= NULL
;
1433 if(Dest
->Length
> 0 && Src
)
1435 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1436 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1439 return STATUS_NO_MEMORY
;
1442 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1443 if(!NT_SUCCESS(Status
))
1445 ExFreePool(Dest
->Buffer
);
1446 Dest
->Buffer
= NULL
;
1450 /* make sure the string is null-terminated */
1451 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1454 return STATUS_SUCCESS
;
1457 /* string is empty */
1458 return STATUS_SUCCESS
;
1462 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1464 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1465 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1467 /* The unicode_string is already nul terminated. Just reuse it. */
1468 *Dest
= Src
->Buffer
;
1469 return STATUS_SUCCESS
;
1472 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1475 return STATUS_NO_MEMORY
;
1477 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1478 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1480 return STATUS_SUCCESS
;
1484 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1486 if (NullTerminated
!= UnicodeString
->Buffer
)
1488 ExFreePool(NullTerminated
);
1493 NtUserUpdatePerUserSystemParameters(
1498 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);