3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * PURPOSE: Misc User funcs
6 * FILE: subsys/win32k/ntuser/misc.c
7 * PROGRAMER: Ge van Geldorp (ge@gse.nl)
17 /* registered Logon process */
18 PW32PROCESS LogonProcess
= NULL
;
20 VOID
W32kRegisterPrimitiveMessageQueue(VOID
)
22 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
23 if( !pmPrimitiveMessageQueue
) {
25 pThread
= PsGetWin32Thread();
26 if( pThread
&& pThread
->MessageQueue
) {
27 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
28 IntReferenceMessageQueue(pmPrimitiveMessageQueue
);
29 DPRINT( "Installed primitive input queue.\n" );
32 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
36 VOID
W32kUnregisterPrimitiveMessageQueue(VOID
)
38 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
39 IntDereferenceMessageQueue(pmPrimitiveMessageQueue
);
40 pmPrimitiveMessageQueue
= NULL
;
43 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue()
45 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
46 return pmPrimitiveMessageQueue
;
50 co_IntRegisterLogonProcess(HANDLE ProcessId
, BOOL Register
)
54 CSR_API_MESSAGE Request
;
56 Status
= PsLookupProcessByProcessId(ProcessId
,
58 if (!NT_SUCCESS(Status
))
60 SetLastWin32Error(RtlNtStatusToDosError(Status
));
66 /* Register the logon process */
67 if (LogonProcess
!= NULL
)
69 ObDereferenceObject(Process
);
73 LogonProcess
= (PW32PROCESS
)Process
->Win32Process
;
77 /* Deregister the logon process */
78 if (LogonProcess
!= (PW32PROCESS
)Process
->Win32Process
)
80 ObDereferenceObject(Process
);
87 ObDereferenceObject(Process
);
89 Request
.Type
= MAKE_CSR_API(REGISTER_LOGON_PROCESS
, CSR_GUI
);
90 Request
.Data
.RegisterLogonProcessRequest
.ProcessId
= ProcessId
;
91 Request
.Data
.RegisterLogonProcessRequest
.Register
= Register
;
93 Status
= co_CsrNotify(&Request
);
94 if (! NT_SUCCESS(Status
))
96 DPRINT1("Failed to register logon process with CSRSS\n");
108 NtUserCallNoParam(DWORD Routine
)
111 DECLARE_RETURN(DWORD
);
113 DPRINT("Enter NtUserCallNoParam\n");
114 UserEnterExclusive();
118 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
119 W32kRegisterPrimitiveMessageQueue();
120 Result
= (DWORD
)TRUE
;
123 case NOPARAM_ROUTINE_DESTROY_CARET
:
124 Result
= (DWORD
)co_IntDestroyCaret(PsGetCurrentThread()->Tcb
.Win32Thread
);
127 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
128 Result
= (DWORD
)IntInitMessagePumpHook();
131 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
132 Result
= (DWORD
)IntUninitMessagePumpHook();
135 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
136 Result
= (DWORD
)MsqGetMessageExtraInfo();
139 case NOPARAM_ROUTINE_ANYPOPUP
:
140 Result
= (DWORD
)IntAnyPopup();
143 case NOPARAM_ROUTINE_CSRSS_INITIALIZED
:
144 Result
= (DWORD
)CsrInit();
147 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK
:
148 RETURN( (DWORD
)IntMsqClearWakeMask());
151 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine
);
152 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
158 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_
);
172 DECLARE_RETURN(DWORD
);
174 DPRINT("Enter NtUserCallOneParam\n");
175 UserEnterExclusive();
179 case ONEPARAM_ROUTINE_GETMENU
:
181 PWINDOW_OBJECT WindowObject
;
184 WindowObject
= IntGetWindowObject((HWND
)Param
);
187 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
191 Result
= (DWORD
)WindowObject
->IDMenu
;
193 IntReleaseWindowObject(WindowObject
);
197 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
199 PWINDOW_OBJECT WindowObject
;
202 WindowObject
= IntGetWindowObject((HWND
)Param
);
205 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
208 Result
= WindowObject
->Unicode
;
209 IntReleaseWindowObject(WindowObject
);
213 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
214 RETURN( (DWORD
)IntWindowFromDC((HDC
)Param
));
216 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
218 PWINDOW_OBJECT WindowObject
;
221 WindowObject
= IntGetWindowObject((HWND
)Param
);
224 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
228 Result
= WindowObject
->ContextHelpId
;
230 IntReleaseWindowObject(WindowObject
);
234 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
236 PWINSTATION_OBJECT WinStaObject
;
240 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
244 if (!NT_SUCCESS(Status
))
245 RETURN( (DWORD
)FALSE
);
248 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
251 ObDereferenceObject(WinStaObject
);
255 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
256 RETURN( (DWORD
)IntSwitchCaretShowing((PVOID
)Param
));
258 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
259 RETURN( (DWORD
)IntSetCaretBlinkTime((UINT
)Param
));
261 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
262 RETURN( (DWORD
)IntEnumClipboardFormats((UINT
)Param
));
264 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
266 PWINDOW_OBJECT WindowObject
;
269 if(!(WindowObject
= IntGetWindowObject((HWND
)Param
)))
271 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
275 Result
= (DWORD
)WindowObject
->Instance
;
276 IntReleaseWindowObject(WindowObject
);
280 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
281 RETURN( (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
));
283 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
285 PWINSTATION_OBJECT WinStaObject
;
290 RETURN( (DWORD
)FALSE
);
291 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
295 if (!NT_SUCCESS(Status
))
296 RETURN( (DWORD
)FALSE
);
298 /* FIXME - check if process has WINSTA_READATTRIBUTES */
299 IntGetCursorLocation(WinStaObject
, &Pos
);
301 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
302 if(!NT_SUCCESS(Status
))
304 ObDereferenceObject(WinStaObject
);
305 SetLastNtError(Status
);
309 ObDereferenceObject(WinStaObject
);
311 RETURN( (DWORD
)TRUE
);
314 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
316 PWINDOW_OBJECT WindowObject
;
319 WindowObject
= IntGetWindowObject((HWND
)Param
);
322 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
326 Result
= (DWORD
)IntIsWindowInDestroy(WindowObject
);
328 IntReleaseWindowObject(WindowObject
);
332 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
335 PW32PROCESS Process
= PsGetWin32Process();
339 Enable
= (BOOL
)(Param
!= 0);
343 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
347 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
356 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
357 RETURN( (DWORD
)IntMsqSetWakeMask(Param
));
359 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
360 RETURN( UserGetKeyboardType(Param
));
362 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
363 RETURN( (DWORD
)UserGetKeyboardLayout(Param
));
365 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
367 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
371 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_
);
388 PWINDOW_OBJECT WindowObject
;
389 DECLARE_RETURN(DWORD
);
391 DPRINT("Enter NtUserCallTwoParam\n");
392 UserEnterExclusive();
396 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
398 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
));
400 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
402 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
));
404 case TWOPARAM_ROUTINE_GETDCCOLOR
:
406 RETURN( (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
));
408 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
412 Ret
= (DWORD
)IntGetWindowRgnBox((HWND
)Param1
, &rcRect
);
413 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
414 if(!NT_SUCCESS(Status
))
416 SetLastNtError(Status
);
421 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
423 RETURN( (DWORD
)IntGetWindowRgn((HWND
)Param1
, (HRGN
)Param2
));
425 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
428 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
434 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
435 MenuObject
->MenuInfo
.Height
= (int)Param2
;
438 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
439 IntReleaseMenuObject(MenuObject
);
442 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
445 SETMENUITEMRECT smir
;
446 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
450 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
452 IntReleaseMenuObject(MenuObject
);
456 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
458 IntReleaseMenuObject(MenuObject
);
462 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
464 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Tcb
.Win32Thread
->MessageQueue
;
467 RETURN( (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
));
470 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
474 case TWOPARAM_ROUTINE_UNKNOWN
:
478 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
479 RETURN( (DWORD
)IntShowOwnedPopups((HWND
) Param1
, (BOOL
) Param2
));
481 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
483 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
484 PWINDOW_OBJECT Window
= IntGetWindowObject((HWND
)Param1
);
485 DPRINT1("ROS_SHOWWINDOW\n");
488 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
493 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
495 IntReleaseWindowObject(Window
);
498 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
500 else Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
501 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
502 IntReleaseWindowObject(Window
);
505 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
509 case TWOPARAM_ROUTINE_VALIDATERGN
:
511 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
) Param1
);
514 if (!Window
) RETURN(FALSE
);
516 UserRefObjectCo(Window
);
517 ret
= co_UserValidateRgn(Window
, (HRGN
) Param2
);
518 UserDerefObjectCo(Window
);
523 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
524 WindowObject
= IntGetWindowObject((HWND
)Param1
);
527 SetLastWin32Error(ERROR_INVALID_HANDLE
);
528 RETURN( (DWORD
)FALSE
);
531 WindowObject
->ContextHelpId
= Param2
;
533 IntReleaseWindowObject(WindowObject
);
534 RETURN( (DWORD
)TRUE
);
536 case TWOPARAM_ROUTINE_SETCARETPOS
:
537 RETURN( (DWORD
)co_IntSetCaretPos((int)Param1
, (int)Param2
));
539 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
544 if(!(WindowObject
= IntGetWindowObject((HWND
)Param1
)))
546 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
552 * According to WINE, Windows' doesn't check the cbSize field
555 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
556 if(!NT_SUCCESS(Status
))
558 IntReleaseWindowObject(WindowObject
);
559 SetLastNtError(Status
);
563 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
565 IntReleaseWindowObject(WindowObject
);
566 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
571 if((Ret
= (DWORD
)IntGetWindowInfo(WindowObject
, &wi
)))
573 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
574 if(!NT_SUCCESS(Status
))
576 IntReleaseWindowObject(WindowObject
);
577 SetLastNtError(Status
);
582 IntReleaseWindowObject(WindowObject
);
586 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
587 RETURN( (DWORD
)co_IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
));
589 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
599 /* FIXME - we should make use of SEH here... */
601 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
602 if(!NT_SUCCESS(Status
))
604 SetLastNtError(Status
);
608 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
611 INT
*Elements
= (INT
*)Buffer
;
612 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
614 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
615 if(NT_SUCCESS(Status
))
617 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
618 if(NT_SUCCESS(Status
))
620 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
623 SetLastNtError(Status
);
626 SetLastNtError(Status
);
635 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
636 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
637 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
648 /* FIXME - we should make use of SEH here... */
650 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
651 if(Buffer
.Pointer
!= NULL
)
655 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
656 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
658 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
659 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
661 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
662 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
671 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
672 if(!NT_SUCCESS(Status
))
674 SetLastNtError(Status
);
679 ExFreePool(Buffer
.Pointer
);
685 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
686 Routine
, Param1
, Param2
);
687 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
691 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_
);
707 PWINDOW_OBJECT Window
;
708 DECLARE_RETURN(BOOLEAN
);
710 DPRINT("Enter NtUserCallHwndLock\n");
711 UserEnterExclusive();
713 Window
= IntGetWindowObject(hWnd
);
716 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
720 /* FIXME: Routine can be 0x53 - 0x5E */
723 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
724 co_WinPosArrangeIconicWindows(Window
);
727 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
729 PMENU_OBJECT MenuObject
;
730 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
732 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
)) break;
733 MenuObject
= IntGetMenuObject((HMENU
) Window
->IDMenu
);
734 if(MenuObject
== NULL
) break;
735 MenuObject
->MenuInfo
.WndOwner
= hWnd
;
736 MenuObject
->MenuInfo
.Height
= 0;
737 IntReleaseMenuObject(MenuObject
);
738 co_WinPosSetWindowPos(Window
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
739 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
744 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
748 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
749 Ret
= co_IntSetForegroundWindow(Window
);
752 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
757 IntReleaseWindowObject(Window
);
762 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
778 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
781 * Nothing too hard...validate the hWnd and save it in the Desktop Info
783 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
786 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
789 * Nothing too hard...validate the hWnd and save it in the Desktop Info
791 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
802 NtUserGetThreadState(
805 DECLARE_RETURN(DWORD
);
807 DPRINT("Enter NtUserGetThreadState\n");
813 RETURN( (DWORD
)IntGetThreadFocusWindow());
818 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
824 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
826 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
828 static LOGFONTW DefaultFont
= {
829 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
830 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
831 L
"Bitstream Vera Sans"
834 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
836 QueryTable
[0].Name
= lpValueName
;
837 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
838 QueryTable
[0].EntryContext
= font
;
840 Status
= RtlQueryRegistryValues(
842 L
"Control Panel\\Desktop\\WindowMetrics",
847 if (!NT_SUCCESS(Status
))
849 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
854 IntSystemParametersInfo(
860 PWINSTATION_OBJECT WinStaObject
;
863 static BOOL bInitialized
= FALSE
;
864 static LOGFONTW IconFont
;
865 static NONCLIENTMETRICSW pMetrics
;
866 static BOOL GradientCaptions
= TRUE
;
867 static UINT FocusBorderHeight
= 1;
868 static UINT FocusBorderWidth
= 1;
872 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
873 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
875 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
876 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
877 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
878 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
879 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
880 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
882 pMetrics
.iBorderWidth
= 1;
883 pMetrics
.iScrollWidth
= UserGetSystemMetrics(SM_CXVSCROLL
);
884 pMetrics
.iScrollHeight
= UserGetSystemMetrics(SM_CYHSCROLL
);
885 pMetrics
.iCaptionWidth
= UserGetSystemMetrics(SM_CXSIZE
);
886 pMetrics
.iCaptionHeight
= UserGetSystemMetrics(SM_CYSIZE
);
887 pMetrics
.iSmCaptionWidth
= UserGetSystemMetrics(SM_CXSMSIZE
);
888 pMetrics
.iSmCaptionHeight
= UserGetSystemMetrics(SM_CYSMSIZE
);
889 pMetrics
.iMenuWidth
= UserGetSystemMetrics(SM_CXMENUSIZE
);
890 pMetrics
.iMenuHeight
= UserGetSystemMetrics(SM_CYMENUSIZE
);
891 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
898 case SPI_SETDOUBLECLKWIDTH
:
899 case SPI_SETDOUBLECLKHEIGHT
:
900 case SPI_SETDOUBLECLICKTIME
:
901 case SPI_SETDESKWALLPAPER
:
902 case SPI_GETDESKWALLPAPER
:
904 PSYSTEM_CURSORINFO CurInfo
;
906 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
910 if(!NT_SUCCESS(Status
))
912 SetLastNtError(Status
);
918 case SPI_SETDOUBLECLKWIDTH
:
919 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
920 /* FIXME limit the maximum value? */
921 CurInfo
->DblClickWidth
= uiParam
;
923 case SPI_SETDOUBLECLKHEIGHT
:
924 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
925 /* FIXME limit the maximum value? */
926 CurInfo
->DblClickHeight
= uiParam
;
928 case SPI_SETDOUBLECLICKTIME
:
929 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
930 /* FIXME limit the maximum time to 1000 ms? */
931 CurInfo
->DblClickSpeed
= uiParam
;
933 case SPI_SETDESKWALLPAPER
:
935 /* This function expects different parameters than the user mode version!
937 We let the user mode code load the bitmap, it passed the handle to
938 the bitmap. We'll change it's ownership to system and replace it with
939 the current wallpaper bitmap */
940 HBITMAP hOldBitmap
, hNewBitmap
;
943 hNewBitmap
= *(HBITMAP
*)pvParam
;
944 if(hNewBitmap
!= NULL
)
947 /* try to get the size of the wallpaper */
948 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
950 ObDereferenceObject(WinStaObject
);
953 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
954 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
956 BITMAPOBJ_UnlockBitmap(bmp
);
958 /* change the bitmap's ownership */
959 GDIOBJ_SetOwnership(hNewBitmap
, NULL
);
961 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
962 if(hOldBitmap
!= NULL
)
964 /* delete the old wallpaper */
965 NtGdiDeleteObject(hOldBitmap
);
969 case SPI_GETDESKWALLPAPER
:
970 /* This function expects different parameters than the user mode version!
972 We basically return the current wallpaper handle - if any. The user
973 mode version should load the string from the registry and return it
974 without calling this function */
976 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
980 /* FIXME save the value to the registry */
982 ObDereferenceObject(WinStaObject
);
985 case SPI_SETWORKAREA
:
988 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
992 /* FIXME - Set last error */
998 Desktop
->WorkArea
= *rc
;
1002 case SPI_GETWORKAREA
:
1004 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
1008 /* FIXME - Set last error */
1013 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
1017 case SPI_SETGRADIENTCAPTIONS
:
1019 GradientCaptions
= (pvParam
!= NULL
);
1020 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1023 case SPI_GETGRADIENTCAPTIONS
:
1026 BOOL Ret
= GradientCaptions
;
1028 hDC
= IntGetScreenDC();
1031 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
1034 *((PBOOL
)pvParam
) = Ret
;
1039 case SPI_SETFONTSMOOTHING
:
1041 IntEnableFontRendering(uiParam
!= 0);
1044 case SPI_GETFONTSMOOTHING
:
1047 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
1050 case SPI_GETICONTITLELOGFONT
:
1053 *((LOGFONTW
*)pvParam
) = IconFont
;
1056 case SPI_GETNONCLIENTMETRICS
:
1059 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1062 case SPI_GETFOCUSBORDERHEIGHT
:
1065 *((UINT
*)pvParam
) = FocusBorderHeight
;
1068 case SPI_GETFOCUSBORDERWIDTH
:
1071 *((UINT
*)pvParam
) = FocusBorderWidth
;
1074 case SPI_SETFOCUSBORDERHEIGHT
:
1076 FocusBorderHeight
= (UINT
)pvParam
;
1079 case SPI_SETFOCUSBORDERWIDTH
:
1081 FocusBorderWidth
= (UINT
)pvParam
;
1087 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1088 uiAction
, uiParam
, pvParam
, fWinIni
);
1099 UserSystemParametersInfo(
1109 case SPI_SETDOUBLECLKWIDTH
:
1110 case SPI_SETDOUBLECLKHEIGHT
:
1111 case SPI_SETDOUBLECLICKTIME
:
1112 case SPI_SETGRADIENTCAPTIONS
:
1113 case SPI_SETFONTSMOOTHING
:
1114 case SPI_SETFOCUSBORDERHEIGHT
:
1115 case SPI_SETFOCUSBORDERWIDTH
:
1117 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1119 case SPI_SETWORKAREA
:
1122 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1123 if(!NT_SUCCESS(Status
))
1125 SetLastNtError(Status
);
1128 return( (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
));
1130 case SPI_GETWORKAREA
:
1134 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1139 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1140 if(!NT_SUCCESS(Status
))
1142 SetLastNtError(Status
);
1147 case SPI_GETFONTSMOOTHING
:
1148 case SPI_GETGRADIENTCAPTIONS
:
1149 case SPI_GETFOCUSBORDERHEIGHT
:
1150 case SPI_GETFOCUSBORDERWIDTH
:
1154 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1159 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1160 if(!NT_SUCCESS(Status
))
1162 SetLastNtError(Status
);
1167 case SPI_SETDESKWALLPAPER
:
1169 /* !!! As opposed to the user mode version this version accepts a handle
1171 HBITMAP hbmWallpaper
;
1173 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1174 if(!NT_SUCCESS(Status
))
1176 SetLastNtError(Status
);
1179 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
));
1181 case SPI_GETDESKWALLPAPER
:
1183 /* !!! As opposed to the user mode version this version returns a handle
1185 HBITMAP hbmWallpaper
;
1188 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1190 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1191 if(!NT_SUCCESS(Status
))
1193 SetLastNtError(Status
);
1198 case SPI_GETICONTITLELOGFONT
:
1202 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1207 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1208 if(!NT_SUCCESS(Status
))
1210 SetLastNtError(Status
);
1215 case SPI_GETNONCLIENTMETRICS
:
1217 NONCLIENTMETRICSW metrics
;
1219 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1220 if(!NT_SUCCESS(Status
))
1222 SetLastNtError(Status
);
1225 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1227 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1231 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1236 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1237 if(!NT_SUCCESS(Status
))
1239 SetLastNtError(Status
);
1256 NtUserSystemParametersInfo(
1262 DECLARE_RETURN(BOOLEAN
);
1264 DPRINT("Enter NtUserSystemParametersInfo\n");
1265 UserEnterExclusive();
1267 RETURN( UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
));
1270 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_
);
1279 NtUserGetDoubleClickTime(VOID
)
1283 PWINSTATION_OBJECT WinStaObject
;
1284 PSYSTEM_CURSORINFO CurInfo
;
1285 DECLARE_RETURN(UINT
);
1287 DPRINT("Enter NtUserGetDoubleClickTime\n");
1290 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1294 if (!NT_SUCCESS(Status
))
1295 RETURN( (DWORD
)FALSE
);
1297 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1298 Result
= CurInfo
->DblClickSpeed
;
1300 ObDereferenceObject(WinStaObject
);
1304 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_
);
1311 NtUserGetGUIThreadInfo(
1312 DWORD idThread
, /* if NULL use foreground thread */
1313 LPGUITHREADINFO lpgui
)
1316 PTHRDCARETINFO CaretInfo
;
1317 GUITHREADINFO SafeGui
;
1318 PDESKTOP_OBJECT Desktop
;
1319 PUSER_MESSAGE_QUEUE MsgQueue
;
1320 PETHREAD Thread
= NULL
;
1321 DECLARE_RETURN(BOOLEAN
);
1323 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1326 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1327 if(!NT_SUCCESS(Status
))
1329 SetLastNtError(Status
);
1333 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1335 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1341 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1342 if(!NT_SUCCESS(Status
))
1344 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1347 Desktop
= Thread
->Tcb
.Win32Thread
->Desktop
;
1351 /* get the foreground thread */
1352 PW32THREAD W32Thread
= PsGetCurrentThread()->Tcb
.Win32Thread
;
1353 Desktop
= W32Thread
->Desktop
;
1356 MsgQueue
= Desktop
->ActiveMessageQueue
;
1359 Thread
= MsgQueue
->Thread
;
1364 if(!Thread
|| !Desktop
)
1366 if(idThread
&& Thread
)
1367 ObDereferenceObject(Thread
);
1368 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1372 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1373 CaretInfo
= MsgQueue
->CaretInfo
;
1375 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1376 if(MsgQueue
->MenuOwner
)
1377 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1378 if(MsgQueue
->MoveSize
)
1379 SafeGui
.flags
|= GUI_INMOVESIZE
;
1381 /* FIXME add flag GUI_16BITTASK */
1383 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1384 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1385 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1386 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1387 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1388 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1390 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1391 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1392 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1393 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1396 ObDereferenceObject(Thread
);
1398 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1399 if(!NT_SUCCESS(Status
))
1401 SetLastNtError(Status
);
1408 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
1416 NtUserGetGuiResources(
1421 PW32PROCESS W32Process
;
1424 DECLARE_RETURN(DWORD
);
1426 DPRINT("Enter NtUserGetGuiResources\n");
1429 Status
= ObReferenceObjectByHandle(hProcess
,
1430 PROCESS_QUERY_INFORMATION
,
1432 ExGetPreviousMode(),
1436 if(!NT_SUCCESS(Status
))
1438 SetLastNtError(Status
);
1442 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1445 ObDereferenceObject(Process
);
1446 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1454 Ret
= (DWORD
)W32Process
->GDIObjects
;
1457 case GR_USEROBJECTS
:
1459 Ret
= (DWORD
)W32Process
->UserObjects
;
1464 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1469 ObDereferenceObject(Process
);
1474 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
1480 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1481 PUNICODE_STRING Source
)
1486 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1487 if(!NT_SUCCESS(Status
))
1492 if(Dest
->Length
> 0x4000)
1494 return STATUS_UNSUCCESSFUL
;
1498 Dest
->Buffer
= NULL
;
1500 if(Dest
->Length
> 0 && Src
)
1502 Dest
->MaximumLength
= Dest
->Length
;
1503 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1506 return STATUS_NO_MEMORY
;
1509 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1510 if(!NT_SUCCESS(Status
))
1512 ExFreePool(Dest
->Buffer
);
1513 Dest
->Buffer
= NULL
;
1518 return STATUS_SUCCESS
;
1521 /* string is empty */
1522 return STATUS_SUCCESS
;
1526 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1527 PUNICODE_STRING Source
)
1532 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1533 if(!NT_SUCCESS(Status
))
1538 if(Dest
->Length
> 0x4000)
1540 return STATUS_UNSUCCESSFUL
;
1544 Dest
->Buffer
= NULL
;
1546 if(Dest
->Length
> 0 && Src
)
1548 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1549 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1552 return STATUS_NO_MEMORY
;
1555 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1556 if(!NT_SUCCESS(Status
))
1558 ExFreePool(Dest
->Buffer
);
1559 Dest
->Buffer
= NULL
;
1563 /* make sure the string is null-terminated */
1564 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1567 return STATUS_SUCCESS
;
1570 /* string is empty */
1571 return STATUS_SUCCESS
;
1575 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1577 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1578 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1580 /* The unicode_string is already nul terminated. Just reuse it. */
1581 *Dest
= Src
->Buffer
;
1582 return STATUS_SUCCESS
;
1585 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1588 return STATUS_NO_MEMORY
;
1590 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1591 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1593 return STATUS_SUCCESS
;
1597 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1599 if (NullTerminated
!= UnicodeString
->Buffer
)
1601 ExFreePool(NullTerminated
);
1606 NtUserUpdatePerUserSystemParameters(
1611 DECLARE_RETURN(BOOLEAN
);
1613 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1614 UserEnterExclusive();
1616 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);
1620 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_
);