#pragma alloc_text(INIT, ExpWin32kInit)
#endif
+typedef struct _WIN32_KERNEL_OBJECT_HEADER
+{
+ ULONG SessionId;
+} WIN32_KERNEL_OBJECT_HEADER, *PWIN32_KERNEL_OBJECT_HEADER;
+
+
/* DATA **********************************************************************/
POBJECT_TYPE ExWindowStationObjectType = NULL;
STANDARD_RIGHTS_REQUIRED
};
-PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse = NULL;
-PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete = NULL;
-PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose = NULL;
-PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose = NULL;
-PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete = NULL;
+PKWIN32_SESSION_CALLOUT ExpWindowStationObjectParse = NULL;
+PKWIN32_SESSION_CALLOUT ExpWindowStationObjectDelete = NULL;
+PKWIN32_SESSION_CALLOUT ExpWindowStationObjectOkToClose = NULL;
+PKWIN32_SESSION_CALLOUT ExpDesktopObjectOkToClose = NULL;
+PKWIN32_SESSION_CALLOUT ExpDesktopObjectDelete = NULL;
+PKWIN32_SESSION_CALLOUT ExpDesktopObjectOpen = NULL;
+PKWIN32_SESSION_CALLOUT ExpDesktopObjectClose = NULL;
/* FUNCTIONS ****************************************************************/
+NTSTATUS
+NTAPI
+ExpWin32SessionCallout(
+ _In_ PVOID Object,
+ _In_ PKWIN32_SESSION_CALLOUT CalloutProcedure,
+ _Inout_opt_ PVOID Parameter)
+{
+ PWIN32_KERNEL_OBJECT_HEADER Win32ObjectHeader;
+ PVOID SessionEntry = NULL;
+ KAPC_STATE ApcState;
+ NTSTATUS Status;
+
+ /* The objects have a common header. And the kernel accesses it!
+ Thanks MS for this kind of retarded "design"! */
+ Win32ObjectHeader = Object;
+
+ /* Check if we are not already in the correct session */
+ if (!PsGetCurrentProcess()->ProcessInSession ||
+ (PsGetCurrentProcessSessionId() != Win32ObjectHeader->SessionId))
+ {
+ /* Get the session from the objects session Id */
+ DPRINT("SessionId == %d\n", Win32ObjectHeader->SessionId);
+ SessionEntry = MmGetSessionById(Win32ObjectHeader->SessionId);
+ if (SessionEntry == NULL)
+ {
+ /* The requested session does not even exist! */
+ ASSERT(FALSE);
+ return STATUS_NOT_FOUND;
+ }
+
+ /* Attach to the session */
+ Status = MmAttachSession(SessionEntry, &ApcState);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Could not attach to 0x%p, object %p, callout 0x%p\n",
+ SessionEntry,
+ Win32ObjectHeader,
+ CalloutProcedure);
+
+ /* Cleanup and return */
+ MmQuitNextSession(SessionEntry);
+ ASSERT(FALSE);
+ return Status;
+ }
+ }
+
+ /* Call the callout routine */
+ Status = CalloutProcedure(Parameter);
+
+ /* Check if we have a session */
+ if (SessionEntry != NULL)
+ {
+ /* Detach from the session and quit using it */
+ MmDetachSession(SessionEntry, &ApcState);
+ MmQuitNextSession(SessionEntry);
+ }
+
+ /* Return the callback status */
+ return Status;
+}
+
BOOLEAN
NTAPI
ExpDesktopOkToClose( IN PEPROCESS Process OPTIONAL,
IN KPROCESSOR_MODE AccessMode)
{
WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters;
+ NTSTATUS Status;
Parameters.Process = Process;
Parameters.Object = Object;
Parameters.Handle = Handle;
Parameters.PreviousMode = AccessMode;
- return NT_SUCCESS(ExpDesktopObjectOkToClose(&Parameters));
+ Status = ExpWin32SessionCallout(Object,
+ ExpDesktopObjectOkToClose,
+ &Parameters);
+
+ return NT_SUCCESS(Status);
}
BOOLEAN
IN KPROCESSOR_MODE AccessMode)
{
WIN32_OKAYTOCLOSEMETHOD_PARAMETERS Parameters;
+ NTSTATUS Status;
Parameters.Process = Process;
Parameters.Object = Object;
Parameters.Handle = Handle;
Parameters.PreviousMode = AccessMode;
- return NT_SUCCESS(ExpWindowStationObjectOkToClose(&Parameters));
+ Status = ExpWin32SessionCallout(Object,
+ ExpWindowStationObjectOkToClose,
+ &Parameters);
+
+ return NT_SUCCESS(Status);
}
VOID
/* Fill out the callback structure */
Parameters.Object = DeletedObject;
- /* Call the Registered Callback */
- ExpWindowStationObjectDelete(&Parameters);
+ ExpWin32SessionCallout(DeletedObject,
+ ExpWindowStationObjectDelete,
+ &Parameters);
}
NTSTATUS
Parameters.SecurityQos = SecurityQos;
Parameters.Object = Object;
- /* Call the Registered Callback */
- return ExpWindowStationObjectParse(&Parameters);
+ return ExpWin32SessionCallout(ParseObject,
+ ExpWindowStationObjectParse,
+ &Parameters);
}
VOID
NTAPI
/* Fill out the callback structure */
Parameters.Object = DeletedObject;
- /* Call the Registered Callback */
- ExpDesktopObjectDelete(&Parameters);
+ ExpWin32SessionCallout(DeletedObject,
+ ExpDesktopObjectDelete,
+ &Parameters);
+}
+
+NTSTATUS
+NTAPI
+ExpDesktopOpen(IN OB_OPEN_REASON Reason,
+ IN PEPROCESS Process OPTIONAL,
+ IN PVOID ObjectBody,
+ IN ACCESS_MASK GrantedAccess,
+ IN ULONG HandleCount)
+{
+ WIN32_OPENMETHOD_PARAMETERS Parameters;
+
+ Parameters.OpenReason = Reason;
+ Parameters.Process = Process;
+ Parameters.Object = ObjectBody;
+ Parameters.GrantedAccess = GrantedAccess;
+ Parameters.HandleCount = HandleCount;
+
+ return ExpWin32SessionCallout(ObjectBody,
+ ExpDesktopObjectOpen,
+ &Parameters);
+}
+
+VOID
+NTAPI
+ExpDesktopClose(IN PEPROCESS Process OPTIONAL,
+ IN PVOID Object,
+ IN ACCESS_MASK GrantedAccess,
+ IN ULONG ProcessHandleCount,
+ IN ULONG SystemHandleCount)
+{
+ WIN32_CLOSEMETHOD_PARAMETERS Parameters;
+
+ Parameters.Process = Process;
+ Parameters.Object = Object;
+ Parameters.AccessMask = GrantedAccess;
+ Parameters.ProcessHandleCount = ProcessHandleCount;
+ Parameters.SystemHandleCount = SystemHandleCount;
+
+ ExpWin32SessionCallout(Object,
+ ExpDesktopObjectClose,
+ &Parameters);
}
BOOLEAN
NULL,
&ExWindowStationObjectType);
if (!NT_SUCCESS(Status)) return FALSE;
-
+
/* Create desktop object type */
RtlInitUnicodeString(&Name, L"Desktop");
ObjectTypeInitializer.GenericMapping = ExpDesktopMapping;
ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete;
ObjectTypeInitializer.ParseProcedure = NULL;
ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose;
- ObCreateObjectType(&Name,
- &ObjectTypeInitializer,
- NULL,
- &ExDesktopObjectType);
+ ObjectTypeInitializer.OpenProcedure = ExpDesktopOpen;
+ ObjectTypeInitializer.CloseProcedure = ExpDesktopClose;
+ Status = ObCreateObjectType(&Name,
+ &ObjectTypeInitializer,
+ NULL,
+ &ExDesktopObjectType);
if (!NT_SUCCESS(Status)) return FALSE;
-
+
return TRUE;
}