mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 09:00:27 +00:00
- Rewrite Desktop/WindowsStation parsing to follow the NT Object Model, with some minor hacks to respect ROS's current parsing semantics.
- Thanks to this, the long-lasting ExpDesktopCreate hack is gone, and so is OB_ROS_FIND_METHOD and OB_ROS_CREATE_METHOD in win32k. Next patch can fully remove WIN32_CALLOUT_DATA and use the NT type instead. - Add official OBJECT_ macros in obtypes.h svn path=/trunk/; revision=22041
This commit is contained in:
parent
befa307429
commit
cf356e801d
11 changed files with 257 additions and 263 deletions
|
@ -87,6 +87,22 @@ Author:
|
|||
#define OB_FLAG_SECURITY 0x20
|
||||
#define OB_FLAG_SINGLE_PROCESS 0x40
|
||||
|
||||
#define OBJECT_TO_OBJECT_HEADER(o) \
|
||||
CONTAINING_RECORD((o), OBJECT_HEADER, Body)
|
||||
|
||||
#define OBJECT_HEADER_TO_NAME_INFO(h) \
|
||||
((POBJECT_HEADER_NAME_INFO)(!(h)->NameInfoOffset ? \
|
||||
NULL: ((PCHAR)(h) - (h)->NameInfoOffset)))
|
||||
|
||||
#define OBJECT_HEADER_TO_HANDLE_INFO(h) \
|
||||
((POBJECT_HEADER_HANDLE_INFO)(!(h)->HandleInfoOffset ? \
|
||||
NULL: ((PCHAR)(h) - (h)->HandleInfoOffset)))
|
||||
|
||||
#define OBJECT_HEADER_TO_CREATOR_INFO(h) \
|
||||
((POBJECT_HEADER_CREATOR_INFO)(!((h)->Flags & \
|
||||
OB_FLAG_CREATOR_INFO) ? NULL: ((PCHAR)(h) - \
|
||||
sizeof(OBJECT_HEADER_CREATOR_INFO))))
|
||||
|
||||
//
|
||||
// Reasons for Open Callback
|
||||
//
|
||||
|
|
|
@ -12,8 +12,7 @@ typedef struct _W32_CALLOUT_DATA
|
|||
OB_DELETE_METHOD WinStaDelete;
|
||||
OB_PARSE_METHOD WinStaParse;
|
||||
OB_OPEN_METHOD WinStaOpen;
|
||||
OB_ROS_FIND_METHOD WinStaFind;
|
||||
OB_ROS_CREATE_METHOD DesktopCreate;
|
||||
OB_PARSE_METHOD DesktopParse;
|
||||
} W32_CALLOUT_DATA, *PW32_CALLOUT_DATA;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -38,8 +38,7 @@ static GENERIC_MAPPING ExpDesktopMapping =
|
|||
OB_OPEN_METHOD ExpWindowStationObjectOpen = NULL;
|
||||
OB_PARSE_METHOD ExpWindowStationObjectParse = NULL;
|
||||
OB_DELETE_METHOD ExpWindowStationObjectDelete = NULL;
|
||||
OB_ROS_FIND_METHOD ExpWindowStationObjectFind = NULL;
|
||||
OB_ROS_CREATE_METHOD ExpDesktopObjectCreate = NULL;
|
||||
OB_PARSE_METHOD ExpDesktopObjectParse = NULL;
|
||||
OB_DELETE_METHOD ExpDesktopObjectDelete = NULL;
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
@ -47,17 +46,17 @@ OB_DELETE_METHOD ExpDesktopObjectDelete = NULL;
|
|||
NTSTATUS
|
||||
STDCALL
|
||||
ExpWinStaObjectOpen(OB_OPEN_REASON Reason,
|
||||
PVOID ObjectBody,
|
||||
PEPROCESS Process,
|
||||
ULONG HandleCount,
|
||||
ACCESS_MASK GrantedAccess)
|
||||
PVOID ObjectBody,
|
||||
ACCESS_MASK GrantedAccess,
|
||||
ULONG HandleCount)
|
||||
{
|
||||
/* Call the Registered Callback */
|
||||
return ExpWindowStationObjectOpen(Reason,
|
||||
ObjectBody,
|
||||
Process,
|
||||
HandleCount,
|
||||
GrantedAccess);
|
||||
ObjectBody,
|
||||
GrantedAccess,
|
||||
HandleCount);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -68,18 +67,6 @@ ExpWinStaObjectDelete(PVOID DeletedObject)
|
|||
ExpWindowStationObjectDelete(DeletedObject);
|
||||
}
|
||||
|
||||
PVOID
|
||||
STDCALL
|
||||
ExpWinStaObjectFind(PVOID WinStaObject,
|
||||
PWSTR Name,
|
||||
ULONG Attributes)
|
||||
{
|
||||
/* Call the Registered Callback */
|
||||
return ExpWindowStationObjectFind(WinStaObject,
|
||||
Name,
|
||||
Attributes);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ExpWinStaObjectParse(IN PVOID ParseObject,
|
||||
|
@ -105,21 +92,6 @@ ExpWinStaObjectParse(IN PVOID ParseObject,
|
|||
SecurityQos,
|
||||
Object);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ExpDesktopCreate(PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
POBJECT_ATTRIBUTES ObjectAttributes)
|
||||
{
|
||||
/* Call the Registered Callback */
|
||||
return ExpDesktopObjectCreate(ObjectBody,
|
||||
Parent,
|
||||
RemainingPath,
|
||||
ObjectAttributes);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
ExpDesktopDelete(PVOID DeletedObject)
|
||||
|
@ -143,9 +115,9 @@ ExpWin32kInit(VOID)
|
|||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||
ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping;
|
||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||
ObjectTypeInitializer.OpenProcedure = (OB_OPEN_METHOD)ExpWinStaObjectOpen;
|
||||
ObjectTypeInitializer.OpenProcedure = ExpWinStaObjectOpen;
|
||||
ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete;
|
||||
ObjectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD)ExpWinStaObjectParse;
|
||||
ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse;
|
||||
ObpCreateTypeObject(&ObjectTypeInitializer,
|
||||
&Name,
|
||||
&ExWindowStationObjectType);
|
||||
|
|
|
@ -53,13 +53,6 @@ typedef NTSTATUS
|
|||
struct _OBJECT_ATTRIBUTES* ObjectAttributes
|
||||
);
|
||||
|
||||
typedef PVOID
|
||||
(NTAPI *OB_ROS_FIND_METHOD)(
|
||||
PVOID WinStaObject,
|
||||
PWSTR Name,
|
||||
ULONG Attributes
|
||||
);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ObpDeleteEntryDirectory(POBP_LOOKUP_CONTEXT Context);
|
||||
|
|
|
@ -19,14 +19,6 @@
|
|||
|
||||
PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
||||
|
||||
/* TEMPORARY HACK. DO NOT REMOVE -- Alex */
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
ExpDesktopCreate(PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
POBJECT_CREATE_INFORMATION ObjectCreateInformation);
|
||||
|
||||
/* PRIVATE FUNCTIONS *********************************************************/
|
||||
|
||||
/*++
|
||||
|
@ -1012,7 +1004,6 @@ ObInsertObject(IN PVOID Object,
|
|||
}
|
||||
|
||||
if ((Header->Type == IoFileObjectType) ||
|
||||
(Header->Type == ExDesktopObjectType) ||
|
||||
(Header->Type->TypeInfo.OpenProcedure != NULL))
|
||||
{
|
||||
DPRINT("About to call Open Routine\n");
|
||||
|
@ -1027,15 +1018,6 @@ ObInsertObject(IN PVOID Object,
|
|||
DPRINT("Called IopCreateFile: %x\n", Status);
|
||||
|
||||
}
|
||||
else if (Header->Type == ExDesktopObjectType)
|
||||
{
|
||||
/* TEMPORARY HACK. DO NOT TOUCH -- Alex */
|
||||
DPRINT("Calling ExpDesktopCreate\n");
|
||||
Status = ExpDesktopCreate(&Header->Body,
|
||||
FoundObject,
|
||||
RemainingPath.Buffer,
|
||||
ObjectCreateInfo);
|
||||
}
|
||||
else if (Header->Type->TypeInfo.OpenProcedure != NULL)
|
||||
{
|
||||
DPRINT("Calling %x\n", Header->Type->TypeInfo.OpenProcedure);
|
||||
|
|
|
@ -176,13 +176,13 @@ Next:
|
|||
RtlInitUnicodeString(&CurrentUs, current);
|
||||
Status = CurrentHeader->Type->TypeInfo.ParseProcedure(CurrentObject,
|
||||
CurrentHeader->Type,
|
||||
NULL,
|
||||
ExGetPreviousMode(),
|
||||
AccessState,
|
||||
ExGetPreviousMode(), // fixme: should be a parameter, since caller decides.
|
||||
Attributes,
|
||||
&PathString,
|
||||
&CurrentUs,
|
||||
NULL,
|
||||
NULL,
|
||||
ParseContext,
|
||||
NULL, // fixme: where do we get this from? captured OBP?
|
||||
&NextObject);
|
||||
current = CurrentUs.Buffer;
|
||||
if (Status == STATUS_REPARSE)
|
||||
|
|
|
@ -23,8 +23,7 @@ static PKWIN32_THREAD_CALLOUT PspWin32ThreadCallback = NULL;
|
|||
extern OB_OPEN_METHOD ExpWindowStationObjectOpen;
|
||||
extern OB_PARSE_METHOD ExpWindowStationObjectParse;
|
||||
extern OB_DELETE_METHOD ExpWindowStationObjectDelete;
|
||||
extern OB_ROS_FIND_METHOD ExpWindowStationObjectFind;
|
||||
extern OB_ROS_CREATE_METHOD ExpDesktopObjectCreate;
|
||||
extern OB_PARSE_METHOD ExpDesktopObjectParse;
|
||||
extern OB_DELETE_METHOD ExpDesktopObjectDelete;
|
||||
|
||||
#ifndef ALEX_CB_REWRITE
|
||||
|
@ -64,8 +63,7 @@ PsEstablishWin32Callouts(PWIN32_CALLOUTS_FPNS calloutData)
|
|||
ExpWindowStationObjectOpen = CalloutData->WinStaOpen;
|
||||
ExpWindowStationObjectParse = CalloutData->WinStaParse;
|
||||
ExpWindowStationObjectDelete = CalloutData->WinStaDelete;
|
||||
ExpWindowStationObjectFind = CalloutData->WinStaFind;
|
||||
ExpDesktopObjectCreate = CalloutData->DesktopCreate;
|
||||
ExpDesktopObjectParse = CalloutData->DesktopParse;
|
||||
ExpDesktopObjectDelete = CalloutData->DesktopDelete;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ typedef struct _DESKTOP_OBJECT
|
|||
CSHORT Size;
|
||||
LIST_ENTRY ListEntry;
|
||||
|
||||
UNICODE_STRING Name;
|
||||
/* Pointer to the associated window station. */
|
||||
struct _WINSTATION_OBJECT *WindowStation;
|
||||
/* Pointer to the active queue. */
|
||||
|
@ -48,11 +47,18 @@ InitDesktopImpl(VOID);
|
|||
NTSTATUS FASTCALL
|
||||
CleanupDesktopImpl(VOID);
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntDesktopObjectCreate(PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
struct _OBJECT_ATTRIBUTES* ObjectAttributes);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IntDesktopObjectParse(IN PVOID ParseObject,
|
||||
IN PVOID ObjectType,
|
||||
IN OUT PACCESS_STATE AccessState,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN ULONG Attributes,
|
||||
IN OUT PUNICODE_STRING CompleteName,
|
||||
IN OUT PUNICODE_STRING RemainingName,
|
||||
IN OUT PVOID Context OPTIONAL,
|
||||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
||||
OUT PVOID *Object);
|
||||
|
||||
VOID STDCALL
|
||||
IntDesktopObjectDelete(PVOID DeletedObject);
|
||||
|
@ -120,6 +126,12 @@ VOID co_IntShellHookNotify(WPARAM Message, LPARAM lParam);
|
|||
#define IntIsActiveDesktop(Desktop) \
|
||||
((Desktop)->WindowStation->ActiveDesktop == (Desktop))
|
||||
|
||||
#define GET_DESKTOP_NAME(d) \
|
||||
OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(d)) ? \
|
||||
&(OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(d))->Name) : \
|
||||
NULL
|
||||
|
||||
|
||||
static __inline PVOID
|
||||
DesktopHeapAlloc(IN PDESKTOP Desktop,
|
||||
IN SIZE_T Bytes)
|
||||
|
|
|
@ -384,8 +384,7 @@ DriverEntry (
|
|||
CalloutData.WinStaOpen = IntWinStaObjectOpen;
|
||||
CalloutData.WinStaParse = IntWinStaObjectParse;
|
||||
CalloutData.WinStaDelete = IntWinStaObjectDelete;
|
||||
CalloutData.WinStaFind = IntWinStaObjectFind;
|
||||
CalloutData.DesktopCreate = IntDesktopObjectCreate;
|
||||
CalloutData.DesktopParse = IntDesktopObjectParse;
|
||||
CalloutData.DesktopDelete = IntDesktopObjectDelete;
|
||||
CalloutData.W32ProcessCallout = Win32kProcessCallback;
|
||||
CalloutData.W32ThreadCallout = Win32kThreadCallback;
|
||||
|
|
|
@ -34,82 +34,143 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static
|
||||
VOID
|
||||
IntFreeDesktopHeap(
|
||||
IN OUT PDESKTOP_OBJECT Desktop
|
||||
);
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* Currently active desktop */
|
||||
PDESKTOP_OBJECT InputDesktop = NULL;
|
||||
HDESK InputDesktopHandle = NULL;
|
||||
HDC ScreenDeviceContext = NULL;
|
||||
|
||||
BOOL g_PaintDesktopVersion = FALSE;
|
||||
|
||||
static VOID IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop);
|
||||
|
||||
/* INITALIZATION FUNCTIONS ****************************************************/
|
||||
|
||||
static GENERIC_MAPPING IntDesktopMapping =
|
||||
{
|
||||
STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS,
|
||||
STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS,
|
||||
GENERIC_MAPPING IntDesktopMapping =
|
||||
{
|
||||
STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE |
|
||||
DESKTOP_READOBJECTS,
|
||||
STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU |
|
||||
DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_JOURNALPLAYBACK |
|
||||
DESKTOP_JOURNALRECORD |
|
||||
DESKTOP_WRITEOBJECTS,
|
||||
STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP,
|
||||
STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE |
|
||||
DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
|
||||
DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS
|
||||
};
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
InitDesktopImpl(VOID)
|
||||
{
|
||||
/* Set Desktop Object Attributes */
|
||||
ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP_OBJECT);
|
||||
ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS FASTCALL
|
||||
CleanupDesktopImpl(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU |
|
||||
DESKTOP_CREATEWINDOW |
|
||||
DESKTOP_ENUMERATE |
|
||||
DESKTOP_HOOKCONTROL |
|
||||
DESKTOP_JOURNALPLAYBACK |
|
||||
DESKTOP_JOURNALRECORD |
|
||||
DESKTOP_READOBJECTS |
|
||||
DESKTOP_SWITCHDESKTOP |
|
||||
DESKTOP_WRITEOBJECTS
|
||||
};
|
||||
|
||||
/* OBJECT CALLBACKS **********************************************************/
|
||||
|
||||
NTSTATUS STDCALL
|
||||
IntDesktopObjectCreate(PVOID ObjectBody,
|
||||
PVOID Parent,
|
||||
PWSTR RemainingPath,
|
||||
struct _OBJECT_ATTRIBUTES* ObjectAttributes)
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
IntDesktopObjectParse(IN PVOID ParseObject,
|
||||
IN PVOID ObjectType,
|
||||
IN OUT PACCESS_STATE AccessState,
|
||||
IN KPROCESSOR_MODE AccessMode,
|
||||
IN ULONG Attributes,
|
||||
IN OUT PUNICODE_STRING CompleteName,
|
||||
IN OUT PUNICODE_STRING RemainingName,
|
||||
IN OUT PVOID Context OPTIONAL,
|
||||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
||||
OUT PVOID *Object)
|
||||
{
|
||||
PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody;
|
||||
UNICODE_STRING UnicodeString;
|
||||
NTSTATUS Status;
|
||||
PDESKTOP_OBJECT Desktop;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PLIST_ENTRY NextEntry, ListHead;
|
||||
PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)ParseObject;
|
||||
PUNICODE_STRING DesktopName;
|
||||
|
||||
DPRINT("Creating desktop (0x%X) Name (%S)\n", Desktop, RemainingPath);
|
||||
if (RemainingPath == NULL)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* Set the list pointers and loop the window station */
|
||||
DPRINT1("Creating desktop(%wZ)\n", RemainingName);
|
||||
ListHead = &WinStaObject->DesktopListHead;
|
||||
NextEntry = ListHead->Flink;
|
||||
while (NextEntry != ListHead)
|
||||
{
|
||||
/* Get the current desktop */
|
||||
Desktop = CONTAINING_RECORD(NextEntry, DESKTOP_OBJECT, ListEntry);
|
||||
|
||||
if (wcschr((RemainingPath + 1), '\\') != NULL)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
/* Get its name */
|
||||
DesktopName = GET_DESKTOP_NAME(Desktop);
|
||||
if (DesktopName)
|
||||
{
|
||||
/* Compare the name */
|
||||
if (RtlEqualUnicodeString(RemainingName,
|
||||
DesktopName,
|
||||
(Attributes & OBJ_CASE_INSENSITIVE)))
|
||||
{
|
||||
/* We found a match. Did this come from a create? */
|
||||
if (Context)
|
||||
{
|
||||
/* Unless OPEN_IF was given, fail with an error */
|
||||
if (!(Attributes & OBJ_OPENIF))
|
||||
{
|
||||
/* Name collision */
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, return with a warning only */
|
||||
Status = STATUS_OBJECT_NAME_EXISTS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This was a real open, so this is OK */
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1));
|
||||
/* Reference the desktop and return it */
|
||||
ObReferenceObject(Desktop);
|
||||
*Object = Desktop;
|
||||
RemainingName->Buffer = NULL; // => ROS Parse routines need to do this
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
InitializeListHead(&Desktop->ShellHookWindows);
|
||||
/* Go to the next desktop */
|
||||
NextEntry = NextEntry->Flink;
|
||||
}
|
||||
|
||||
Desktop->WindowStation = (PWINSTATION_OBJECT)Parent;
|
||||
/* If we got here but this isn't a create, then fail */
|
||||
if (!Context) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
/* Put the desktop on the window station's list of associcated desktops */
|
||||
// ExInterlocked
|
||||
InsertTailList(
|
||||
&Desktop->WindowStation->DesktopListHead,
|
||||
&Desktop->ListEntry);//,
|
||||
// &Desktop->WindowStation->Lock);
|
||||
/* Create the desktop object */
|
||||
InitializeObjectAttributes(&ObjectAttributes, RemainingName, 0, NULL, NULL);
|
||||
Status = ObCreateObject(KernelMode,
|
||||
ExDesktopObjectType,
|
||||
&ObjectAttributes,
|
||||
UserMode,
|
||||
NULL,
|
||||
sizeof(DESKTOP_OBJECT),
|
||||
0,
|
||||
0,
|
||||
(PVOID)&Desktop);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer);
|
||||
/* Initialize shell hook window list and set the parent */
|
||||
InitializeListHead(&Desktop->ShellHookWindows);
|
||||
Desktop->WindowStation = (PWINSTATION_OBJECT)ParseObject;
|
||||
|
||||
/* Put the desktop on the window station's list of associated desktops */
|
||||
InsertTailList(&Desktop->WindowStation->DesktopListHead,
|
||||
&Desktop->ListEntry);
|
||||
|
||||
/* Set the desktop object and return success */
|
||||
*Object = Desktop;
|
||||
RemainingName->Buffer = NULL; // => ROS Parse routines need to do this
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -122,13 +183,28 @@ IntDesktopObjectDelete(PVOID DeletedObject)
|
|||
/* Remove the desktop from the window station's list of associcated desktops */
|
||||
RemoveEntryList(&Desktop->ListEntry);
|
||||
|
||||
RtlFreeUnicodeString(&Desktop->Name);
|
||||
|
||||
IntFreeDesktopHeap(Desktop);
|
||||
}
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
InitDesktopImpl(VOID)
|
||||
{
|
||||
/* Set Desktop Object Attributes */
|
||||
ExDesktopObjectType->TypeInfo.DefaultNonPagedPoolCharge = sizeof(DESKTOP_OBJECT);
|
||||
ExDesktopObjectType->TypeInfo.GenericMapping = IntDesktopMapping;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
FASTCALL
|
||||
CleanupDesktopImpl(VOID)
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int GetSystemVersionString(LPWSTR buffer)
|
||||
{
|
||||
RTL_OSVERSIONINFOEXW versionInfo;
|
||||
|
@ -736,8 +812,6 @@ IntFreeDesktopHeap(IN OUT PDESKTOP_OBJECT Desktop)
|
|||
Desktop->DesktopHeapSection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* SYSCALLS *******************************************************************/
|
||||
|
||||
|
||||
|
@ -791,6 +865,7 @@ NtUserCreateDesktop(
|
|||
PVOID DesktopHeapSystemBase = NULL;
|
||||
SIZE_T DesktopInfoSize;
|
||||
UNICODE_STRING SafeDesktopName;
|
||||
ULONG DummyContext;
|
||||
DECLARE_RETURN(HDESK);
|
||||
|
||||
|
||||
|
@ -839,7 +914,7 @@ NtUserCreateDesktop(
|
|||
* Try to open already existing desktop
|
||||
*/
|
||||
|
||||
DPRINT1("Trying to open desktop (%wZ)\n", &DesktopName);
|
||||
DPRINT("Trying to open desktop (%wZ)\n", &DesktopName);
|
||||
|
||||
/* Initialize ObjectAttributes for the desktop object */
|
||||
InitializeObjectAttributes(
|
||||
|
@ -852,41 +927,26 @@ NtUserCreateDesktop(
|
|||
Status = ObOpenObjectByName(
|
||||
&ObjectAttributes,
|
||||
ExDesktopObjectType,
|
||||
NULL,
|
||||
(PVOID)&DummyContext,
|
||||
KernelMode,
|
||||
dwDesiredAccess,
|
||||
NULL,
|
||||
(HANDLE*)&Desktop);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status)) RETURN(NULL);
|
||||
if (Status == STATUS_OBJECT_NAME_EXISTS)
|
||||
{
|
||||
DPRINT("Successfully opened desktop (%wZ)\n", &DesktopName);
|
||||
ExFreePool(DesktopName.Buffer);
|
||||
RETURN( Desktop);
|
||||
}
|
||||
|
||||
/*
|
||||
* No existing desktop found, try to create new one
|
||||
*/
|
||||
|
||||
Status = ObCreateObject(
|
||||
KernelMode,
|
||||
ExDesktopObjectType,
|
||||
&ObjectAttributes,
|
||||
ExGetPreviousMode(),
|
||||
NULL,
|
||||
sizeof(DESKTOP_OBJECT),
|
||||
0,
|
||||
0,
|
||||
(PVOID*)&DesktopObject);
|
||||
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed creating desktop (%wZ)\n", &DesktopName);
|
||||
ExFreePool(DesktopName.Buffer);
|
||||
SetLastNtError(STATUS_UNSUCCESSFUL);
|
||||
RETURN( NULL);
|
||||
}
|
||||
/* Reference the desktop */
|
||||
Status = ObReferenceObjectByHandle(Desktop,
|
||||
0,
|
||||
ExDesktopObjectType,
|
||||
KernelMode,
|
||||
(PVOID)&DesktopObject,
|
||||
NULL);
|
||||
if (!NT_SUCCESS(Status)) RETURN(NULL);
|
||||
|
||||
DesktopObject->DesktopHeapSection = NULL;
|
||||
DesktopObject->hDesktopHeap = UserCreateHeap(&DesktopObject->DesktopHeapSection,
|
||||
|
@ -930,16 +990,6 @@ NtUserCreateDesktop(
|
|||
|
||||
/* Initialize some local (to win32k) desktop state. */
|
||||
DesktopObject->ActiveMessageQueue = NULL;
|
||||
|
||||
Status = ObInsertObject(
|
||||
(PVOID)DesktopObject,
|
||||
NULL,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
0,
|
||||
NULL,
|
||||
(HANDLE*)&Desktop);
|
||||
|
||||
ObDereferenceObject(DesktopObject);
|
||||
ExFreePool(DesktopName.Buffer);
|
||||
|
||||
if (! NT_SUCCESS(Status))
|
||||
|
|
|
@ -105,7 +105,6 @@ IntWinStaObjectOpen(OB_OPEN_REASON Reason,
|
|||
PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("IntWinStaObjectOpen\n");
|
||||
|
||||
if (Reason == ObCreateHandle)
|
||||
{
|
||||
|
@ -115,10 +114,8 @@ DPRINT1("IntWinStaObjectOpen\n");
|
|||
|
||||
InitializeListHead(&WinSta->DesktopListHead);
|
||||
|
||||
DPRINT1("Create winsta atomtable\n");
|
||||
WinSta->AtomTable = NULL;
|
||||
Status = RtlCreateAtomTable(37, &WinSta->AtomTable);
|
||||
if (!NT_SUCCESS(Status)) DPRINT1("Error creating atom table\n");
|
||||
WinSta->SystemMenuTemplate = (HANDLE)0;
|
||||
|
||||
DPRINT("Window station successfully created.\n");
|
||||
|
@ -139,51 +136,6 @@ IntWinStaObjectDelete(PVOID DeletedObject)
|
|||
RtlFreeUnicodeString(&WinSta->Name);
|
||||
}
|
||||
|
||||
PVOID STDCALL
|
||||
IntWinStaObjectFind(PVOID Object,
|
||||
PWSTR Name,
|
||||
ULONG Attributes)
|
||||
{
|
||||
PLIST_ENTRY Current;
|
||||
PDESKTOP_OBJECT CurrentObject;
|
||||
PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)Object;
|
||||
|
||||
DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name);
|
||||
|
||||
if (Name[0] == 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Current = WinStaObject->DesktopListHead.Flink;
|
||||
while (Current != &WinStaObject->DesktopListHead)
|
||||
{
|
||||
CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry);
|
||||
DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name);
|
||||
if (Attributes & OBJ_CASE_INSENSITIVE)
|
||||
{
|
||||
if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0)
|
||||
{
|
||||
DPRINT("Found desktop at (0x%X)\n", CurrentObject);
|
||||
return CurrentObject;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wcscmp(CurrentObject->Name.Buffer, Name) == 0)
|
||||
{
|
||||
DPRINT("Found desktop at (0x%X)\n", CurrentObject);
|
||||
return CurrentObject;
|
||||
}
|
||||
}
|
||||
Current = Current->Flink;
|
||||
}
|
||||
|
||||
DPRINT("Returning NULL\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
IntWinStaObjectParse(IN PVOID Object,
|
||||
|
@ -197,44 +149,65 @@ IntWinStaObjectParse(IN PVOID Object,
|
|||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
|
||||
OUT PVOID *NextObject)
|
||||
{
|
||||
PWSTR *Path = &RemainingName->Buffer;
|
||||
PVOID FoundObject;
|
||||
NTSTATUS Status;
|
||||
PWSTR End;
|
||||
DPRINT("Object (0x%X) Path (0x%X) *Path (%wZ)\n", Object, RemainingName, RemainingName);
|
||||
|
||||
DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path);
|
||||
/* Assume we don't find anything */
|
||||
*NextObject = NULL;
|
||||
|
||||
*NextObject = NULL;
|
||||
/* Check for an empty name */
|
||||
if (!RemainingName->Length)
|
||||
{
|
||||
/* Make sure this is a window station, can't parse a desktop now */
|
||||
if (ObjectType != ExWindowStationObjectType)
|
||||
{
|
||||
/* Fail */
|
||||
return STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
if ((Path == NULL) || ((*Path) == NULL))
|
||||
{
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* Reference the window station and return */
|
||||
//ObReferenceObject(Object);
|
||||
//*NextObject = Object; => ROS Parse routines don't need to do this
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
End = wcschr((*Path) + 1, '\\');
|
||||
if (End != NULL)
|
||||
{
|
||||
DPRINT("Name contains illegal characters\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
/* Check for leading slash */
|
||||
if (RemainingName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR)
|
||||
{
|
||||
/* Skip it */
|
||||
RemainingName->Buffer++;
|
||||
RemainingName->Length -= sizeof(WCHAR);
|
||||
RemainingName->MaximumLength -= sizeof(WCHAR);
|
||||
}
|
||||
|
||||
FoundObject = IntWinStaObjectFind(Object, (*Path) + 1, Attributes);
|
||||
if (FoundObject == NULL)
|
||||
{
|
||||
DPRINT("Name was not found\n");
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
/* Check if there is still a slash */
|
||||
if (wcschr(RemainingName->Buffer, OBJ_NAME_PATH_SEPARATOR))
|
||||
{
|
||||
/* In this case, fail */
|
||||
return STATUS_OBJECT_PATH_INVALID;
|
||||
}
|
||||
|
||||
Status = ObReferenceObjectByPointer(
|
||||
FoundObject,
|
||||
STANDARD_RIGHTS_REQUIRED,
|
||||
NULL,
|
||||
UserMode);
|
||||
/*
|
||||
* Check if we are parsing a desktop.
|
||||
* FIXME: ROS Sends the wrong Object Type. The parsed object's type
|
||||
* should be sent, not the parsed parent's.
|
||||
*/
|
||||
if (ObjectType == ExWindowStationObjectType)
|
||||
{
|
||||
/* Then call the desktop parse routine */
|
||||
return IntDesktopObjectParse(Object,
|
||||
ObjectType,
|
||||
AccessState,
|
||||
AccessMode,
|
||||
Attributes,
|
||||
FullPath,
|
||||
RemainingName,
|
||||
Context,
|
||||
SecurityQos,
|
||||
NextObject);
|
||||
}
|
||||
|
||||
*NextObject = FoundObject;
|
||||
*Path = NULL;
|
||||
|
||||
return Status;
|
||||
/* Should hopefully never get here */
|
||||
return STATUS_OBJECT_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
@ -824,14 +797,14 @@ NtUserGetObjectInformation(
|
|||
case UOI_NAME:
|
||||
if (WinStaObject != NULL)
|
||||
{
|
||||
pvData = WinStaObject->Name.Buffer;
|
||||
nDataSize = WinStaObject->Name.Length+2;
|
||||
pvData = ((PUNICODE_STRING)GET_DESKTOP_NAME(WinStaObject))->Buffer;
|
||||
nDataSize = ((PUNICODE_STRING)GET_DESKTOP_NAME(WinStaObject))->Length + 2;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else if (DesktopObject != NULL)
|
||||
{
|
||||
pvData = DesktopObject->Name.Buffer;
|
||||
nDataSize = DesktopObject->Name.Length+2;
|
||||
pvData = ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Buffer;
|
||||
nDataSize = ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Length + 2;
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
|
@ -1407,7 +1380,7 @@ BuildDesktopNameList(
|
|||
DesktopEntry = DesktopEntry->Flink)
|
||||
{
|
||||
DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP_OBJECT, ListEntry);
|
||||
ReturnLength += DesktopObject->Name.Length + sizeof(WCHAR);
|
||||
ReturnLength += ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Length + sizeof(WCHAR);
|
||||
EntryCount++;
|
||||
}
|
||||
DPRINT("Required size: %d Entry count: %d\n", ReturnLength, EntryCount);
|
||||
|
@ -1450,14 +1423,14 @@ BuildDesktopNameList(
|
|||
DesktopEntry = DesktopEntry->Flink)
|
||||
{
|
||||
DesktopObject = CONTAINING_RECORD(DesktopEntry, DESKTOP_OBJECT, ListEntry);
|
||||
Status = MmCopyToCaller(lpBuffer, DesktopObject->Name.Buffer, DesktopObject->Name.Length);
|
||||
Status = MmCopyToCaller(lpBuffer, ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Buffer, ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Length);
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
KeReleaseSpinLock(&WindowStation->Lock, OldLevel);
|
||||
ObDereferenceObject(WindowStation);
|
||||
return Status;
|
||||
}
|
||||
lpBuffer = (PVOID) ((PCHAR) lpBuffer + DesktopObject->Name.Length);
|
||||
lpBuffer = (PVOID) ((PCHAR) lpBuffer + ((PUNICODE_STRING)GET_DESKTOP_NAME(DesktopObject))->Length);
|
||||
Status = MmCopyToCaller(lpBuffer, &NullWchar, sizeof(WCHAR));
|
||||
if (! NT_SUCCESS(Status))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue