[NTOS:MM] Quick fix: use SIZE_T instead of ULONG, because ULONG is 32-bit and on...
[reactos.git] / ntoskrnl / ex / win32k.c
index c710db5..99de63c 100644 (file)
 #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;
@@ -35,14 +41,77 @@ GENERIC_MAPPING ExpDesktopMapping =
     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,
@@ -51,13 +120,18 @@ 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
@@ -68,13 +142,18 @@ ExpWindowStationOkToClose( 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(ExpWindowStationObjectOkToClose(&Parameters));
+    Status = ExpWin32SessionCallout(Object,
+                                    ExpWindowStationObjectOkToClose,
+                                    &Parameters);
+
+    return NT_SUCCESS(Status);
 }
 
 VOID
@@ -86,8 +165,9 @@ ExpWinStaObjectDelete(PVOID DeletedObject)
     /* Fill out the callback structure */
     Parameters.Object = DeletedObject;
 
-    /* Call the Registered Callback */
-    ExpWindowStationObjectDelete(&Parameters);
+    ExpWin32SessionCallout(DeletedObject,
+                           ExpWindowStationObjectDelete,
+                           &Parameters);
 }
 
 NTSTATUS
@@ -117,8 +197,9 @@ ExpWinStaObjectParse(IN PVOID ParseObject,
     Parameters.SecurityQos = SecurityQos;
     Parameters.Object = Object;
 
-    /* Call the Registered Callback */
-    return ExpWindowStationObjectParse(&Parameters);
+    return ExpWin32SessionCallout(ParseObject,
+                                  ExpWindowStationObjectParse,
+                                  &Parameters);
 }
 VOID
 NTAPI
@@ -129,8 +210,51 @@ ExpDesktopDelete(PVOID DeletedObject)
     /* 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
@@ -162,19 +286,21 @@ ExpWin32kInit(VOID)
                                 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;
 }