2008-03-21 00:07:06 +00:00
|
|
|
/*
|
2003-05-26 18:52:37 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Misc User funcs
|
2008-03-21 00:07:06 +00:00
|
|
|
* FILE: subsystem/win32/win32k/ntuser/misc.c
|
2003-05-26 18:52:37 +00:00
|
|
|
* PROGRAMER: Ge van Geldorp (ge@gse.nl)
|
|
|
|
* REVISION HISTORY:
|
2005-11-25 13:01:44 +00:00
|
|
|
* 2003/05/22 Created
|
2003-05-26 18:52:37 +00:00
|
|
|
*/
|
2004-05-10 17:07:20 +00:00
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
2003-05-26 18:52:37 +00:00
|
|
|
|
2006-05-22 22:05:40 +00:00
|
|
|
#define NDEBUG
|
2003-05-26 18:52:37 +00:00
|
|
|
#include <debug.h>
|
|
|
|
|
2003-08-28 18:04:59 +00:00
|
|
|
|
2008-10-30 10:46:27 +00:00
|
|
|
SHORT
|
|
|
|
FASTCALL
|
2009-08-24 20:09:58 +00:00
|
|
|
IntGdiGetLanguageID(VOID)
|
2008-10-30 10:46:27 +00:00
|
|
|
{
|
|
|
|
HANDLE KeyHandle;
|
|
|
|
ULONG Size = sizeof(WCHAR) * (MAX_PATH + 12);
|
|
|
|
OBJECT_ATTRIBUTES ObAttr;
|
|
|
|
// http://support.microsoft.com/kb/324097
|
|
|
|
ULONG Ret = 0x409; // English
|
|
|
|
PVOID KeyInfo;
|
|
|
|
UNICODE_STRING Language;
|
|
|
|
|
|
|
|
RtlInitUnicodeString( &Language,
|
|
|
|
L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Nls\\Language");
|
|
|
|
|
|
|
|
InitializeObjectAttributes( &ObAttr,
|
|
|
|
&Language,
|
|
|
|
OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if ( NT_SUCCESS(ZwOpenKey(&KeyHandle, KEY_READ, &ObAttr)))
|
|
|
|
{
|
|
|
|
KeyInfo = ExAllocatePoolWithTag(PagedPool, Size, TAG_STRING);
|
|
|
|
if ( KeyInfo )
|
|
|
|
{
|
|
|
|
RtlInitUnicodeString(&Language, L"Default");
|
|
|
|
|
|
|
|
if ( NT_SUCCESS(ZwQueryValueKey( KeyHandle,
|
|
|
|
&Language,
|
|
|
|
KeyValuePartialInformation,
|
|
|
|
KeyInfo,
|
|
|
|
Size,
|
|
|
|
&Size)) )
|
|
|
|
{
|
|
|
|
RtlInitUnicodeString(&Language, (PVOID)((char *)KeyInfo + 12));
|
|
|
|
RtlUnicodeStringToInteger(&Language, 16, &Ret);
|
|
|
|
}
|
|
|
|
ExFreePoolWithTag(KeyInfo, TAG_STRING);
|
|
|
|
}
|
|
|
|
ZwClose(KeyHandle);
|
|
|
|
}
|
2008-12-30 10:32:23 +00:00
|
|
|
DPRINT("Language ID = %x\n",Ret);
|
2008-10-30 10:46:27 +00:00
|
|
|
return (SHORT) Ret;
|
|
|
|
}
|
|
|
|
|
2003-11-30 20:03:47 +00:00
|
|
|
/*
|
|
|
|
* @unimplemented
|
|
|
|
*/
|
2010-01-05 19:26:32 +00:00
|
|
|
DWORD_PTR APIENTRY
|
2003-11-30 20:03:47 +00:00
|
|
|
NtUserGetThreadState(
|
2005-09-07 21:25:42 +00:00
|
|
|
DWORD Routine)
|
2003-11-30 20:03:47 +00:00
|
|
|
{
|
2010-01-05 19:26:32 +00:00
|
|
|
DWORD_PTR ret = 0;
|
2005-09-05 21:19:23 +00:00
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetThreadState\n");
|
2006-04-05 08:05:55 +00:00
|
|
|
if (Routine != THREADSTATE_GETTHREADINFO)
|
|
|
|
{
|
|
|
|
UserEnterShared();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
UserEnterExclusive();
|
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2003-11-30 20:03:47 +00:00
|
|
|
switch (Routine)
|
|
|
|
{
|
2006-04-05 08:05:55 +00:00
|
|
|
case THREADSTATE_GETTHREADINFO:
|
|
|
|
GetW32ThreadInfo();
|
2010-01-05 19:26:32 +00:00
|
|
|
break;
|
2006-04-05 08:05:55 +00:00
|
|
|
case THREADSTATE_FOCUSWINDOW:
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = (DWORD_PTR)IntGetThreadFocusWindow();
|
|
|
|
break;
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
case THREADSTATE_CAPTUREWINDOW:
|
|
|
|
/* FIXME should use UserEnterShared */
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = (DWORD_PTR)IntGetCapture();
|
|
|
|
break;
|
2006-07-22 16:50:23 +00:00
|
|
|
case THREADSTATE_PROGMANWINDOW:
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hProgmanWindow;
|
|
|
|
break;
|
2006-07-22 16:50:23 +00:00
|
|
|
case THREADSTATE_TASKMANWINDOW:
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = (DWORD_PTR)GetW32ThreadInfo()->pDeskInfo->hTaskManWindow;
|
|
|
|
break;
|
Patch by Stefan Ginsberg (stefan__100__ AT hotmail DOT com):
- remove NtUserEnumClipboardFormats, use ->ONEPARAM_ROUTINE_ENUMCLIPBOARDFORMAT insetad
- remove NtUserRegisterClipboardFormat, use NtUserRegisterWIndowsMessage instead
- remove NtUserKillSystemTimer, use HWNDPARAM_ROUTINE_KILLSYSTEMTIMER instead
- remove NtUserInsertMenuItem, use NtUserThunkedMenuItemInfo instead
- remove NtUserGetCapture, use THREADSTATE_CAPTUREWINDOW instead
- remove NtUserGetActiveWindow, use THREADSTATE_ACTIVEWINDOW instead
- remove NtUserGetQueueStatus, use ONEPARAM_ROUTIME_GETQUEUESTATUS instead
- remove NtUserGetLastActivePopup, wasn't implemented
- remove NtUserRealizePalette from ntuser.h, it's not implemented
- remove duplicate NtUserGetLastInputInfo from ntuser.h
- remove PrivateCsrssRergisterPrimitive from user32, it was unused and unimplemented
- remove NtUserDereferenceWndprocHandle, it was unused
- move WNDPROC_INFO structure from ntuser.h to win32k/include/class.h, as it's not used in usermode anymore
tested with AbiWord and FF on VMWare
svn path=/trunk/; revision=32825
2008-04-03 02:13:34 +00:00
|
|
|
case THREADSTATE_ACTIVEWINDOW:
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = (DWORD_PTR)UserGetActiveWindow();
|
|
|
|
break;
|
2009-05-06 18:49:53 +00:00
|
|
|
case THREADSTATE_INSENDMESSAGE:
|
|
|
|
{
|
|
|
|
PUSER_MESSAGE_QUEUE MessageQueue =
|
|
|
|
((PTHREADINFO)PsGetCurrentThreadWin32Thread())->MessageQueue;
|
|
|
|
DPRINT1("THREADSTATE_INSENDMESSAGE\n");
|
|
|
|
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = ISMEX_NOSEND;
|
2009-05-06 18:49:53 +00:00
|
|
|
if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
|
|
|
|
{
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = ISMEX_SEND;
|
2009-05-06 18:49:53 +00:00
|
|
|
}
|
|
|
|
else if (!IsListEmpty(&MessageQueue->NotifyMessagesListHead))
|
|
|
|
{
|
|
|
|
/* FIXME Need to set message flag when in callback mode with notify */
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = ISMEX_NOTIFY;
|
2009-05-06 18:49:53 +00:00
|
|
|
}
|
|
|
|
/* FIXME Need to set message flag if replied to or ReplyMessage */
|
2010-01-05 19:26:32 +00:00
|
|
|
break;
|
2009-05-06 18:49:53 +00:00
|
|
|
}
|
|
|
|
case THREADSTATE_GETMESSAGETIME:
|
|
|
|
/* FIXME Needs more work! */
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = ((PTHREADINFO)PsGetCurrentThreadWin32Thread())->timeLast;
|
|
|
|
break;
|
2009-05-19 15:47:16 +00:00
|
|
|
|
|
|
|
case THREADSTATE_GETINPUTSTATE:
|
2010-01-05 19:26:32 +00:00
|
|
|
ret = HIWORD(IntGetQueueStatus(FALSE)) & (QS_KEY | QS_MOUSEBUTTON);
|
|
|
|
break;
|
2003-11-30 20:03:47 +00:00
|
|
|
}
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2010-01-05 19:26:32 +00:00
|
|
|
DPRINT("Leave NtUserGetThreadState, ret=%i\n", ret);
|
2005-09-05 21:19:23 +00:00
|
|
|
UserLeave();
|
2010-01-05 19:26:32 +00:00
|
|
|
|
|
|
|
return ret;
|
2003-11-30 20:03:47 +00:00
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
|
2003-09-12 12:54:26 +00:00
|
|
|
UINT
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2003-09-12 12:54:26 +00:00
|
|
|
NtUserGetDoubleClickTime(VOID)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
UINT Result;
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetDoubleClickTime\n");
|
|
|
|
UserEnterShared();
|
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
// FIXME: Check if this works on non-interactive winsta
|
|
|
|
Result = gspv.iDblClickTime;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
2009-06-25 02:43:38 +00:00
|
|
|
DPRINT("Leave NtUserGetDoubleClickTime, ret=%i\n", Result);
|
2005-09-07 21:25:42 +00:00
|
|
|
UserLeave();
|
2009-06-25 02:43:38 +00:00
|
|
|
return Result;
|
2003-09-12 12:54:26 +00:00
|
|
|
}
|
|
|
|
|
2003-11-18 23:33:31 +00:00
|
|
|
BOOL
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2003-11-18 23:33:31 +00:00
|
|
|
NtUserGetGUIThreadInfo(
|
2005-09-07 21:25:42 +00:00
|
|
|
DWORD idThread, /* if NULL use foreground thread */
|
|
|
|
LPGUITHREADINFO lpgui)
|
2003-11-18 23:33:31 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PTHRDCARETINFO CaretInfo;
|
|
|
|
GUITHREADINFO SafeGui;
|
2008-10-17 13:09:56 +00:00
|
|
|
PDESKTOP Desktop;
|
2005-09-07 21:25:42 +00:00
|
|
|
PUSER_MESSAGE_QUEUE MsgQueue;
|
|
|
|
PETHREAD Thread = NULL;
|
|
|
|
DECLARE_RETURN(BOOLEAN);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetGUIThreadInfo\n");
|
|
|
|
UserEnterShared();
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(&SafeGui, lpgui, sizeof(DWORD));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(SafeGui.cbSize != sizeof(GUITHREADINFO))
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN( FALSE);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(idThread)
|
|
|
|
{
|
2010-01-05 19:26:32 +00:00
|
|
|
Status = PsLookupThreadByThreadId((HANDLE)(DWORD_PTR)idThread, &Thread);
|
2005-09-07 21:25:42 +00:00
|
|
|
if(!NT_SUCCESS(Status))
|
2003-11-18 23:33:31 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
|
|
RETURN( FALSE);
|
2003-11-18 23:33:31 +00:00
|
|
|
}
|
2010-01-14 02:52:12 +00:00
|
|
|
Desktop = ((PTHREADINFO)Thread->Tcb.Win32Thread)->rpdesk;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* get the foreground thread */
|
2008-10-16 17:52:38 +00:00
|
|
|
PTHREADINFO W32Thread = (PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread;
|
2010-01-14 02:52:12 +00:00
|
|
|
Desktop = W32Thread->rpdesk;
|
2005-09-07 21:25:42 +00:00
|
|
|
if(Desktop)
|
|
|
|
{
|
|
|
|
MsgQueue = Desktop->ActiveMessageQueue;
|
|
|
|
if(MsgQueue)
|
|
|
|
{
|
|
|
|
Thread = MsgQueue->Thread;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
if(!Thread || !Desktop)
|
|
|
|
{
|
|
|
|
if(idThread && Thread)
|
|
|
|
ObDereferenceObject(Thread);
|
|
|
|
SetLastWin32Error(ERROR_ACCESS_DENIED);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
MsgQueue = (PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue;
|
|
|
|
CaretInfo = MsgQueue->CaretInfo;
|
|
|
|
|
|
|
|
SafeGui.flags = (CaretInfo->Visible ? GUI_CARETBLINKING : 0);
|
|
|
|
if(MsgQueue->MenuOwner)
|
|
|
|
SafeGui.flags |= GUI_INMENUMODE | MsgQueue->MenuState;
|
|
|
|
if(MsgQueue->MoveSize)
|
|
|
|
SafeGui.flags |= GUI_INMOVESIZE;
|
|
|
|
|
|
|
|
/* FIXME add flag GUI_16BITTASK */
|
|
|
|
|
|
|
|
SafeGui.hwndActive = MsgQueue->ActiveWindow;
|
|
|
|
SafeGui.hwndFocus = MsgQueue->FocusWindow;
|
|
|
|
SafeGui.hwndCapture = MsgQueue->CaptureWindow;
|
|
|
|
SafeGui.hwndMenuOwner = MsgQueue->MenuOwner;
|
|
|
|
SafeGui.hwndMoveSize = MsgQueue->MoveSize;
|
|
|
|
SafeGui.hwndCaret = CaretInfo->hWnd;
|
|
|
|
|
|
|
|
SafeGui.rcCaret.left = CaretInfo->Pos.x;
|
|
|
|
SafeGui.rcCaret.top = CaretInfo->Pos.y;
|
|
|
|
SafeGui.rcCaret.right = SafeGui.rcCaret.left + CaretInfo->Size.cx;
|
|
|
|
SafeGui.rcCaret.bottom = SafeGui.rcCaret.top + CaretInfo->Size.cy;
|
|
|
|
|
|
|
|
if(idThread)
|
2003-11-23 13:46:33 +00:00
|
|
|
ObDereferenceObject(Thread);
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
Status = MmCopyToCaller(lpgui, &SafeGui, sizeof(GUITHREADINFO));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
RETURN( TRUE);
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetGUIThreadInfo, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-11-18 23:33:31 +00:00
|
|
|
}
|
|
|
|
|
2003-11-19 12:25:03 +00:00
|
|
|
|
|
|
|
DWORD
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2003-11-19 12:25:03 +00:00
|
|
|
NtUserGetGuiResources(
|
2005-09-07 21:25:42 +00:00
|
|
|
HANDLE hProcess,
|
|
|
|
DWORD uiFlags)
|
2003-11-19 12:25:03 +00:00
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
PEPROCESS Process;
|
2009-07-26 16:17:50 +00:00
|
|
|
PPROCESSINFO W32Process;
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
DWORD Ret = 0;
|
|
|
|
DECLARE_RETURN(DWORD);
|
|
|
|
|
|
|
|
DPRINT("Enter NtUserGetGuiResources\n");
|
|
|
|
UserEnterShared();
|
|
|
|
|
|
|
|
Status = ObReferenceObjectByHandle(hProcess,
|
|
|
|
PROCESS_QUERY_INFORMATION,
|
|
|
|
PsProcessType,
|
|
|
|
ExGetPreviousMode(),
|
|
|
|
(PVOID*)&Process,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
RETURN( 0);
|
|
|
|
}
|
|
|
|
|
2009-07-26 16:17:50 +00:00
|
|
|
W32Process = (PPROCESSINFO)Process->Win32Process;
|
2005-09-07 21:25:42 +00:00
|
|
|
if(!W32Process)
|
|
|
|
{
|
|
|
|
ObDereferenceObject(Process);
|
2003-11-19 12:25:03 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
2005-09-07 21:25:42 +00:00
|
|
|
RETURN( 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch(uiFlags)
|
|
|
|
{
|
|
|
|
case GR_GDIOBJECTS:
|
|
|
|
{
|
2009-03-30 03:56:53 +00:00
|
|
|
Ret = (DWORD)W32Process->GDIHandleCount;
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case GR_USEROBJECTS:
|
|
|
|
{
|
2009-03-30 03:56:53 +00:00
|
|
|
Ret = (DWORD)W32Process->UserHandleCount;
|
2005-09-07 21:25:42 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
ObDereferenceObject(Process);
|
|
|
|
|
|
|
|
RETURN( Ret);
|
2003-11-19 12:25:03 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
2005-09-07 21:25:42 +00:00
|
|
|
DPRINT("Leave NtUserGetGuiResources, ret=%i\n",_ret_);
|
|
|
|
UserLeave();
|
|
|
|
END_CLEANUP;
|
2003-11-19 12:25:03 +00:00
|
|
|
}
|
|
|
|
|
2003-12-13 15:49:32 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
|
|
|
|
PUNICODE_STRING Source)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PWSTR Src;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2003-12-13 15:49:32 +00:00
|
|
|
return Status;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(Dest->Length > 0x4000)
|
|
|
|
{
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Src = Dest->Buffer;
|
|
|
|
Dest->Buffer = NULL;
|
2007-12-04 22:52:05 +00:00
|
|
|
Dest->MaximumLength = Dest->Length;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
if(Dest->Length > 0 && Src)
|
|
|
|
{
|
|
|
|
Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
|
|
|
|
if(!Dest->Buffer)
|
|
|
|
{
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2008-11-04 23:49:07 +00:00
|
|
|
ExFreePoolWithTag(Dest->Buffer, TAG_STRING);
|
2005-09-07 21:25:42 +00:00
|
|
|
Dest->Buffer = NULL;
|
|
|
|
return Status;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* string is empty */
|
|
|
|
return STATUS_SUCCESS;
|
2003-12-13 15:49:32 +00:00
|
|
|
}
|
|
|
|
|
2004-05-19 19:09:20 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
|
|
|
|
PUNICODE_STRING Source)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
PWSTR Src;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
Status = MmCopyFromCaller(Dest, Source, sizeof(UNICODE_STRING));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-05-19 19:09:20 +00:00
|
|
|
return Status;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(Dest->Length > 0x4000)
|
|
|
|
{
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
|
|
|
Src = Dest->Buffer;
|
|
|
|
Dest->Buffer = NULL;
|
2007-12-04 22:52:05 +00:00
|
|
|
Dest->MaximumLength = 0;
|
2005-09-07 21:25:42 +00:00
|
|
|
|
|
|
|
if(Dest->Length > 0 && Src)
|
|
|
|
{
|
|
|
|
Dest->MaximumLength = Dest->Length + sizeof(WCHAR);
|
|
|
|
Dest->Buffer = ExAllocatePoolWithTag(PagedPool, Dest->MaximumLength, TAG_STRING);
|
|
|
|
if(!Dest->Buffer)
|
|
|
|
{
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = MmCopyFromCaller(Dest->Buffer, Src, Dest->Length);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2008-11-04 23:49:07 +00:00
|
|
|
ExFreePoolWithTag(Dest->Buffer, TAG_STRING);
|
2005-09-07 21:25:42 +00:00
|
|
|
Dest->Buffer = NULL;
|
|
|
|
return Status;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* make sure the string is null-terminated */
|
|
|
|
Src = (PWSTR)((PBYTE)Dest->Buffer + Dest->Length);
|
|
|
|
*Src = L'\0';
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
/* string is empty */
|
|
|
|
return STATUS_SUCCESS;
|
2004-05-19 19:09:20 +00:00
|
|
|
}
|
|
|
|
|
2004-06-16 06:09:40 +00:00
|
|
|
NTSTATUS FASTCALL
|
|
|
|
IntUnicodeStringToNULLTerminated(PWSTR *Dest, PUNICODE_STRING Src)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
if (Src->Length + sizeof(WCHAR) <= Src->MaximumLength
|
|
|
|
&& L'\0' == Src->Buffer[Src->Length / sizeof(WCHAR)])
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
/* The unicode_string is already nul terminated. Just reuse it. */
|
|
|
|
*Dest = Src->Buffer;
|
|
|
|
return STATUS_SUCCESS;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
*Dest = ExAllocatePoolWithTag(PagedPool, Src->Length + sizeof(WCHAR), TAG_STRING);
|
|
|
|
if (NULL == *Dest)
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
return STATUS_NO_MEMORY;
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
|
|
|
RtlCopyMemory(*Dest, Src->Buffer, Src->Length);
|
|
|
|
(*Dest)[Src->Length / 2] = L'\0';
|
2004-06-16 06:09:40 +00:00
|
|
|
|
2005-09-07 21:25:42 +00:00
|
|
|
return STATUS_SUCCESS;
|
2004-06-16 06:09:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void FASTCALL
|
|
|
|
IntFreeNULLTerminatedFromUnicodeString(PWSTR NullTerminated, PUNICODE_STRING UnicodeString)
|
|
|
|
{
|
2005-09-07 21:25:42 +00:00
|
|
|
if (NullTerminated != UnicodeString->Buffer)
|
|
|
|
{
|
2004-06-16 06:09:40 +00:00
|
|
|
ExFreePool(NullTerminated);
|
2005-09-07 21:25:42 +00:00
|
|
|
}
|
2004-06-16 06:09:40 +00:00
|
|
|
}
|
|
|
|
|
2009-03-30 05:45:08 +00:00
|
|
|
PPROCESSINFO
|
2006-04-05 08:05:55 +00:00
|
|
|
GetW32ProcessInfo(VOID)
|
|
|
|
{
|
2009-05-23 00:57:51 +00:00
|
|
|
return (PPROCESSINFO)PsGetCurrentProcessWin32Process();
|
2006-04-05 08:05:55 +00:00
|
|
|
}
|
|
|
|
|
2009-08-16 21:44:59 +00:00
|
|
|
PTHREADINFO
|
2006-04-05 08:05:55 +00:00
|
|
|
GetW32ThreadInfo(VOID)
|
|
|
|
{
|
|
|
|
PTEB Teb;
|
2009-05-13 21:32:10 +00:00
|
|
|
PPROCESSINFO ppi;
|
|
|
|
PCLIENTINFO pci;
|
|
|
|
PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2009-05-13 21:32:10 +00:00
|
|
|
if (pti == NULL)
|
2006-04-05 08:05:55 +00:00
|
|
|
{
|
|
|
|
/* FIXME - temporary hack for system threads... */
|
|
|
|
return NULL;
|
|
|
|
}
|
2009-08-16 21:44:59 +00:00
|
|
|
/* initialize it */
|
|
|
|
pti->ppi = ppi = GetW32ProcessInfo();
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2009-08-16 21:44:59 +00:00
|
|
|
pti->pcti = &pti->cti; // FIXME Need to set it in desktop.c!
|
|
|
|
|
2010-01-14 02:52:12 +00:00
|
|
|
if (pti->rpdesk != NULL)
|
2006-04-05 08:05:55 +00:00
|
|
|
{
|
2010-01-14 02:52:12 +00:00
|
|
|
pti->pDeskInfo = pti->rpdesk->pDeskInfo;
|
2009-08-16 21:44:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pti->pDeskInfo = NULL;
|
|
|
|
}
|
|
|
|
/* update the TEB */
|
|
|
|
Teb = NtCurrentTeb();
|
|
|
|
pci = GetWin32ClientInfo();
|
|
|
|
pti->pClientInfo = pci;
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite( Teb,
|
|
|
|
sizeof(TEB),
|
|
|
|
sizeof(ULONG));
|
|
|
|
|
|
|
|
Teb->Win32ThreadInfo = (PW32THREAD) pti;
|
|
|
|
|
|
|
|
pci->pClientThreadInfo = NULL; // FIXME Need to set it in desktop.c!
|
|
|
|
pci->ppi = ppi;
|
|
|
|
pci->fsHooks = pti->fsHooks;
|
2009-10-10 21:51:24 +00:00
|
|
|
if (pti->KeyboardLayout) pci->hKL = pti->KeyboardLayout->hkl;
|
2009-10-27 19:02:02 +00:00
|
|
|
pci->dwTIFlags = pti->TIF_flags;
|
2009-08-16 21:44:59 +00:00
|
|
|
/* CI may not have been initialized. */
|
|
|
|
if (!pci->pDeskInfo && pti->pDeskInfo)
|
2006-04-05 08:05:55 +00:00
|
|
|
{
|
2009-08-16 21:44:59 +00:00
|
|
|
if (!pci->ulClientDelta) pci->ulClientDelta = DesktopHeapGetUserDelta();
|
|
|
|
|
|
|
|
pci->pDeskInfo = (PVOID)((ULONG_PTR)pti->pDeskInfo - pci->ulClientDelta);
|
2006-04-05 08:05:55 +00:00
|
|
|
}
|
|
|
|
}
|
2009-08-16 21:44:59 +00:00
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
SetLastNtError(_SEH2_GetExceptionCode());
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2009-08-16 21:44:59 +00:00
|
|
|
return pti;
|
2006-04-05 08:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-06-16 06:09:40 +00:00
|
|
|
/* EOF */
|