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)
18 /* registered Logon process */
19 PW32PROCESS LogonProcess
= NULL
;
21 VOID
W32kRegisterPrimitiveMessageQueue(VOID
)
23 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
24 if( !pmPrimitiveMessageQueue
)
27 pThread
= PsGetWin32Thread();
28 if( pThread
&& pThread
->MessageQueue
)
30 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
31 IntReferenceMessageQueue(pmPrimitiveMessageQueue
);
32 DPRINT( "Installed primitive input queue.\n" );
37 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
41 VOID
W32kUnregisterPrimitiveMessageQueue(VOID
)
43 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
44 IntDereferenceMessageQueue(pmPrimitiveMessageQueue
);
45 pmPrimitiveMessageQueue
= NULL
;
48 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue()
50 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
51 return pmPrimitiveMessageQueue
;
55 co_IntRegisterLogonProcess(HANDLE ProcessId
, BOOL Register
)
59 CSR_API_MESSAGE Request
;
61 Status
= PsLookupProcessByProcessId(ProcessId
,
63 if (!NT_SUCCESS(Status
))
65 SetLastWin32Error(RtlNtStatusToDosError(Status
));
71 /* Register the logon process */
72 if (LogonProcess
!= NULL
)
74 ObDereferenceObject(Process
);
78 LogonProcess
= (PW32PROCESS
)Process
->Win32Process
;
82 /* Deregister the logon process */
83 if (LogonProcess
!= (PW32PROCESS
)Process
->Win32Process
)
85 ObDereferenceObject(Process
);
92 ObDereferenceObject(Process
);
94 Request
.Type
= MAKE_CSR_API(REGISTER_LOGON_PROCESS
, CSR_GUI
);
95 Request
.Data
.RegisterLogonProcessRequest
.ProcessId
= ProcessId
;
96 Request
.Data
.RegisterLogonProcessRequest
.Register
= Register
;
98 Status
= co_CsrNotify(&Request
);
99 if (! NT_SUCCESS(Status
))
101 DPRINT1("Failed to register logon process with CSRSS\n");
113 NtUserCallNoParam(DWORD Routine
)
116 DECLARE_RETURN(DWORD
);
118 DPRINT("Enter NtUserCallNoParam\n");
119 UserEnterExclusive();
123 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
124 W32kRegisterPrimitiveMessageQueue();
125 Result
= (DWORD
)TRUE
;
128 case NOPARAM_ROUTINE_DESTROY_CARET
:
129 Result
= (DWORD
)co_IntDestroyCaret(PsGetCurrentThread()->Tcb
.Win32Thread
);
132 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
133 Result
= (DWORD
)IntInitMessagePumpHook();
136 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
137 Result
= (DWORD
)IntUninitMessagePumpHook();
140 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
141 Result
= (DWORD
)MsqGetMessageExtraInfo();
144 case NOPARAM_ROUTINE_ANYPOPUP
:
145 Result
= (DWORD
)IntAnyPopup();
148 case NOPARAM_ROUTINE_CSRSS_INITIALIZED
:
149 Result
= (DWORD
)CsrInit();
152 case NOPARAM_ROUTINE_MSQCLEARWAKEMASK
:
153 RETURN( (DWORD
)IntMsqClearWakeMask());
156 DPRINT1("Calling invalid routine number 0x%x in NtUserCallNoParam\n", Routine
);
157 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
163 DPRINT("Leave NtUserCallNoParam, ret=%i\n",_ret_
);
178 DECLARE_RETURN(DWORD
);
181 DPRINT("Enter NtUserCallOneParam\n");
184 if (Routine
== ONEPARAM_ROUTINE_SHOWCURSOR
)
186 PWINSTATION_OBJECT WinSta
= PsGetWin32Thread()->Desktop
->WindowStation
;
187 PSYSTEM_CURSORINFO CurInfo
;
192 BITMAPOBJ
*BitmapObj
;
197 if(!(Screen
= IntGetScreenDC()))
199 return showpointer
; /* No mouse */
202 dc
= DC_LockDc(Screen
);
206 return showpointer
; /* No mouse */
209 dcbmp
= dc
->w
.hBitmap
;
212 BitmapObj
= BITMAPOBJ_LockBitmap(dcbmp
);
215 BITMAPOBJ_UnlockBitmap(BitmapObj
);
216 return showpointer
; /* No Mouse */
219 SurfObj
= &BitmapObj
->SurfObj
;
222 BITMAPOBJ_UnlockBitmap(BitmapObj
);
223 return showpointer
; /* No mouse */
226 ppdev
= GDIDEV(SurfObj
);
230 BITMAPOBJ_UnlockBitmap(BitmapObj
);
231 return showpointer
; /* No mouse */
234 pgp
= &ppdev
->Pointer
;
236 CurInfo
= IntGetSysCursorInfo(WinSta
);
241 showpointer
= pgp
->ShowPointer
;
243 if (showpointer
>= 0)
245 //ppdev->SafetyRemoveCount = 1;
246 //ppdev->SafetyRemoveLevel = 1;
247 EngMovePointer(SurfObj
,-1,-1,NULL
);
248 CurInfo
->ShowingCursor
= 0;
255 showpointer
= pgp
->ShowPointer
;
260 //ppdev->SafetyRemoveCount = 0;
261 //ppdev->SafetyRemoveLevel = 0;
262 EngMovePointer(SurfObj
,-1,-1,NULL
);
263 CurInfo
->ShowingCursor
= CURSOR_SHOWING
;
267 BITMAPOBJ_UnlockBitmap(BitmapObj
);
272 UserEnterExclusive();
276 case ONEPARAM_ROUTINE_GETMENU
:
278 PWINDOW_OBJECT Window
;
281 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
286 Result
= (DWORD
)Window
->IDMenu
;
291 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
293 PWINDOW_OBJECT Window
;
296 Window
= UserGetWindowObject((HWND
)Param
);
301 Result
= Window
->Unicode
;
305 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
306 RETURN( (DWORD
)IntWindowFromDC((HDC
)Param
));
308 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
310 PWINDOW_OBJECT Window
;
313 Window
= UserGetWindowObject((HWND
)Param
);
319 Result
= Window
->ContextHelpId
;
324 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
326 PWINSTATION_OBJECT WinSta
;
330 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
334 if (!NT_SUCCESS(Status
))
335 RETURN( (DWORD
)FALSE
);
338 Result = (DWORD)IntSwapMouseButton(WinStaObject, (BOOL)Param); */
341 ObDereferenceObject(WinSta
);
345 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
346 RETURN( (DWORD
)IntSwitchCaretShowing((PVOID
)Param
));
348 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
349 RETURN( (DWORD
)IntSetCaretBlinkTime((UINT
)Param
));
351 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
352 RETURN( (DWORD
)IntEnumClipboardFormats((UINT
)Param
));
354 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
356 PWINDOW_OBJECT Window
;
359 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
364 Result
= (DWORD
)Window
->Instance
;
368 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
369 RETURN( (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
));
371 case ONEPARAM_ROUTINE_GETCURSORPOSITION
:
373 PWINSTATION_OBJECT WinSta
;
378 RETURN( (DWORD
)FALSE
);
379 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
383 if (!NT_SUCCESS(Status
))
384 RETURN( (DWORD
)FALSE
);
386 /* FIXME - check if process has WINSTA_READATTRIBUTES */
387 IntGetCursorLocation(WinSta
, &Pos
);
389 Status
= MmCopyToCaller((PPOINT
)Param
, &Pos
, sizeof(POINT
));
390 if(!NT_SUCCESS(Status
))
392 ObDereferenceObject(WinSta
);
393 SetLastNtError(Status
);
397 ObDereferenceObject(WinSta
);
399 RETURN( (DWORD
)TRUE
);
402 case ONEPARAM_ROUTINE_ISWINDOWINDESTROY
:
404 PWINDOW_OBJECT Window
;
407 if(!(Window
= UserGetWindowObject((HWND
)Param
)))
412 Result
= (DWORD
)IntIsWindowInDestroy(Window
);
417 case ONEPARAM_ROUTINE_ENABLEPROCWNDGHSTING
:
420 PW32PROCESS Process
= PsGetWin32Process();
424 Enable
= (BOOL
)(Param
!= 0);
428 Process
->Flags
&= ~W32PF_NOWINDOWGHOSTING
;
432 Process
->Flags
|= W32PF_NOWINDOWGHOSTING
;
441 case ONEPARAM_ROUTINE_MSQSETWAKEMASK
:
442 RETURN( (DWORD
)IntMsqSetWakeMask(Param
));
444 case ONEPARAM_ROUTINE_GETKEYBOARDTYPE
:
445 RETURN( UserGetKeyboardType(Param
));
447 case ONEPARAM_ROUTINE_GETKEYBOARDLAYOUT
:
448 RETURN( (DWORD
)UserGetKeyboardLayout(Param
));
450 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
452 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
456 DPRINT("Leave NtUserCallOneParam, ret=%i\n",_ret_
);
473 PWINDOW_OBJECT Window
;
474 DECLARE_RETURN(DWORD
);
476 DPRINT("Enter NtUserCallTwoParam\n");
477 UserEnterExclusive();
481 case TWOPARAM_ROUTINE_SETDCPENCOLOR
:
483 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_PEN
, (COLORREF
)Param2
));
485 case TWOPARAM_ROUTINE_SETDCBRUSHCOLOR
:
487 RETURN( (DWORD
)IntSetDCColor((HDC
)Param1
, OBJ_BRUSH
, (COLORREF
)Param2
));
489 case TWOPARAM_ROUTINE_GETDCCOLOR
:
491 RETURN( (DWORD
)IntGetDCColor((HDC
)Param1
, (ULONG
)Param2
));
493 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
497 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
498 if (!Window
) RETURN(ERROR
);
500 Ret
= (DWORD
)IntGetWindowRgnBox(Window
, &rcRect
);
501 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
502 if(!NT_SUCCESS(Status
))
504 SetLastNtError(Status
);
509 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
511 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
512 if (!Window
) RETURN(ERROR
);
514 RETURN( (DWORD
)IntGetWindowRgn(Window
, (HRGN
)Param2
));
516 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
519 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
525 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
526 MenuObject
->MenuInfo
.Height
= (int)Param2
;
529 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
530 IntReleaseMenuObject(MenuObject
);
533 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
536 SETMENUITEMRECT smir
;
537 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
541 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
543 IntReleaseMenuObject(MenuObject
);
547 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
549 IntReleaseMenuObject(MenuObject
);
553 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
555 PUSER_MESSAGE_QUEUE MsgQueue
= ((PW32THREAD
)PsGetCurrentThread()->Tcb
.Win32Thread
)->MessageQueue
;
558 RETURN( (DWORD
)MsqSetStateWindow(MsgQueue
, (ULONG
)Param1
, (HWND
)Param2
));
561 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
565 case TWOPARAM_ROUTINE_UNKNOWN
:
569 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
571 PWINDOW_OBJECT Window
= UserGetWindowObject((HWND
)Param1
);
572 if (!Window
) RETURN(0);
574 RETURN( (DWORD
)IntShowOwnedPopups(Window
, (BOOL
) Param2
));
577 case TWOPARAM_ROUTINE_ROS_SHOWWINDOW
:
579 #define WIN_NEEDS_SHOW_OWNEDPOPUP (0x00000040)
580 PWINDOW_OBJECT Window
;
581 DPRINT1("ROS_SHOWWINDOW\n");
583 if (!(Window
= UserGetWindowObject((HWND
)Param1
)))
590 if (!(Window
->Flags
& WIN_NEEDS_SHOW_OWNEDPOPUP
))
594 Window
->Flags
&= ~WIN_NEEDS_SHOW_OWNEDPOPUP
;
597 Window
->Flags
|= WIN_NEEDS_SHOW_OWNEDPOPUP
;
599 DPRINT1("ROS_SHOWWINDOW ---> 0x%x\n",Window
->Flags
);
602 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
606 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
608 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
610 RETURN( (DWORD
)FALSE
);
613 Window
->ContextHelpId
= Param2
;
615 RETURN( (DWORD
)TRUE
);
617 case TWOPARAM_ROUTINE_SETCARETPOS
:
618 RETURN( (DWORD
)co_IntSetCaretPos((int)Param1
, (int)Param2
));
620 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
625 if(!(Window
= UserGetWindowObject((HWND
)Param1
)))
632 * According to WINE, Windows' doesn't check the cbSize field
635 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
636 if(!NT_SUCCESS(Status
))
638 SetLastNtError(Status
);
642 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
644 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
649 if((Ret
= (DWORD
)IntGetWindowInfo(Window
, &wi
)))
651 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
652 if(!NT_SUCCESS(Status
))
654 SetLastNtError(Status
);
662 case TWOPARAM_ROUTINE_REGISTERLOGONPROC
:
663 RETURN( (DWORD
)co_IntRegisterLogonProcess((HANDLE
)Param1
, (BOOL
)Param2
));
665 case TWOPARAM_ROUTINE_SETSYSCOLORS
:
676 /* FIXME - we should make use of SEH here... */
678 Status
= MmCopyFromCaller(&ChangeSysColors
, (PVOID
)Param1
, sizeof(ChangeSysColors
));
679 if(!NT_SUCCESS(Status
))
681 SetLastNtError(Status
);
685 Buffer
= ExAllocatePool(PagedPool
, (Param2
* sizeof(INT
)) + (Param2
* sizeof(COLORREF
)));
688 INT
*Elements
= (INT
*)Buffer
;
689 COLORREF
*Colors
= (COLORREF
*)Buffer
+ Param2
;
691 Status
= MmCopyFromCaller(Elements
, ChangeSysColors
.Elements
, Param2
* sizeof(INT
));
692 if(NT_SUCCESS(Status
))
694 Status
= MmCopyFromCaller(Colors
, ChangeSysColors
.Colors
, Param2
* sizeof(COLORREF
));
695 if(NT_SUCCESS(Status
))
697 Ret
= (DWORD
)IntSetSysColors((UINT
)Param2
, Elements
, Colors
);
700 SetLastNtError(Status
);
703 SetLastNtError(Status
);
712 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
713 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
714 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
725 /* FIXME - we should make use of SEH here... */
727 Buffer
.Pointer
= ExAllocatePool(PagedPool
, Param2
* sizeof(HANDLE
));
728 if(Buffer
.Pointer
!= NULL
)
732 case TWOPARAM_ROUTINE_GETSYSCOLORBRUSHES
:
733 Ret
= (DWORD
)IntGetSysColorBrushes(Buffer
.Brushes
, (UINT
)Param2
);
735 case TWOPARAM_ROUTINE_GETSYSCOLORPENS
:
736 Ret
= (DWORD
)IntGetSysColorPens(Buffer
.Pens
, (UINT
)Param2
);
738 case TWOPARAM_ROUTINE_GETSYSCOLORS
:
739 Ret
= (DWORD
)IntGetSysColors(Buffer
.Colors
, (UINT
)Param2
);
748 Status
= MmCopyToCaller((PVOID
)Param1
, Buffer
.Pointer
, Param2
* sizeof(HANDLE
));
749 if(!NT_SUCCESS(Status
))
751 SetLastNtError(Status
);
756 ExFreePool(Buffer
.Pointer
);
762 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam(), Param1=0x%x Parm2=0x%x\n",
763 Routine
, Param1
, Param2
);
764 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
768 DPRINT("Leave NtUserCallTwoParam, ret=%i\n",_ret_
);
784 PWINDOW_OBJECT Window
;
785 USER_REFERENCE_ENTRY Ref
;
786 DECLARE_RETURN(BOOLEAN
);
788 DPRINT("Enter NtUserCallHwndLock\n");
789 UserEnterExclusive();
791 if (!(Window
= UserGetWindowObject(hWnd
)))
795 UserRefObjectCo(Window
, &Ref
);
797 /* FIXME: Routine can be 0x53 - 0x5E */
800 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
801 co_WinPosArrangeIconicWindows(Window
);
804 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
807 DPRINT("HWNDLOCK_ROUTINE_DRAWMENUBAR\n");
809 if (!((Window
->Style
& (WS_CHILD
| WS_POPUP
)) != WS_CHILD
))
812 if(!(Menu
= UserGetMenuObject((HMENU
) Window
->IDMenu
)))
815 Menu
->MenuInfo
.WndOwner
= hWnd
;
816 Menu
->MenuInfo
.Height
= 0;
818 co_WinPosSetWindowPos(Window
, 0, 0, 0, 0, 0, SWP_NOSIZE
| SWP_NOMOVE
|
819 SWP_NOACTIVATE
| SWP_NOZORDER
| SWP_FRAMECHANGED
);
825 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
829 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
830 Ret
= co_IntSetForegroundWindow(Window
);
833 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
838 UserDerefObjectCo(Window
);
843 DPRINT("Leave NtUserCallHwndLock, ret=%i\n",_ret_
);
859 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
862 * Nothing too hard...validate the hWnd and save it in the Desktop Info
864 DPRINT1("HWNDOPT_ROUTINE_SETPROGMANWINDOW UNIMPLEMENTED\n");
867 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
870 * Nothing too hard...validate the hWnd and save it in the Desktop Info
872 DPRINT1("HWNDOPT_ROUTINE_SETTASKMANWINDOW UNIMPLEMENTED\n");
883 NtUserGetThreadState(
886 DECLARE_RETURN(DWORD
);
888 DPRINT("Enter NtUserGetThreadState\n");
889 if (Routine
!= THREADSTATE_GETTHREADINFO
)
895 UserEnterExclusive();
900 case THREADSTATE_GETTHREADINFO
:
904 case THREADSTATE_FOCUSWINDOW
:
905 RETURN( (DWORD
)IntGetThreadFocusWindow());
910 DPRINT("Leave NtUserGetThreadState, ret=%i\n",_ret_
);
916 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
918 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
920 /* Firefox 1.0.7 depends on the lfHeight value being negative */
921 static LOGFONTW DefaultFont
= {
922 -11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
923 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
924 L
"Bitstream Vera Sans"
927 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
929 QueryTable
[0].Name
= lpValueName
;
930 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
931 QueryTable
[0].EntryContext
= font
;
933 Status
= RtlQueryRegistryValues(
935 L
"Control Panel\\Desktop\\WindowMetrics",
940 if (!NT_SUCCESS(Status
))
942 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
947 IntSystemParametersInfo(
953 PWINSTATION_OBJECT WinStaObject
;
956 static BOOL bInitialized
= FALSE
;
957 static LOGFONTW IconFont
;
958 static NONCLIENTMETRICSW pMetrics
;
959 static BOOL GradientCaptions
= TRUE
;
960 static UINT FocusBorderHeight
= 1;
961 static UINT FocusBorderWidth
= 1;
965 RtlZeroMemory(&IconFont
, sizeof(LOGFONTW
));
966 RtlZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
968 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
969 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
970 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
971 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
972 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
973 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
975 pMetrics
.iBorderWidth
= 1;
976 pMetrics
.iScrollWidth
= UserGetSystemMetrics(SM_CXVSCROLL
);
977 pMetrics
.iScrollHeight
= UserGetSystemMetrics(SM_CYHSCROLL
);
978 pMetrics
.iCaptionWidth
= UserGetSystemMetrics(SM_CXSIZE
);
979 pMetrics
.iCaptionHeight
= UserGetSystemMetrics(SM_CYSIZE
);
980 pMetrics
.iSmCaptionWidth
= UserGetSystemMetrics(SM_CXSMSIZE
);
981 pMetrics
.iSmCaptionHeight
= UserGetSystemMetrics(SM_CYSMSIZE
);
982 pMetrics
.iMenuWidth
= UserGetSystemMetrics(SM_CXMENUSIZE
);
983 pMetrics
.iMenuHeight
= UserGetSystemMetrics(SM_CYMENUSIZE
);
984 pMetrics
.cbSize
= sizeof(NONCLIENTMETRICSW
);
991 case SPI_SETDOUBLECLKWIDTH
:
992 case SPI_SETDOUBLECLKHEIGHT
:
993 case SPI_SETDOUBLECLICKTIME
:
994 case SPI_SETDESKWALLPAPER
:
995 case SPI_GETDESKWALLPAPER
:
997 PSYSTEM_CURSORINFO CurInfo
;
999 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1003 if(!NT_SUCCESS(Status
))
1005 SetLastNtError(Status
);
1006 return (DWORD
)FALSE
;
1011 case SPI_SETDOUBLECLKWIDTH
:
1012 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1013 /* FIXME limit the maximum value? */
1014 CurInfo
->DblClickWidth
= uiParam
;
1016 case SPI_SETDOUBLECLKHEIGHT
:
1017 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1018 /* FIXME limit the maximum value? */
1019 CurInfo
->DblClickHeight
= uiParam
;
1021 case SPI_SETDOUBLECLICKTIME
:
1022 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1023 /* FIXME limit the maximum time to 1000 ms? */
1024 CurInfo
->DblClickSpeed
= uiParam
;
1026 case SPI_SETDESKWALLPAPER
:
1028 /* This function expects different parameters than the user mode version!
1030 We let the user mode code load the bitmap, it passed the handle to
1031 the bitmap. We'll change it's ownership to system and replace it with
1032 the current wallpaper bitmap */
1033 HBITMAP hOldBitmap
, hNewBitmap
;
1034 UNICODE_STRING Key
= RTL_CONSTANT_STRING(L
"Control Panel\\Desktop");
1035 UNICODE_STRING Tile
= RTL_CONSTANT_STRING(L
"TileWallpaper");
1036 UNICODE_STRING Style
= RTL_CONSTANT_STRING(L
"WallpaperStyle");
1037 UNICODE_STRING KeyPath
;
1038 OBJECT_ATTRIBUTES KeyAttributes
;
1039 OBJECT_ATTRIBUTES ObjectAttributes
;
1041 HANDLE CurrentUserKey
= NULL
;
1042 HANDLE KeyHandle
= NULL
;
1043 PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo
;
1045 ULONG ResLength
= 0;
1050 hNewBitmap
= *(HBITMAP
*)pvParam
;
1051 if(hNewBitmap
!= NULL
)
1054 /* try to get the size of the wallpaper */
1055 if(!(bmp
= BITMAPOBJ_LockBitmap(hNewBitmap
)))
1057 ObDereferenceObject(WinStaObject
);
1060 WinStaObject
->cxWallpaper
= bmp
->SurfObj
.sizlBitmap
.cx
;
1061 WinStaObject
->cyWallpaper
= bmp
->SurfObj
.sizlBitmap
.cy
;
1063 BITMAPOBJ_UnlockBitmap(bmp
);
1065 /* change the bitmap's ownership */
1066 GDIOBJ_SetOwnership(GdiHandleTable
, hNewBitmap
, NULL
);
1068 hOldBitmap
= (HBITMAP
)InterlockedExchange((LONG
*)&WinStaObject
->hbmWallpaper
, (LONG
)hNewBitmap
);
1069 if(hOldBitmap
!= NULL
)
1071 /* delete the old wallpaper */
1072 NtGdiDeleteObject(hOldBitmap
);
1077 /*default value is center */
1078 WinStaObject
->WallpaperMode
= wmCenter
;
1082 /* Get a handle to the current users settings */
1083 RtlFormatCurrentUserKeyPath(&KeyPath
);
1084 InitializeObjectAttributes(&ObjectAttributes
,&KeyPath
,OBJ_CASE_INSENSITIVE
,NULL
,NULL
);
1085 ZwOpenKey(&CurrentUserKey
, KEY_READ
, &ObjectAttributes
);
1086 RtlFreeUnicodeString(&KeyPath
);
1088 /* open up the settings to read the values */
1089 InitializeObjectAttributes(&KeyAttributes
, &Key
, OBJ_CASE_INSENSITIVE
,
1090 CurrentUserKey
, NULL
);
1091 ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
1092 ZwClose(CurrentUserKey
);
1094 /* read the tile value in the registry */
1095 Status
= ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1098 /* fall back to .DEFAULT if we didnt find values */
1099 if(Status
== STATUS_INVALID_HANDLE
)
1101 RtlInitUnicodeString (&KeyPath
,L
"\\Registry\\User\\.Default\\Control Panel\\Desktop");
1102 InitializeObjectAttributes(&KeyAttributes
, &KeyPath
, OBJ_CASE_INSENSITIVE
,
1104 ZwOpenKey(&KeyHandle
, KEY_READ
, &KeyAttributes
);
1105 ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1109 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1110 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
1113 if(!KeyValuePartialInfo
)
1119 Status
= ZwQueryValueKey(KeyHandle
, &Tile
, KeyValuePartialInformation
,
1120 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
1121 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
1124 ExFreePool(KeyValuePartialInfo
);
1128 Tile
.Length
= KeyValuePartialInfo
->DataLength
;
1129 Tile
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
1130 Tile
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
1132 Status
= RtlUnicodeStringToInteger(&Tile
, 0, &TileNum
);
1133 if(!NT_SUCCESS(Status
))
1137 ExFreePool(KeyValuePartialInfo
);
1139 /* start over again and look for the style*/
1141 Status
= ZwQueryValueKey(KeyHandle
, &Style
, KeyValuePartialInformation
,
1144 ResLength
+= sizeof(KEY_VALUE_PARTIAL_INFORMATION
);
1145 KeyValuePartialInfo
= ExAllocatePoolWithTag(PagedPool
, ResLength
, TAG_STRING
);
1148 if(!KeyValuePartialInfo
)
1154 Status
= ZwQueryValueKey(KeyHandle
, &Style
, KeyValuePartialInformation
,
1155 (PVOID
)KeyValuePartialInfo
, Length
, &ResLength
);
1156 if(!NT_SUCCESS(Status
) || (KeyValuePartialInfo
->Type
!= REG_SZ
))
1159 ExFreePool(KeyValuePartialInfo
);
1163 Style
.Length
= KeyValuePartialInfo
->DataLength
;
1164 Style
.MaximumLength
= KeyValuePartialInfo
->DataLength
;
1165 Style
.Buffer
= (PWSTR
)KeyValuePartialInfo
->Data
;
1167 Status
= RtlUnicodeStringToInteger(&Style
, 0, &StyleNum
);
1168 if(!NT_SUCCESS(Status
))
1172 ExFreePool(KeyValuePartialInfo
);
1174 /* Check the values we found in the registry */
1175 if(TileNum
&& !StyleNum
)
1177 WinStaObject
->WallpaperMode
= wmTile
;
1179 else if(!TileNum
&& StyleNum
== 2)
1181 WinStaObject
->WallpaperMode
= wmStretch
;
1187 case SPI_GETDESKWALLPAPER
:
1188 /* This function expects different parameters than the user mode version!
1190 We basically return the current wallpaper handle - if any. The user
1191 mode version should load the string from the registry and return it
1192 without calling this function */
1194 *(HBITMAP
*)pvParam
= (HBITMAP
)WinStaObject
->hbmWallpaper
;
1198 /* FIXME save the value to the registry */
1200 ObDereferenceObject(WinStaObject
);
1203 case SPI_SETWORKAREA
:
1206 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
1210 /* FIXME - Set last error */
1215 rc
= (RECT
*)pvParam
;
1216 Desktop
->WorkArea
= *rc
;
1220 case SPI_GETWORKAREA
:
1222 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
1226 /* FIXME - Set last error */
1231 IntGetDesktopWorkArea(Desktop
, (PRECT
)pvParam
);
1235 case SPI_SETGRADIENTCAPTIONS
:
1237 GradientCaptions
= (pvParam
!= NULL
);
1238 /* FIXME - should be checked if the color depth is higher than 8bpp? */
1241 case SPI_GETGRADIENTCAPTIONS
:
1244 BOOL Ret
= GradientCaptions
;
1246 hDC
= IntGetScreenDC();
1249 Ret
= (NtGdiGetDeviceCaps(hDC
, BITSPIXEL
) > 8) && Ret
;
1252 *((PBOOL
)pvParam
) = Ret
;
1257 case SPI_SETFONTSMOOTHING
:
1259 IntEnableFontRendering(uiParam
!= 0);
1262 case SPI_GETFONTSMOOTHING
:
1265 *((BOOL
*)pvParam
) = IntIsFontRenderingEnabled();
1268 case SPI_GETICONTITLELOGFONT
:
1271 *((LOGFONTW
*)pvParam
) = IconFont
;
1274 case SPI_GETNONCLIENTMETRICS
:
1277 *((NONCLIENTMETRICSW
*)pvParam
) = pMetrics
;
1280 case SPI_GETFOCUSBORDERHEIGHT
:
1283 *((UINT
*)pvParam
) = FocusBorderHeight
;
1286 case SPI_GETFOCUSBORDERWIDTH
:
1289 *((UINT
*)pvParam
) = FocusBorderWidth
;
1292 case SPI_SETFOCUSBORDERHEIGHT
:
1294 FocusBorderHeight
= (UINT
)pvParam
;
1297 case SPI_SETFOCUSBORDERWIDTH
:
1299 FocusBorderWidth
= (UINT
)pvParam
;
1305 DPRINT1("SystemParametersInfo: Unsupported Action 0x%x (uiParam: 0x%x, pvParam: 0x%x, fWinIni: 0x%x)\n",
1306 uiAction
, uiParam
, pvParam
, fWinIni
);
1317 UserSystemParametersInfo(
1327 case SPI_SETDOUBLECLKWIDTH
:
1328 case SPI_SETDOUBLECLKHEIGHT
:
1329 case SPI_SETDOUBLECLICKTIME
:
1330 case SPI_SETGRADIENTCAPTIONS
:
1331 case SPI_SETFONTSMOOTHING
:
1332 case SPI_SETFOCUSBORDERHEIGHT
:
1333 case SPI_SETFOCUSBORDERWIDTH
:
1335 return (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
);
1337 case SPI_SETWORKAREA
:
1340 Status
= MmCopyFromCaller(&rc
, (PRECT
)pvParam
, sizeof(RECT
));
1341 if(!NT_SUCCESS(Status
))
1343 SetLastNtError(Status
);
1346 return( (DWORD
)IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
));
1348 case SPI_GETWORKAREA
:
1352 if(!IntSystemParametersInfo(uiAction
, uiParam
, &rc
, fWinIni
))
1357 Status
= MmCopyToCaller((PRECT
)pvParam
, &rc
, sizeof(RECT
));
1358 if(!NT_SUCCESS(Status
))
1360 SetLastNtError(Status
);
1365 case SPI_GETFONTSMOOTHING
:
1366 case SPI_GETGRADIENTCAPTIONS
:
1367 case SPI_GETFOCUSBORDERHEIGHT
:
1368 case SPI_GETFOCUSBORDERWIDTH
:
1372 if(!IntSystemParametersInfo(uiAction
, uiParam
, &Ret
, fWinIni
))
1377 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
1378 if(!NT_SUCCESS(Status
))
1380 SetLastNtError(Status
);
1385 case SPI_SETDESKWALLPAPER
:
1387 /* !!! As opposed to the user mode version this version accepts a handle
1389 HBITMAP hbmWallpaper
;
1391 Status
= MmCopyFromCaller(&hbmWallpaper
, pvParam
, sizeof(HBITMAP
));
1392 if(!NT_SUCCESS(Status
))
1394 SetLastNtError(Status
);
1397 return( IntSystemParametersInfo(SPI_SETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
));
1399 case SPI_GETDESKWALLPAPER
:
1401 /* !!! As opposed to the user mode version this version returns a handle
1403 HBITMAP hbmWallpaper
;
1406 Ret
= IntSystemParametersInfo(SPI_GETDESKWALLPAPER
, 0, &hbmWallpaper
, fWinIni
);
1408 Status
= MmCopyToCaller(pvParam
, &hbmWallpaper
, sizeof(HBITMAP
));
1409 if(!NT_SUCCESS(Status
))
1411 SetLastNtError(Status
);
1416 case SPI_GETICONTITLELOGFONT
:
1420 if(!IntSystemParametersInfo(uiAction
, uiParam
, &IconFont
, fWinIni
))
1425 Status
= MmCopyToCaller(pvParam
, &IconFont
, sizeof(LOGFONTW
));
1426 if(!NT_SUCCESS(Status
))
1428 SetLastNtError(Status
);
1433 case SPI_GETNONCLIENTMETRICS
:
1435 NONCLIENTMETRICSW metrics
;
1437 Status
= MmCopyFromCaller(&metrics
.cbSize
, pvParam
, sizeof(UINT
));
1438 if(!NT_SUCCESS(Status
))
1440 SetLastNtError(Status
);
1443 if(metrics
.cbSize
!= sizeof(NONCLIENTMETRICSW
))
1445 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1449 if(!IntSystemParametersInfo(uiAction
, uiParam
, &metrics
, fWinIni
))
1454 Status
= MmCopyToCaller(pvParam
, &metrics
.cbSize
, sizeof(NONCLIENTMETRICSW
));
1455 if(!NT_SUCCESS(Status
))
1457 SetLastNtError(Status
);
1474 NtUserSystemParametersInfo(
1480 DECLARE_RETURN(BOOLEAN
);
1482 DPRINT("Enter NtUserSystemParametersInfo\n");
1483 UserEnterExclusive();
1485 RETURN( UserSystemParametersInfo(uiAction
, uiParam
, pvParam
, fWinIni
));
1488 DPRINT("Leave NtUserSystemParametersInfo, ret=%i\n",_ret_
);
1497 NtUserGetDoubleClickTime(VOID
)
1501 PWINSTATION_OBJECT WinStaObject
;
1502 PSYSTEM_CURSORINFO CurInfo
;
1503 DECLARE_RETURN(UINT
);
1505 DPRINT("Enter NtUserGetDoubleClickTime\n");
1508 Status
= IntValidateWindowStationHandle(PsGetCurrentProcess()->Win32WindowStation
,
1512 if (!NT_SUCCESS(Status
))
1513 RETURN( (DWORD
)FALSE
);
1515 CurInfo
= IntGetSysCursorInfo(WinStaObject
);
1516 Result
= CurInfo
->DblClickSpeed
;
1518 ObDereferenceObject(WinStaObject
);
1522 DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n",_ret_
);
1529 NtUserGetGUIThreadInfo(
1530 DWORD idThread
, /* if NULL use foreground thread */
1531 LPGUITHREADINFO lpgui
)
1534 PTHRDCARETINFO CaretInfo
;
1535 GUITHREADINFO SafeGui
;
1536 PDESKTOP_OBJECT Desktop
;
1537 PUSER_MESSAGE_QUEUE MsgQueue
;
1538 PETHREAD Thread
= NULL
;
1539 DECLARE_RETURN(BOOLEAN
);
1541 DPRINT("Enter NtUserGetGUIThreadInfo\n");
1544 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
1545 if(!NT_SUCCESS(Status
))
1547 SetLastNtError(Status
);
1551 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
1553 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1559 Status
= PsLookupThreadByThreadId((HANDLE
)idThread
, &Thread
);
1560 if(!NT_SUCCESS(Status
))
1562 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1565 Desktop
= ((PW32THREAD
)Thread
->Tcb
.Win32Thread
)->Desktop
;
1569 /* get the foreground thread */
1570 PW32THREAD W32Thread
= (PW32THREAD
)PsGetCurrentThread()->Tcb
.Win32Thread
;
1571 Desktop
= W32Thread
->Desktop
;
1574 MsgQueue
= Desktop
->ActiveMessageQueue
;
1577 Thread
= MsgQueue
->Thread
;
1582 if(!Thread
|| !Desktop
)
1584 if(idThread
&& Thread
)
1585 ObDereferenceObject(Thread
);
1586 SetLastWin32Error(ERROR_ACCESS_DENIED
);
1590 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
1591 CaretInfo
= MsgQueue
->CaretInfo
;
1593 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
1594 if(MsgQueue
->MenuOwner
)
1595 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
1596 if(MsgQueue
->MoveSize
)
1597 SafeGui
.flags
|= GUI_INMOVESIZE
;
1599 /* FIXME add flag GUI_16BITTASK */
1601 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
1602 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
1603 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
1604 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
1605 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
1606 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
1608 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
1609 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
1610 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
1611 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
1614 ObDereferenceObject(Thread
);
1616 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
1617 if(!NT_SUCCESS(Status
))
1619 SetLastNtError(Status
);
1626 DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_
);
1634 NtUserGetGuiResources(
1639 PW32PROCESS W32Process
;
1642 DECLARE_RETURN(DWORD
);
1644 DPRINT("Enter NtUserGetGuiResources\n");
1647 Status
= ObReferenceObjectByHandle(hProcess
,
1648 PROCESS_QUERY_INFORMATION
,
1650 ExGetPreviousMode(),
1654 if(!NT_SUCCESS(Status
))
1656 SetLastNtError(Status
);
1660 W32Process
= (PW32PROCESS
)Process
->Win32Process
;
1663 ObDereferenceObject(Process
);
1664 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1672 Ret
= (DWORD
)W32Process
->GDIObjects
;
1675 case GR_USEROBJECTS
:
1677 Ret
= (DWORD
)W32Process
->UserObjects
;
1682 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
1687 ObDereferenceObject(Process
);
1692 DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_
);
1698 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
1699 PUNICODE_STRING Source
)
1704 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1705 if(!NT_SUCCESS(Status
))
1710 if(Dest
->Length
> 0x4000)
1712 return STATUS_UNSUCCESSFUL
;
1716 Dest
->Buffer
= NULL
;
1718 if(Dest
->Length
> 0 && Src
)
1720 Dest
->MaximumLength
= Dest
->Length
;
1721 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1724 return STATUS_NO_MEMORY
;
1727 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1728 if(!NT_SUCCESS(Status
))
1730 ExFreePool(Dest
->Buffer
);
1731 Dest
->Buffer
= NULL
;
1736 return STATUS_SUCCESS
;
1739 /* string is empty */
1740 return STATUS_SUCCESS
;
1744 IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest
,
1745 PUNICODE_STRING Source
)
1750 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
1751 if(!NT_SUCCESS(Status
))
1756 if(Dest
->Length
> 0x4000)
1758 return STATUS_UNSUCCESSFUL
;
1762 Dest
->Buffer
= NULL
;
1764 if(Dest
->Length
> 0 && Src
)
1766 Dest
->MaximumLength
= Dest
->Length
+ sizeof(WCHAR
);
1767 Dest
->Buffer
= ExAllocatePoolWithTag(PagedPool
, Dest
->MaximumLength
, TAG_STRING
);
1770 return STATUS_NO_MEMORY
;
1773 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->Length
);
1774 if(!NT_SUCCESS(Status
))
1776 ExFreePool(Dest
->Buffer
);
1777 Dest
->Buffer
= NULL
;
1781 /* make sure the string is null-terminated */
1782 Src
= (PWSTR
)((PBYTE
)Dest
->Buffer
+ Dest
->Length
);
1785 return STATUS_SUCCESS
;
1788 /* string is empty */
1789 return STATUS_SUCCESS
;
1793 IntUnicodeStringToNULLTerminated(PWSTR
*Dest
, PUNICODE_STRING Src
)
1795 if (Src
->Length
+ sizeof(WCHAR
) <= Src
->MaximumLength
1796 && L
'\0' == Src
->Buffer
[Src
->Length
/ sizeof(WCHAR
)])
1798 /* The unicode_string is already nul terminated. Just reuse it. */
1799 *Dest
= Src
->Buffer
;
1800 return STATUS_SUCCESS
;
1803 *Dest
= ExAllocatePoolWithTag(PagedPool
, Src
->Length
+ sizeof(WCHAR
), TAG_STRING
);
1806 return STATUS_NO_MEMORY
;
1808 RtlCopyMemory(*Dest
, Src
->Buffer
, Src
->Length
);
1809 (*Dest
)[Src
->Length
/ 2] = L
'\0';
1811 return STATUS_SUCCESS
;
1815 IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated
, PUNICODE_STRING UnicodeString
)
1817 if (NullTerminated
!= UnicodeString
->Buffer
)
1819 ExFreePool(NullTerminated
);
1824 NtUserUpdatePerUserSystemParameters(
1829 DECLARE_RETURN(BOOLEAN
);
1831 DPRINT("Enter NtUserUpdatePerUserSystemParameters\n");
1832 UserEnterExclusive();
1834 Result
&= IntDesktopUpdatePerUserSettings(bEnable
);
1838 DPRINT("Leave NtUserUpdatePerUserSystemParameters, ret=%i\n",_ret_
);
1844 GetW32ProcessInfo(VOID
)
1847 PW32PROCESS W32Process
= PsGetWin32Process();
1849 if (W32Process
== NULL
)
1851 /* FIXME - temporary hack for system threads... */
1855 if (W32Process
->ProcessInfo
== NULL
)
1857 pi
= UserHeapAlloc(sizeof(W32PROCESSINFO
));
1861 sizeof(W32PROCESSINFO
));
1864 pi
->UserHandleTable
= gHandleTable
;
1866 if (InterlockedCompareExchangePointer(&W32Process
->ProcessInfo
,
1875 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1879 return W32Process
->ProcessInfo
;
1883 GetW32ThreadInfo(VOID
)
1887 PW32THREAD W32Thread
= PsGetWin32Thread();
1889 if (W32Thread
== NULL
)
1891 /* FIXME - temporary hack for system threads... */
1895 /* allocate a W32THREAD structure if neccessary */
1896 if (W32Thread
->ThreadInfo
== NULL
)
1898 ti
= UserHeapAlloc(sizeof(W32THREADINFO
));
1902 sizeof(W32THREADINFO
));
1905 ti
->kpi
= GetW32ProcessInfo();
1906 ti
->pi
= UserHeapAddressToUser(ti
->kpi
);
1907 if (W32Thread
->Desktop
!= NULL
)
1909 ti
->Desktop
= W32Thread
->Desktop
->DesktopInfo
;
1910 ti
->DesktopHeapDelta
= DesktopHeapGetUserDelta();
1915 ti
->DesktopHeapDelta
= 0;
1918 W32Thread
->ThreadInfo
= ti
;
1919 /* update the TEB */
1920 Teb
= NtCurrentTeb();
1927 Teb
->Win32ThreadInfo
= UserHeapAddressToUser(W32Thread
->ThreadInfo
);
1931 SetLastNtError(_SEH_GetExceptionCode());
1937 SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY
);
1941 return W32Thread
->ThreadInfo
;