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_
);
177 DECLARE_RETURN(DWORD
);
180 DPRINT("Enter NtUserCallOneParam\n");
183 if (Routine
== ONEPARAM_ROUTINE_SHOWCURSOR
)
185 PWINSTATION_OBJECT WinSta
= PsGetWin32Thread()->Desktop
->WindowStation
;
186 PSYSTEM_CURSORINFO CurInfo
;
191 BITMAPOBJ
*BitmapObj
;
196 if(!(Screen
= IntGetScreenDC()))
198 return showpointer
; /* No mouse */
201 dc
= DC_LockDc(Screen
);
205 return showpointer
; /* No mouse */
208 dcbmp
= dc
->w
.hBitmap
;
211 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
214 BITMAPOBJ_UnlockBitmap(BitmapObj
);
215 return showpointer
; /* No Mouse */
218 SurfObj
= &BitmapObj
->SurfObj
;
221 BITMAPOBJ_UnlockBitmap(BitmapObj
);
222 return showpointer
; /* No mouse */
225 ppdev
= GDIDEV(SurfObj
);
229 BITMAPOBJ_UnlockBitmap(BitmapObj
);
230 return showpointer
; /* No mouse */
233 pgp
= &ppdev
->Pointer
;
235 CurInfo
= IntGetSysCursorInfo(WinSta
);
240 showpointer
= pgp
->ShowPointer
;
242 if (showpointer
>= 0)
244 //ppdev->SafetyRemoveCount = 1;
245 //ppdev->SafetyRemoveLevel = 1;
246 EngMovePointer(SurfObj
,-1,-1,NULL
);
247 CurInfo
->ShowingCursor
= 0;
254 showpointer
= pgp
->ShowPointer
;
259 //ppdev->SafetyRemoveCount = 0;
260 //ppdev->SafetyRemoveLevel = 0;
261 EngMovePointer(SurfObj
,-1,-1,NULL
);
262 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
266 BITMAPOBJ_UnlockBitmap(BitmapObj
);
271 UserEnterExclusive();
275 case ONEPARAM_ROUTINE_GETMENU
:
277 PWINDOW_OBJECT Window
;
280 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
285 Result
= (DWORD
)Window
->IDMenu
;
290 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
292 PWINDOW_OBJECT Window
;
295 Window
= UserGetWindowObject((HWND
)Param
);
300 Result
= Window
->Unicode
;
304 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
305 RETURN( (DWORD
)IntWindowFromDC((HDC
)Param
));
307 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
309 PWINDOW_OBJECT Window
;
312 Window
= UserGetWindowObject((HWND
)Param
);
318 Result
= Window
->ContextHelpId
;
323 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
325 PWINSTATION_OBJECT WinSta
;
329 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
333 if (!NT_SUCCESS(Status
))
334 RETURN( (DWORD
)FALSE
);
337 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
340 ObDereferenceObject(WinSta
);
344 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
345 RETURN( (DWORD
)IntSwitchCaretShowing((PVOID
)Param
));
347 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
348 RETURN( (DWORD
)IntSetCaretBlinkTime((UINT
)Param
));
350 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
351 RETURN( (DWORD
)IntEnumClipboardFormats((UINT
)Param
));
353 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
355 PWINDOW_OBJECT Window
;
358 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
363 Result
= (DWORD
)Window
->Instance
;
367 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
368 RETURN( (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
));
370 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
372 PWINSTATION_OBJECT WinSta
;
377 RETURN( (DWORD
)FALSE
);
378 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
382 if (!NT_SUCCESS(Status
))
383 RETURN( (DWORD
)FALSE
);
385 /* FIXME - check if process has WINSTA_READATTRIBUTES */
386 IntGetCursorLocation(WinSta
, &Pos
);
388 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
389 if(!NT_SUCCESS(Status
))
391 ObDereferenceObject(WinSta
);
392 SetLastNtError(Status
);
396 ObDereferenceObject(WinSta
);
398 RETURN( (DWORD
)TRUE
);
401 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
403 PWINDOW_OBJECT Window
;
406 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
411 Result
= (DWORD
)IntIsWindowInDestroy(Window
);
416 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
419 PW32PROCESS Process
= PsGetWin32Process();
423 Enable
= (BOOL
)(Param
!= 0);
427 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
431 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
440 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
441 RETURN( (DWORD
)IntMsqSetWakeMask(Param
));
443 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
444 RETURN( UserGetKeyboardType(Param
));
446 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
447 RETURN( (DWORD
)UserGetKeyboardLayout(Param
));
449 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
451 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
455 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_
);
472 PWINDOW_OBJECT Window
;
473 DECLARE_RETURN(DWORD
);
475 DPRINT("Enter NtUserCallTwoParam\n");
476 UserEnterExclusive();
480 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
482 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
));
484 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
486 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
));
488 case TWOPARAM_ROUTINE_GETDCCOLOR
:
490 RETURN( (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
));
492 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
496 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
497 if (!Window
) RETURN(ERROR
);
499 Ret
= (DWORD
)IntGetWindowRgnBox(Window
, &rcRect
);
500 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
501 if(!NT_SUCCESS(Status
))
503 SetLastNtError(Status
);
508 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
510 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
511 if (!Window
) RETURN(ERROR
);
513 RETURN( (DWORD
)IntGetWindowRgn(Window
, (HRGN
)Param2
));
515 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
518 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
524 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
525 MenuObject
->MenuInfo
.Height
= (int)Param2
;
528 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
529 IntReleaseMenuObject(MenuObject
);
532 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
535 SETMENUITEMRECT smir
;
536 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
540 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
542 IntReleaseMenuObject(MenuObject
);
546 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
548 IntReleaseMenuObject(MenuObject
);
552 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
554 PUSER_MESSAGE_QUEUE MsgQueue
= ((PW32THREAD
)PsGetCurrentThread()->Tcb
.Win32Thread
)->MessageQueue
;
557 RETURN( (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
));
560 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
564 case TWOPARAM_ROUTINE_UNKNOWN
:
568 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
570 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
571 if (!Window
) RETURN(0);
573 RETURN( (DWORD
)IntShowOwnedPopups(Window
, (BOOL
) Param2
));
576 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
578 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
579 PWINDOW_OBJECT Window
;
580 DPRINT1("ROS_SHOWWINDOW\n");
582 if (!(Window
= UserGetWindowObject((HWND
)Param1
)))
589 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
593 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
596 Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
598 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
601 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
605 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
607 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
609 RETURN( (DWORD
)FALSE
);
612 Window
->ContextHelpId
= Param2
;
614 RETURN( (DWORD
)TRUE
);
616 case TWOPARAM_ROUTINE_SETCARETPOS
:
617 RETURN( (DWORD
)co_IntSetCaretPos((int)Param1
, (int)Param2
));
619 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
624 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
631 * According to WINE, Windows' doesn't check the cbSize field
634 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
635 if(!NT_SUCCESS(Status
))
637 SetLastNtError(Status
);
641 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
643 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
648 if((Ret
= (DWORD
)IntGetWindowInfo(Window
, &wi
)))
650 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
651 if(!NT_SUCCESS(Status
))
653 SetLastNtError(Status
);
661 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
662 RETURN( (DWORD
)co_IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
));
664 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
675 /* FIXME - we should make use of SEH here... */
677 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
678 if(!NT_SUCCESS(Status
))
680 SetLastNtError(Status
);
684 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
687 INT
*Elements
= (INT
*)Buffer
;
688 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
690 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
691 if(NT_SUCCESS(Status
))
693 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
694 if(NT_SUCCESS(Status
))
696 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
699 SetLastNtError(Status
);
702 SetLastNtError(Status
);
711 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
712 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
713 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
724 /* FIXME - we should make use of SEH here... */
726 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
727 if(Buffer
.Pointer
!= NULL
)
731 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
732 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
734 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
735 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
737 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
738 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
747 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
748 if(!NT_SUCCESS(Status
))
750 SetLastNtError(Status
);
755 ExFreePool(Buffer
.Pointer
);
761 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
762 Routine
, Param1
, Param2
);
763 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
767 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_
);
783 PWINDOW_OBJECT Window
;
784 USER_REFERENCE_ENTRY Ref
;
785 DECLARE_RETURN(BOOLEAN
);
787 DPRINT("Enter NtUserCallHwndLock\n");
788 UserEnterExclusive();
790 if (!(Window
= UserGetWindowObject(hWnd
)))
794 UserRefObjectCo(Window
, &Ref
);
796 /* FIXME: Routine can be 0x53 - 0x5E */
799 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
800 co_WinPosArrangeIconicWindows(Window
);
803 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
806 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
808 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
))
811 if(!(Menu
= UserGetMenuObject((HMENU
) Window
->IDMenu
)))
814 Menu
->MenuInfo
.WndOwner
= hWnd
;
815 Menu
->MenuInfo
.Height
= 0;
817 co_WinPosSetWindowPos(Window
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
818 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
824 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
828 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
829 Ret
= co_IntSetForegroundWindow(Window
);
832 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
837 UserDerefObjectCo(Window
);
842 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
858 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
861 * Nothing too hard...validate the hWnd and save it in the Desktop Info
863 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
866 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
869 * Nothing too hard...validate the hWnd and save it in the Desktop Info
871 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
882 NtUserGetThreadState(
885 DECLARE_RETURN(DWORD
);
887 DPRINT("Enter NtUserGetThreadState\n");
888 if (Routine
!= THREADSTATE_GETTHREADINFO
)
894 UserEnterExclusive();
899 case THREADSTATE_GETTHREADINFO
:
903 case THREADSTATE_FOCUSWINDOW
:
904 RETURN( (DWORD
)IntGetThreadFocusWindow());
909 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
915 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
917 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
919 /* Firefox 1.0.7 depends on the lfHeight value being negative */
920 static LOGFONTW DefaultFont
= {
921 -11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
922 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
923 L
"Bitstream Vera Sans"
926 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
928 QueryTable
[0].Name
= lpValueName
;
929 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
930 QueryTable
[0].EntryContext
= font
;
932 Status
= RtlQueryRegistryValues(
934 L
"Control Panel\\Desktop\\WindowMetrics",
939 if (!NT_SUCCESS(Status
))
941 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
946 IntSystemParametersInfo(
952 PWINSTATION_OBJECT WinStaObject
;
955 static BOOL bInitialized
= FALSE
;
956 static LOGFONTW IconFont
;
957 static NONCLIENTMETRICSW pMetrics
;
958 static BOOL GradientCaptions
= TRUE
;
959 static UINT FocusBorderHeight
= 1;
960 static UINT FocusBorderWidth
= 1;
964 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
965 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
967 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
968 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
969 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
970 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
971 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
972 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
974 pMetrics
.iBorderWidth
= 1;
975 pMetrics
.iScrollWidth
= UserGetSystemMetrics(SM_CXVSCROLL
);
976 pMetrics
.iScrollHeight
= UserGetSystemMetrics(SM_CYHSCROLL
);
977 pMetrics
.iCaptionWidth
= UserGetSystemMetrics(SM_CXSIZE
);
978 pMetrics
.iCaptionHeight
= UserGetSystemMetrics(SM_CYSIZE
);
979 pMetrics
.iSmCaptionWidth
= UserGetSystemMetrics(SM_CXSMSIZE
);
980 pMetrics
.iSmCaptionHeight
= UserGetSystemMetrics(SM_CYSMSIZE
);
981 pMetrics
.iMenuWidth
= UserGetSystemMetrics(SM_CXMENUSIZE
);
982 pMetrics
.iMenuHeight
= UserGetSystemMetrics(SM_CYMENUSIZE
);
983 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
990 case SPI_SETDOUBLECLKWIDTH
:
991 case SPI_SETDOUBLECLKHEIGHT
:
992 case SPI_SETDOUBLECLICKTIME
:
993 case SPI_SETDESKWALLPAPER
:
994 case SPI_GETDESKWALLPAPER
:
996 PSYSTEM_CURSORINFO CurInfo
;
998 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1002 if(!NT_SUCCESS(Status
))
1004 SetLastNtError(Status
);
1005 return (DWORD
)FALSE
;
1010 case SPI_SETDOUBLECLKWIDTH
:
1011 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1012 /* FIXME limit the maximum value? */
1013 CurInfo
->DblClickWidth
= uiParam
;
1015 case SPI_SETDOUBLECLKHEIGHT
:
1016 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1017 /* FIXME limit the maximum value? */
1018 CurInfo
->DblClickHeight
= uiParam
;
1020 case SPI_SETDOUBLECLICKTIME
:
1021 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1022 /* FIXME limit the maximum time to 1000 ms? */
1023 CurInfo
->DblClickSpeed
= uiParam
;
1025 case SPI_SETDESKWALLPAPER
:
1027 /* This function expects different parameters than the user mode version!
1029 We let the user mode code load the bitmap, it passed the handle to
1030 the bitmap. We'll change it's ownership to system and replace it with
1031 the current wallpaper bitmap */
1032 HBITMAP hOldBitmap
, hNewBitmap
;
1033 UNICODE_STRING Key
= RTL_CONSTANT_STRING(L
"Control Panel\\Desktop");
1034 UNICODE_STRING Tile
= RTL_CONSTANT_STRING(L
"TileWallpaper");
1035 UNICODE_STRING Style
= RTL_CONSTANT_STRING(L
"WallpaperStyle");
1036 UNICODE_STRING KeyPath
;
1037 OBJECT_ATTRIBUTES KeyAttributes
;
1038 OBJECT_ATTRIBUTES ObjectAttributes
;
1040 HANDLE CurrentUserKey
= NULL
;
1041 HANDLE KeyHandle
= NULL
;
1042 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
1044 ULONG ResLength
= 0;
1049 hNewBitmap
= *(HBITMAP
*)pvParam
;
1050 if(hNewBitmap
!= NULL
)
1053 /* try to get the size of the wallpaper */
1054 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
1056 ObDereferenceObject(WinStaObject
);
1059 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
1060 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
1062 BITMAPOBJ_UnlockBitmap(bmp
);
1064 /* change the bitmap's ownership */
1065 GDIOBJ_SetOwnership(GdiHandleTable
, hNewBitmap
, NULL
);
1067 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
1068 if(hOldBitmap
!= NULL
)
1070 /* delete the old wallpaper */
1071 NtGdiDeleteObject(hOldBitmap
);
1076 /*default value is center */
1077 WinStaObject
->WallpaperMode
= wmCenter
;
1081 /* Get a handle to the current users settings */
1082 RtlFormatCurrentUserKeyPath(&KeyPath
);
1083 InitializeObjectAttributes(&ObjectAttributes
,&KeyPath
,OBJ_CASE_INSENSITIVE
,NULL
,NULL
);
1084 ZwOpenKey(&CurrentUserKey
, KEY_READ
, &ObjectAttributes
);
1085 RtlFreeUnicodeString(&KeyPath
);
1087 /* open up the settings to read the values */
1088 InitializeObjectAttributes(&KeyAttributes
, &Key
, OBJ_CASE_INSENSITIVE
,
1089 CurrentUserKey
, NULL
);
1090 ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
1091 ZwClose(CurrentUserKey
);
1093 /* read the tile value in the registry */
1094 Status
= ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1097 /* fall back to .DEFAULT if we didnt find values */
1098 if(Status
== STATUS_INVALID_HANDLE
)
1100 RtlInitUnicodeString (&KeyPath
,L
"\\Registry\\User\\.Default\\Control Panel\\Desktop");
1101 InitializeObjectAttributes(&KeyAttributes
, &KeyPath
, OBJ_CASE_INSENSITIVE
,
1103 ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
1104 ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1108 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1109 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
1112 if(!KeyValuePartialInfo
)
1118 Status
= ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1119 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
1120 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
1123 ExFreePool(KeyValuePartialInfo
);
1127 Tile
.Length
= KeyValuePartialInfo
->DataLength
;
1128 Tile
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
1129 Tile
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
1131 Status
= RtlUnicodeStringToInteger(&Tile
, 0, &TileNum
);
1132 if(!NT_SUCCESS(Status
))
1136 ExFreePool(KeyValuePartialInfo
);
1138 /* start over again and look for the style*/
1140 Status
= ZwQueryValueKey(KeyHandle
, &Style
, KeyValuePartialInformation
,
1143 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1144 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
1147 if(!KeyValuePartialInfo
)
1153 Status
= ZwQueryValueKey(KeyHandle
, &Style
, KeyValuePartialInformation
,
1154 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
1155 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
1158 ExFreePool(KeyValuePartialInfo
);
1162 Style
.Length
= KeyValuePartialInfo
->DataLength
;
1163 Style
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
1164 Style
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
1166 Status
= RtlUnicodeStringToInteger(&Style
, 0, &StyleNum
);
1167 if(!NT_SUCCESS(Status
))
1171 ExFreePool(KeyValuePartialInfo
);
1173 /* Check the values we found in the registry */
1174 if(TileNum
&& !StyleNum
)
1176 WinStaObject
->WallpaperMode
= wmTile
;
1178 else if(!TileNum
&& StyleNum
== 2)
1180 WinStaObject
->WallpaperMode
= wmStretch
;
1186 case SPI_GETDESKWALLPAPER
:
1187 /* This function expects different parameters than the user mode version!
1189 We basically return the current wallpaper handle - if any. The user
1190 mode version should load the string from the registry and return it
1191 without calling this function */
1193 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
1197 /* FIXME save the value to the registry */
1199 ObDereferenceObject(WinStaObject
);
1202 case SPI_SETWORKAREA
:
1205 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
1209 /* FIXME - Set last error */
1214 rc
= (RECT
*)pvParam
;
1215 Desktop
->WorkArea
= *rc
;
1219 case SPI_GETWORKAREA
:
1221 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
1225 /* FIXME - Set last error */
1230 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
1234 case SPI_SETGRADIENTCAPTIONS
:
1236 GradientCaptions
= (pvParam
!= NULL
);
1237 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1240 case SPI_GETGRADIENTCAPTIONS
:
1243 BOOL Ret
= GradientCaptions
;
1245 hDC
= IntGetScreenDC();
1248 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
1251 *((PBOOL
)pvParam
) = Ret
;
1256 case SPI_SETFONTSMOOTHING
:
1258 IntEnableFontRendering(uiParam
!= 0);
1261 case SPI_GETFONTSMOOTHING
:
1264 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
1267 case SPI_GETICONTITLELOGFONT
:
1270 *((LOGFONTW
*)pvParam
) = IconFont
;
1273 case SPI_GETNONCLIENTMETRICS
:
1276 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1279 case SPI_GETFOCUSBORDERHEIGHT
:
1282 *((UINT
*)pvParam
) = FocusBorderHeight
;
1285 case SPI_GETFOCUSBORDERWIDTH
:
1288 *((UINT
*)pvParam
) = FocusBorderWidth
;
1291 case SPI_SETFOCUSBORDERHEIGHT
:
1293 FocusBorderHeight
= (UINT
)pvParam
;
1296 case SPI_SETFOCUSBORDERWIDTH
:
1298 FocusBorderWidth
= (UINT
)pvParam
;
1304 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1305 uiAction
, uiParam
, pvParam
, fWinIni
);
1316 UserSystemParametersInfo(
1326 case SPI_SETDOUBLECLKWIDTH
:
1327 case SPI_SETDOUBLECLKHEIGHT
:
1328 case SPI_SETDOUBLECLICKTIME
:
1329 case SPI_SETGRADIENTCAPTIONS
:
1330 case SPI_SETFONTSMOOTHING
:
1331 case SPI_SETFOCUSBORDERHEIGHT
:
1332 case SPI_SETFOCUSBORDERWIDTH
:
1334 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1336 case SPI_SETWORKAREA
:
1339 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1340 if(!NT_SUCCESS(Status
))
1342 SetLastNtError(Status
);
1345 return( (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
));
1347 case SPI_GETWORKAREA
:
1351 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1356 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1357 if(!NT_SUCCESS(Status
))
1359 SetLastNtError(Status
);
1364 case SPI_GETFONTSMOOTHING
:
1365 case SPI_GETGRADIENTCAPTIONS
:
1366 case SPI_GETFOCUSBORDERHEIGHT
:
1367 case SPI_GETFOCUSBORDERWIDTH
:
1371 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1376 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1377 if(!NT_SUCCESS(Status
))
1379 SetLastNtError(Status
);
1384 case SPI_SETDESKWALLPAPER
:
1386 /* !!! As opposed to the user mode version this version accepts a handle
1388 HBITMAP hbmWallpaper
;
1390 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1391 if(!NT_SUCCESS(Status
))
1393 SetLastNtError(Status
);
1396 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
));
1398 case SPI_GETDESKWALLPAPER
:
1400 /* !!! As opposed to the user mode version this version returns a handle
1402 HBITMAP hbmWallpaper
;
1405 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1407 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1408 if(!NT_SUCCESS(Status
))
1410 SetLastNtError(Status
);
1415 case SPI_GETICONTITLELOGFONT
:
1419 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1424 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1425 if(!NT_SUCCESS(Status
))
1427 SetLastNtError(Status
);
1432 case SPI_GETNONCLIENTMETRICS
:
1434 NONCLIENTMETRICSW metrics
;
1436 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1437 if(!NT_SUCCESS(Status
))
1439 SetLastNtError(Status
);
1442 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1444 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1448 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1453 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1454 if(!NT_SUCCESS(Status
))
1456 SetLastNtError(Status
);
1473 NtUserSystemParametersInfo(
1479 DECLARE_RETURN(BOOLEAN
);
1481 DPRINT("Enter NtUserSystemParametersInfo\n");
1482 UserEnterExclusive();
1484 RETURN( UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
));
1487 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_
);
1496 NtUserGetDoubleClickTime(VOID
)
1500 PWINSTATION_OBJECT WinStaObject
;
1501 PSYSTEM_CURSORINFO CurInfo
;
1502 DECLARE_RETURN(UINT
);
1504 DPRINT("Enter NtUserGetDoubleClickTime\n");
1507 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1511 if (!NT_SUCCESS(Status
))
1512 RETURN( (DWORD
)FALSE
);
1514 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1515 Result
= CurInfo
->DblClickSpeed
;
1517 ObDereferenceObject(WinStaObject
);
1521 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_
);
1528 NtUserGetGUIThreadInfo(
1529 DWORD idThread
, /* if NULL use foreground thread */
1530 LPGUITHREADINFO lpgui
)
1533 PTHRDCARETINFO CaretInfo
;
1534 GUITHREADINFO SafeGui
;
1535 PDESKTOP_OBJECT Desktop
;
1536 PUSER_MESSAGE_QUEUE MsgQueue
;
1537 PETHREAD Thread
= NULL
;
1538 DECLARE_RETURN(BOOLEAN
);
1540 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1543 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1544 if(!NT_SUCCESS(Status
))
1546 SetLastNtError(Status
);
1550 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1552 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1558 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1559 if(!NT_SUCCESS(Status
))
1561 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1564 Desktop
= ((PW32THREAD
)Thread
->Tcb
.Win32Thread
)->Desktop
;
1568 /* get the foreground thread */
1569 PW32THREAD W32Thread
= (PW32THREAD
)PsGetCurrentThread()->Tcb
.Win32Thread
;
1570 Desktop
= W32Thread
->Desktop
;
1573 MsgQueue
= Desktop
->ActiveMessageQueue
;
1576 Thread
= MsgQueue
->Thread
;
1581 if(!Thread
|| !Desktop
)
1583 if(idThread
&& Thread
)
1584 ObDereferenceObject(Thread
);
1585 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1589 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1590 CaretInfo
= MsgQueue
->CaretInfo
;
1592 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1593 if(MsgQueue
->MenuOwner
)
1594 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1595 if(MsgQueue
->MoveSize
)
1596 SafeGui
.flags
|= GUI_INMOVESIZE
;
1598 /* FIXME add flag GUI_16BITTASK */
1600 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1601 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1602 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1603 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1604 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1605 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1607 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1608 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1609 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1610 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1613 ObDereferenceObject(Thread
);
1615 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1616 if(!NT_SUCCESS(Status
))
1618 SetLastNtError(Status
);
1625 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
1633 NtUserGetGuiResources(
1638 PW32PROCESS W32Process
;
1641 DECLARE_RETURN(DWORD
);
1643 DPRINT("Enter NtUserGetGuiResources\n");
1646 Status
= ObReferenceObjectByHandle(hProcess
,
1647 PROCESS_QUERY_INFORMATION
,
1649 ExGetPreviousMode(),
1653 if(!NT_SUCCESS(Status
))
1655 SetLastNtError(Status
);
1659 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1662 ObDereferenceObject(Process
);
1663 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1671 Ret
= (DWORD
)W32Process
->GDIObjects
;
1674 case GR_USEROBJECTS
:
1676 Ret
= (DWORD
)W32Process
->UserObjects
;
1681 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1686 ObDereferenceObject(Process
);
1691 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
1697 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1698 PUNICODE_STRING Source
)
1703 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1704 if(!NT_SUCCESS(Status
))
1709 if(Dest
->Length
> 0x4000)
1711 return STATUS_UNSUCCESSFUL
;
1715 Dest
->Buffer
= NULL
;
1717 if(Dest
->Length
> 0 && Src
)
1719 Dest
->MaximumLength
= Dest
->Length
;
1720 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1723 return STATUS_NO_MEMORY
;
1726 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1727 if(!NT_SUCCESS(Status
))
1729 ExFreePool(Dest
->Buffer
);
1730 Dest
->Buffer
= NULL
;
1735 return STATUS_SUCCESS
;
1738 /* string is empty */
1739 return STATUS_SUCCESS
;
1743 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1744 PUNICODE_STRING Source
)
1749 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1750 if(!NT_SUCCESS(Status
))
1755 if(Dest
->Length
> 0x4000)
1757 return STATUS_UNSUCCESSFUL
;
1761 Dest
->Buffer
= NULL
;
1763 if(Dest
->Length
> 0 && Src
)
1765 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1766 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1769 return STATUS_NO_MEMORY
;
1772 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1773 if(!NT_SUCCESS(Status
))
1775 ExFreePool(Dest
->Buffer
);
1776 Dest
->Buffer
= NULL
;
1780 /* make sure the string is null-terminated */
1781 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1784 return STATUS_SUCCESS
;
1787 /* string is empty */
1788 return STATUS_SUCCESS
;
1792 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1794 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1795 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1797 /* The unicode_string is already nul terminated. Just reuse it. */
1798 *Dest
= Src
->Buffer
;
1799 return STATUS_SUCCESS
;
1802 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1805 return STATUS_NO_MEMORY
;
1807 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1808 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1810 return STATUS_SUCCESS
;
1814 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1816 if (NullTerminated
!= UnicodeString
->Buffer
)
1818 ExFreePool(NullTerminated
);
1823 NtUserUpdatePerUserSystemParameters(
1828 DECLARE_RETURN(BOOLEAN
);
1830 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1831 UserEnterExclusive();
1833 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);
1837 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_
);
1843 GetW32ProcessInfo(VOID
)
1846 PW32PROCESS W32Process
= PsGetWin32Process();
1848 if (W32Process
== NULL
)
1850 /* FIXME - temporary hack for system threads... */
1854 if (W32Process
->ProcessInfo
== NULL
)
1856 pi
= UserHeapAlloc(sizeof(W32PROCESSINFO
));
1860 sizeof(W32PROCESSINFO
));
1863 pi
->UserHandleTable
= gHandleTable
;
1865 if (InterlockedCompareExchangePointer(&W32Process
->ProcessInfo
,
1874 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1878 return W32Process
->ProcessInfo
;
1882 GetW32ThreadInfo(VOID
)
1886 PW32THREAD W32Thread
= PsGetWin32Thread();
1888 if (W32Thread
== NULL
)
1890 /* FIXME - temporary hack for system threads... */
1894 /* allocate a W32THREAD structure if neccessary */
1895 if (W32Thread
->ThreadInfo
== NULL
)
1897 ti
= UserHeapAlloc(sizeof(W32THREADINFO
));
1901 sizeof(W32THREADINFO
));
1904 ti
->kpi
= GetW32ProcessInfo();
1905 ti
->pi
= UserHeapAddressToUser(ti
->kpi
);
1906 if (W32Thread
->Desktop
!= NULL
)
1908 ti
->Desktop
= W32Thread
->Desktop
->DesktopInfo
;
1909 ti
->DesktopHeapDelta
= DesktopHeapGetUserDelta();
1914 ti
->DesktopHeapDelta
= 0;
1917 W32Thread
->ThreadInfo
= ti
;
1918 /* update the TEB */
1919 Teb
= NtCurrentTeb();
1926 Teb
->Win32ThreadInfo
= UserHeapAddressToUser(W32Thread
->ThreadInfo
);
1930 SetLastNtError(_SEH_GetExceptionCode());
1936 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1940 return W32Thread
->ThreadInfo
;