1 /* $Id: misc.c,v 1.59 2004/04/09 20:03:19 navaraf Exp $
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)
11 #include <ddk/ntddk.h>
12 #include <ddk/ntddmou.h>
13 #include <win32k/win32k.h>
14 #include <win32k/dc.h>
15 #include <internal/safe.h>
16 #include <include/error.h>
17 #include <include/window.h>
18 #include <include/menu.h>
19 #include <include/painting.h>
20 #include <include/dce.h>
21 #include <include/mouse.h>
22 #include <include/winsta.h>
23 #include <include/caret.h>
24 #include <include/object.h>
25 #include <include/focus.h>
26 #include <include/clipboard.h>
27 #include <include/msgqueue.h>
28 #include <include/desktop.h>
29 #include <include/text.h>
30 #include <include/tags.h>
35 void W32kRegisterPrimitiveMessageQueue() {
36 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
37 if( !pmPrimitiveMessageQueue
) {
39 pThread
= PsGetWin32Thread();
40 if( pThread
&& pThread
->MessageQueue
) {
41 pmPrimitiveMessageQueue
= pThread
->MessageQueue
;
42 DPRINT( "Installed primitive input queue.\n" );
45 DPRINT1( "Alert! Someone is trying to steal the primitive queue.\n" );
49 PUSER_MESSAGE_QUEUE
W32kGetPrimitiveMessageQueue() {
50 extern PUSER_MESSAGE_QUEUE pmPrimitiveMessageQueue
;
51 return pmPrimitiveMessageQueue
;
59 NtUserCallNoParam(DWORD Routine
)
65 case NOPARAM_ROUTINE_REGISTER_PRIMITIVE
:
66 W32kRegisterPrimitiveMessageQueue();
70 case NOPARAM_ROUTINE_DESTROY_CARET
:
71 Result
= (DWORD
)IntDestroyCaret(PsGetCurrentThread()->Win32Thread
);
74 case NOPARAM_ROUTINE_INIT_MESSAGE_PUMP
:
75 Result
= (DWORD
)IntInitMessagePumpHook();
78 case NOPARAM_ROUTINE_UNINIT_MESSAGE_PUMP
:
79 Result
= (DWORD
)IntUninitMessagePumpHook();
82 case NOPARAM_ROUTINE_GETMESSAGEEXTRAINFO
:
83 Result
= (DWORD
)MsqGetMessageExtraInfo();
87 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam\n");
88 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
105 PWINSTATION_OBJECT WinStaObject
;
106 PWINDOW_OBJECT WindowObject
;
110 case ONEPARAM_ROUTINE_GETMENU
:
111 WindowObject
= IntGetWindowObject((HWND
)Param
);
114 SetLastWin32Error(ERROR_INVALID_HANDLE
);
118 Result
= (DWORD
)WindowObject
->IDMenu
;
120 IntReleaseWindowObject(WindowObject
);
123 case ONEPARAM_ROUTINE_ISWINDOWUNICODE
:
124 WindowObject
= IntGetWindowObject((HWND
)Param
);
127 SetLastWin32Error(ERROR_INVALID_HANDLE
);
130 Result
= WindowObject
->Unicode
;
131 IntReleaseWindowObject(WindowObject
);
134 case ONEPARAM_ROUTINE_WINDOWFROMDC
:
135 return (DWORD
)IntWindowFromDC((HDC
)Param
);
137 case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID
:
138 WindowObject
= IntGetWindowObject((HWND
)Param
);
141 SetLastWin32Error(ERROR_INVALID_HANDLE
);
145 Result
= WindowObject
->ContextHelpId
;
147 IntReleaseWindowObject(WindowObject
);
150 case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON
:
151 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
155 if (!NT_SUCCESS(Status
))
158 Result
= (DWORD
)IntSwapMouseButton(WinStaObject
, (BOOL
)Param
);
160 ObDereferenceObject(WinStaObject
);
163 case ONEPARAM_ROUTINE_SWITCHCARETSHOWING
:
164 return (DWORD
)IntSwitchCaretShowing((PVOID
)Param
);
166 case ONEPARAM_ROUTINE_SETCARETBLINKTIME
:
167 return (DWORD
)IntSetCaretBlinkTime((UINT
)Param
);
169 case ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMATS
:
170 return (DWORD
)IntEnumClipboardFormats((UINT
)Param
);
172 case ONEPARAM_ROUTINE_GETWINDOWINSTANCE
:
173 if(!(WindowObject
= IntGetWindowObject((HWND
)Param
)))
175 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
179 Result
= (DWORD
)WindowObject
->Instance
;
180 IntReleaseWindowObject(WindowObject
);
183 case ONEPARAM_ROUTINE_SETMESSAGEEXTRAINFO
:
184 return (DWORD
)MsqSetMessageExtraInfo((LPARAM
)Param
);
186 DPRINT1("Calling invalid routine number 0x%x in NtUserCallOneParam()\n Param=0x%x\n",
188 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
204 PWINDOW_OBJECT WindowObject
;
205 PSYSTEM_CURSORINFO CurInfo
;
206 PWINSTATION_OBJECT WinStaObject
;
211 case TWOPARAM_ROUTINE_GETWINDOWRGNBOX
:
215 Ret
= (DWORD
)IntGetWindowRgnBox((HWND
)Param1
, &rcRect
);
216 Status
= MmCopyToCaller((PVOID
)Param2
, &rcRect
, sizeof(RECT
));
217 if(!NT_SUCCESS(Status
))
219 SetLastNtError(Status
);
224 case TWOPARAM_ROUTINE_GETWINDOWRGN
:
226 return (DWORD
)IntGetWindowRgn((HWND
)Param1
, (HRGN
)Param2
);
228 case TWOPARAM_ROUTINE_SETMENUBARHEIGHT
:
231 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
237 Ret
= (MenuObject
->MenuInfo
.Height
== (int)Param2
);
238 MenuObject
->MenuInfo
.Height
= (int)Param2
;
241 Ret
= (DWORD
)MenuObject
->MenuInfo
.Height
;
242 IntReleaseMenuObject(MenuObject
);
245 case TWOPARAM_ROUTINE_SETMENUITEMRECT
:
248 SETMENUITEMRECT smir
;
249 PMENU_OBJECT MenuObject
= IntGetMenuObject((HMENU
)Param1
);
253 if(!NT_SUCCESS(MmCopyFromCaller(&smir
, (PVOID
)Param2
, sizeof(SETMENUITEMRECT
))))
255 IntReleaseMenuObject(MenuObject
);
259 Ret
= IntSetMenuItemRect(MenuObject
, smir
.uItem
, smir
.fByPosition
, &smir
.rcRect
);
261 IntReleaseMenuObject(MenuObject
);
265 case TWOPARAM_ROUTINE_SETGUITHRDHANDLE
:
268 PUSER_MESSAGE_QUEUE MsgQueue
= PsGetCurrentThread()->Win32Thread
->MessageQueue
;
272 case TPR_SGTH_ACTIVE
:
273 hwnd
= &MsgQueue
->ActiveWindow
;
276 hwnd
= &MsgQueue
->FocusWindow
;
278 case TPR_SGTH_CAPTURE
:
279 hwnd
= &MsgQueue
->CaptureWindow
;
281 case TPR_SGTH_MENUOWNER
:
282 hwnd
= &MsgQueue
->MenuOwner
;
284 case TPR_SGTH_MOVESIZE
:
285 hwnd
= &MsgQueue
->MoveSize
;
288 hwnd
= &MsgQueue
->CaretInfo
->hWnd
;
293 return (DWORD
)(*hwnd
= (HWND
)Param2
);
296 case TWOPARAM_ROUTINE_ENABLEWINDOW
:
300 case TWOPARAM_ROUTINE_UNKNOWN
:
304 case TWOPARAM_ROUTINE_SHOWOWNEDPOPUPS
:
308 case TWOPARAM_ROUTINE_SWITCHTOTHISWINDOW
:
312 case TWOPARAM_ROUTINE_VALIDATERGN
:
313 return (DWORD
)NtUserValidateRgn((HWND
) Param1
, (HRGN
) Param2
);
315 case TWOPARAM_ROUTINE_SETWNDCONTEXTHLPID
:
316 WindowObject
= IntGetWindowObject((HWND
)Param1
);
319 SetLastWin32Error(ERROR_INVALID_HANDLE
);
323 WindowObject
->ContextHelpId
= Param2
;
325 IntReleaseWindowObject(WindowObject
);
328 case TWOPARAM_ROUTINE_CURSORPOSITION
:
331 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
335 if (!NT_SUCCESS(Status
))
340 /* set cursor position */
342 Status
= MmCopyFromCaller(&Pos
, (PPOINT
)Param1
, sizeof(POINT
));
343 if(!NT_SUCCESS(Status
))
345 ObDereferenceObject(WinStaObject
);
346 SetLastNtError(Status
);
350 CurInfo
= &WinStaObject
->SystemCursor
;
351 /* FIXME - check if process has WINSTA_WRITEATTRIBUTES */
353 //CheckClipCursor(&Pos->x, &Pos->y, CurInfo);
354 if((Pos
.x
!= CurInfo
->x
) || (Pos
.y
!= CurInfo
->y
))
356 MouseMoveCursor(Pos
.x
, Pos
.y
);
362 /* get cursor position */
363 /* FIXME - check if process has WINSTA_READATTRIBUTES */
364 Pos
.x
= WinStaObject
->SystemCursor
.x
;
365 Pos
.y
= WinStaObject
->SystemCursor
.y
;
367 Status
= MmCopyToCaller((PPOINT
)Param1
, &Pos
, sizeof(POINT
));
368 if(!NT_SUCCESS(Status
))
370 ObDereferenceObject(WinStaObject
);
371 SetLastNtError(Status
);
377 ObDereferenceObject(WinStaObject
);
381 case TWOPARAM_ROUTINE_SETCARETPOS
:
382 return (DWORD
)IntSetCaretPos((int)Param1
, (int)Param2
);
384 case TWOPARAM_ROUTINE_GETWINDOWINFO
:
389 if(!(WindowObject
= IntGetWindowObject((HWND
)Param1
)))
391 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
395 Status
= MmCopyFromCaller(&wi
.cbSize
, (PVOID
)Param2
, sizeof(wi
.cbSize
));
396 if(!NT_SUCCESS(Status
))
398 IntReleaseWindowObject(WindowObject
);
399 SetLastNtError(Status
);
403 if(wi
.cbSize
!= sizeof(WINDOWINFO
))
405 IntReleaseWindowObject(WindowObject
);
406 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
410 if((Ret
= (DWORD
)IntGetWindowInfo(WindowObject
, &wi
)))
412 Status
= MmCopyToCaller((PVOID
)Param2
, &wi
, sizeof(WINDOWINFO
));
413 if(!NT_SUCCESS(Status
))
415 IntReleaseWindowObject(WindowObject
);
416 SetLastNtError(Status
);
421 IntReleaseWindowObject(WindowObject
);
425 DPRINT1("Calling invalid routine number 0x%x in NtUserCallTwoParam()\n Param1=0x%x Parm2=0x%x\n",
426 Routine
, Param1
, Param2
);
427 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
441 PWINDOW_OBJECT Window
;
443 Window
= IntGetWindowObject(hWnd
);
446 SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE
);
450 /* FIXME: Routine can be 0x53 - 0x5E */
453 case HWNDLOCK_ROUTINE_ARRANGEICONICWINDOWS
:
457 case HWNDLOCK_ROUTINE_DRAWMENUBAR
:
461 case HWNDLOCK_ROUTINE_REDRAWFRAME
:
465 case HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOW
:
466 Ret
= IntSetForegroundWindow(Window
);
469 case HWNDLOCK_ROUTINE_UPDATEWINDOW
:
474 IntReleaseWindowObject(Window
);
487 case HWNDOPT_ROUTINE_SETPROGMANWINDOW
:
491 case HWNDOPT_ROUTINE_SETTASKMANWINDOW
:
503 NtUserGetThreadState(
509 return (DWORD
)IntGetThreadFocusWindow();
515 IntGetFontMetricSetting(LPWSTR lpValueName
, PLOGFONTW font
)
517 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
519 static LOGFONTW DefaultFont
= {
520 11, 0, 0, 0, FW_NORMAL
, FALSE
, FALSE
, FALSE
, ANSI_CHARSET
,
521 0, 0, DEFAULT_QUALITY
, VARIABLE_PITCH
| FF_SWISS
,
522 L
"Bitstream Vera Sans"
525 RtlZeroMemory(&QueryTable
, sizeof(QueryTable
));
527 QueryTable
[0].Name
= lpValueName
;
528 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_DIRECT
| RTL_QUERY_REGISTRY_REQUIRED
;
529 QueryTable
[0].EntryContext
= font
;
531 Status
= RtlQueryRegistryValues(
533 L
"Control Panel\\Desktop\\WindowMetrics",
538 if (!NT_SUCCESS(Status
))
540 RtlCopyMemory(font
, &DefaultFont
, sizeof(LOGFONTW
));
549 NtUserSystemParametersInfo(
555 static BOOL GradientCaptions
= TRUE
;
557 PWINSTATION_OBJECT WinStaObject
;
559 static BOOL bInitialized
= FALSE
;
560 static LOGFONTW IconFont
;
561 static NONCLIENTMETRICSW pMetrics
;
565 ZeroMemory(&IconFont
, sizeof(LOGFONTW
));
566 ZeroMemory(&pMetrics
, sizeof(NONCLIENTMETRICSW
));
568 IntGetFontMetricSetting(L
"CaptionFont", &pMetrics
.lfCaptionFont
);
569 IntGetFontMetricSetting(L
"SmCaptionFont", &pMetrics
.lfSmCaptionFont
);
570 IntGetFontMetricSetting(L
"MenuFont", &pMetrics
.lfMenuFont
);
571 IntGetFontMetricSetting(L
"StatusFont", &pMetrics
.lfStatusFont
);
572 IntGetFontMetricSetting(L
"MessageFont", &pMetrics
.lfMessageFont
);
573 IntGetFontMetricSetting(L
"IconFont", &IconFont
);
575 pMetrics
.iBorderWidth
= 1;
576 pMetrics
.iScrollWidth
= NtUserGetSystemMetrics(SM_CXVSCROLL
);
577 pMetrics
.iScrollHeight
= NtUserGetSystemMetrics(SM_CYHSCROLL
);
578 pMetrics
.iCaptionWidth
= NtUserGetSystemMetrics(SM_CXSIZE
);
579 pMetrics
.iCaptionHeight
= NtUserGetSystemMetrics(SM_CYSIZE
);
580 pMetrics
.iSmCaptionWidth
= NtUserGetSystemMetrics(SM_CXSMSIZE
);
581 pMetrics
.iSmCaptionHeight
= NtUserGetSystemMetrics(SM_CYSMSIZE
);
582 pMetrics
.iMenuWidth
= NtUserGetSystemMetrics(SM_CXMENUSIZE
);
583 pMetrics
.iMenuHeight
= NtUserGetSystemMetrics(SM_CYMENUSIZE
);
584 pMetrics
.cbSize
= sizeof(LPNONCLIENTMETRICSW
);
591 case SPI_SETDOUBLECLKWIDTH
:
592 case SPI_SETDOUBLECLKHEIGHT
:
593 case SPI_SETDOUBLECLICKTIME
:
595 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
599 if (!NT_SUCCESS(Status
))
604 case SPI_SETDOUBLECLKWIDTH
:
605 /* FIXME limit the maximum value? */
606 WinStaObject
->SystemCursor
.DblClickWidth
= uiParam
;
608 case SPI_SETDOUBLECLKHEIGHT
:
609 /* FIXME limit the maximum value? */
610 WinStaObject
->SystemCursor
.DblClickHeight
= uiParam
;
612 case SPI_SETDOUBLECLICKTIME
:
613 /* FIXME limit the maximum time to 1000 ms? */
614 WinStaObject
->SystemCursor
.DblClickSpeed
= uiParam
;
618 /* FIXME save the value to the registry */
620 ObDereferenceObject(WinStaObject
);
623 case SPI_SETWORKAREA
:
625 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
629 /* FIXME - Set last error */
633 Status
= MmCopyFromCaller(Desktop
->WorkArea
, (PRECT
)pvParam
, sizeof(RECT
));
634 if(!NT_SUCCESS(Status
))
636 SetLastNtError(Status
);
642 case SPI_GETWORKAREA
:
645 PDESKTOP_OBJECT Desktop
= PsGetWin32Thread()->Desktop
;
649 /* FIXME - Set last error */
653 Rect
= IntGetDesktopWorkArea(Desktop
);
655 Status
= MmCopyToCaller((PRECT
)pvParam
, Desktop
->WorkArea
, sizeof(RECT
));
656 if(!NT_SUCCESS(Status
))
658 SetLastNtError(Status
);
664 case SPI_GETGRADIENTCAPTIONS
:
669 BOOL Ret
= GradientCaptions
;
671 hDC
= IntGetScreenDC();
675 SurfObj
= (SURFOBJ
*)AccessUserObject((ULONG
) dc
->Surface
);
677 Ret
= (SurfObj
->iBitmapFormat
> BMF_8BPP
);
681 Status
= MmCopyToCaller(pvParam
, &Ret
, sizeof(BOOL
));
682 if(!NT_SUCCESS(Status
))
684 SetLastNtError(Status
);
689 case SPI_SETGRADIENTCAPTIONS
:
691 Status
= MmCopyFromCaller(&GradientCaptions
, pvParam
, sizeof(BOOL
));
692 if(!NT_SUCCESS(Status
))
694 SetLastNtError(Status
);
699 case SPI_SETFONTSMOOTHING
:
703 Status
= MmCopyFromCaller(&Enable
, pvParam
, sizeof(BOOL
));
704 if(!NT_SUCCESS(Status
))
706 SetLastNtError(Status
);
710 IntEnableFontRendering(Enable
);
714 case SPI_GETFONTSMOOTHING
:
716 BOOL Enabled
= IntIsFontRenderingEnabled();
718 Status
= MmCopyToCaller(pvParam
, &Enabled
, sizeof(BOOL
));
719 if(!NT_SUCCESS(Status
))
721 SetLastNtError(Status
);
726 case SPI_GETICONTITLELOGFONT
:
728 MmCopyToCaller(pvParam
, (PVOID
)&IconFont
, sizeof(LOGFONTW
));
731 case SPI_GETNONCLIENTMETRICS
:
733 /* FIXME: Is this windows default behavior? */
734 LPNONCLIENTMETRICSW lpMetrics
= (LPNONCLIENTMETRICSW
)pvParam
;
735 if ( lpMetrics
->cbSize
!= sizeof(NONCLIENTMETRICSW
) ||
736 uiParam
!= sizeof(NONCLIENTMETRICSW
))
740 DPRINT("FontName: %S, Size: %i\n",pMetrics
.lfMessageFont
.lfFaceName
, pMetrics
.lfMessageFont
.lfHeight
);
741 MmCopyToCaller(pvParam
, (PVOID
)&pMetrics
, sizeof(NONCLIENTMETRICSW
));
750 NtUserGetDoubleClickTime(VOID
)
754 PWINSTATION_OBJECT WinStaObject
;
756 Status
= IntValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
760 if (!NT_SUCCESS(Status
))
763 Result
= WinStaObject
->SystemCursor
.DblClickSpeed
;
765 ObDereferenceObject(WinStaObject
);
771 NtUserGetGUIThreadInfo(
773 LPGUITHREADINFO lpgui
)
776 PTHRDCARETINFO CaretInfo
;
777 GUITHREADINFO SafeGui
;
778 PDESKTOP_OBJECT Desktop
;
779 PUSER_MESSAGE_QUEUE MsgQueue
;
780 PETHREAD Thread
= NULL
;
782 Status
= MmCopyFromCaller(&SafeGui
, lpgui
, sizeof(DWORD
));
783 if(!NT_SUCCESS(Status
))
785 SetLastNtError(Status
);
789 if(SafeGui
.cbSize
!= sizeof(GUITHREADINFO
))
791 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
797 Status
= PsLookupThreadByThreadId((PVOID
)idThread
, &Thread
);
798 if(!NT_SUCCESS(Status
))
800 SetLastWin32Error(ERROR_ACCESS_DENIED
);
803 Desktop
= Thread
->Win32Thread
->Desktop
;
807 /* get the foreground thread */
808 PW32THREAD W32Thread
= PsGetCurrentThread()->Win32Thread
;
809 Desktop
= W32Thread
->Desktop
;
812 MsgQueue
= Desktop
->ActiveMessageQueue
;
815 Thread
= MsgQueue
->Thread
;
820 if(!Thread
|| !Desktop
)
822 if(idThread
&& Thread
)
823 ObDereferenceObject(Thread
);
824 SetLastWin32Error(ERROR_ACCESS_DENIED
);
828 MsgQueue
= (PUSER_MESSAGE_QUEUE
)Desktop
->ActiveMessageQueue
;
829 CaretInfo
= MsgQueue
->CaretInfo
;
831 SafeGui
.flags
= (CaretInfo
->Visible
? GUI_CARETBLINKING
: 0);
832 if(MsgQueue
->MenuOwner
)
833 SafeGui
.flags
|= GUI_INMENUMODE
| MsgQueue
->MenuState
;
834 if(MsgQueue
->MoveSize
)
835 SafeGui
.flags
|= GUI_INMOVESIZE
;
837 /* FIXME add flag GUI_16BITTASK */
839 SafeGui
.hwndActive
= MsgQueue
->ActiveWindow
;
840 SafeGui
.hwndFocus
= MsgQueue
->FocusWindow
;
841 SafeGui
.hwndCapture
= MsgQueue
->CaptureWindow
;
842 SafeGui
.hwndMenuOwner
= MsgQueue
->MenuOwner
;
843 SafeGui
.hwndMoveSize
= MsgQueue
->MoveSize
;
844 SafeGui
.hwndCaret
= CaretInfo
->hWnd
;
846 SafeGui
.rcCaret
.left
= CaretInfo
->Pos
.x
;
847 SafeGui
.rcCaret
.top
= CaretInfo
->Pos
.y
;
848 SafeGui
.rcCaret
.right
= SafeGui
.rcCaret
.left
+ CaretInfo
->Size
.cx
;
849 SafeGui
.rcCaret
.bottom
= SafeGui
.rcCaret
.top
+ CaretInfo
->Size
.cy
;
852 ObDereferenceObject(Thread
);
854 Status
= MmCopyToCaller(lpgui
, &SafeGui
, sizeof(GUITHREADINFO
));
855 if(!NT_SUCCESS(Status
))
857 SetLastNtError(Status
);
867 NtUserGetGuiResources(
872 PW32PROCESS W32Process
;
876 Status
= ObReferenceObjectByHandle(hProcess
,
877 PROCESS_QUERY_INFORMATION
,
883 if(!NT_SUCCESS(Status
))
885 SetLastNtError(Status
);
889 W32Process
= Process
->Win32Process
;
892 ObDereferenceObject(Process
);
893 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
901 Ret
= (DWORD
)W32Process
->GDIObjects
;
906 Ret
= (DWORD
)W32Process
->UserObjects
;
911 SetLastWin32Error(ERROR_INVALID_PARAMETER
);
916 ObDereferenceObject(Process
);
922 IntSafeCopyUnicodeString(PUNICODE_STRING Dest
,
923 PUNICODE_STRING Source
)
928 Status
= MmCopyFromCaller(Dest
, Source
, sizeof(UNICODE_STRING
));
929 if(!NT_SUCCESS(Status
))
934 if(Dest
->MaximumLength
> 0)
938 Dest
->Buffer
= ExAllocatePoolWithTag(NonPagedPool
, Dest
->MaximumLength
, TAG_STRING
);
941 return STATUS_NO_MEMORY
;
944 Status
= MmCopyFromCaller(Dest
->Buffer
, Src
, Dest
->MaximumLength
);
945 if(!NT_SUCCESS(Status
))
947 ExFreePool(Dest
->Buffer
);
953 return STATUS_SUCCESS
;
955 return STATUS_UNSUCCESSFUL
;