[ros-diffs] [tkreuzer] 40068: Rewrite DRIVEROBJ api, giving the object a handle, belonging to the current process. Let the gdi obj cleanup take care for calling the callback function. Allow deleting of objects that are exclusively locked by the current thread.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Tue Mar 17 01:30:17 CET 2009


Author: tkreuzer
Date: Tue Mar 17 03:30:15 2009
New Revision: 40068

URL: http://svn.reactos.org/svn/reactos?rev=40068&view=rev
Log:
Rewrite DRIVEROBJ api, giving the object a handle, belonging to the current process. Let the gdi obj cleanup take care for calling the callback function.
Allow deleting of objects that are exclusively locked by the current thread.

Added:
    trunk/reactos/subsystems/win32/win32k/include/driverobj.h   (with props)
Modified:
    trunk/reactos/include/reactos/win32k/ntgdihdl.h
    trunk/reactos/subsystems/win32/win32k/eng/driverobj.c
    trunk/reactos/subsystems/win32/win32k/eng/objects.h
    trunk/reactos/subsystems/win32/win32k/include/inteng.h
    trunk/reactos/subsystems/win32/win32k/include/win32k.h
    trunk/reactos/subsystems/win32/win32k/main/dllmain.c
    trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c

Modified: trunk/reactos/include/reactos/win32k/ntgdihdl.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntgdihdl.h?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/win32k/ntgdihdl.h [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -66,6 +66,7 @@
 #define GDI_OBJECT_TYPE_DD_VIDEOPORT  0x00120000 /* Should be moved away from gdi objects */
 #define GDI_OBJECT_TYPE_DD_MOTIONCOMP 0x00140000 /* Should be moved away from gdi objects */
 #define GDI_OBJECT_TYPE_ENUMFONT      0x00160000
+#define GDI_OBJECT_TYPE_DRIVEROBJ     0x001C0000
 
 /* Confrim on XP value is taken from NtGdiCreateDirectDrawObject */
 #define GDI_OBJECT_TYPE_DIRECTDRAW  0x00200000

Modified: trunk/reactos/subsystems/win32/win32k/eng/driverobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/eng/driverobj.c?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/driverobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/driverobj.c [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -1,180 +1,156 @@
 /*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 2005 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * COPYRIGHT:         GPL, see COPYING in the top level directory
+ * PROJECT:           ReactOS win32 kernel mode sunsystem
+ * PURPOSE:           GDI DRIVEROBJ Functions
+ * FILE:              subsystems/win32k/eng/driverobj.c
+ * PROGRAMER:         Timo Kreuzer
  */
-/*
- * COPYRIGHT:         See COPYING in the top level directory
- * PROJECT:           ReactOS kernel
- * PURPOSE:           GDI DRIVEROBJ Functions
- * FILE:              subsys/win32k/eng/driverobj.c
- * PROGRAMER:         Gregor Anich
- * REVISION HISTORY:
- *                 04/01/2005: Created
- */
+
+/** Includes ******************************************************************/
 
 #include <w32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
-/*!\brief Called when the process is terminated.
- *
- * Calls the free-proc for each existing DRIVEROBJ.
- *
- * \param Process  Pointer to the EPROCESS struct for the process beeing terminated.
- * \param Win32Process  Pointer to the W32PROCESS
+
+/** Internal interface ********************************************************/
+
+/*!
+ * \brief DRIVEROBJ cleanup function
  */
-VOID FASTCALL
-IntEngCleanupDriverObjs(struct _EPROCESS *Process,
-                        PW32PROCESS Win32Process)
+BOOL INTERNAL_CALL
+DRIVEROBJ_Cleanup(PVOID pObject)
 {
-  PDRIVERGDI DrvObjInt;
-  PW32PROCESS CurrentWin32Process;
+    PEDRIVEROBJ pedo = pObject;
+    FREEOBJPROC pFreeProc;
 
-  CurrentWin32Process = PsGetCurrentProcessWin32Process();
-  IntEngLockProcessDriverObjs(CurrentWin32Process);
-  while (!IsListEmpty(&Win32Process->DriverObjListHead))
+    pFreeProc = pedo->drvobj.pFreeProc;
+    if (pFreeProc)
     {
-      DrvObjInt = CONTAINING_RECORD(Win32Process->DriverObjListHead.Flink,
-                                    DRIVERGDI, ListEntry);
-      IntEngUnLockProcessDriverObjs(CurrentWin32Process);
-      EngDeleteDriverObj((HDRVOBJ)(&DrvObjInt->DriverObj), TRUE, FALSE);
-      IntEngLockProcessDriverObjs(CurrentWin32Process);
+        return pFreeProc(pedo->drvobj.pvObj);
     }
-  IntEngUnLockProcessDriverObjs(CurrentWin32Process);
+
+    return TRUE;
+}
+
+/** Public interface **********************************************************/
+
+HDRVOBJ
+APIENTRY
+EngCreateDriverObj(
+	IN PVOID       pvObj,
+	IN FREEOBJPROC pFreeObjProc,
+	IN HDEV        hdev)
+{
+    PEDRIVEROBJ pedo;
+    HDRVOBJ hdo;
+    GDIDEVICE *ppdev = (GDIDEVICE*)hdev;
+
+    /* Allocate a new DRIVEROBJ */
+    pedo = DRIVEROBJ_AllocObjectWithHandle();
+    if (!pedo)
+    {
+        return NULL;
+    }
+    hdo = pedo->baseobj.hHmgr;
+
+    /* Fill in fields */
+    pedo->drvobj.pvObj = pvObj;
+    pedo->drvobj.pFreeProc = pFreeObjProc;
+    pedo->drvobj.hdev = hdev;
+    pedo->drvobj.dhpdev = ppdev->hPDev;
+
+    /* Unlock the object */
+    DRIVEROBJ_UnlockObject(pedo);
+
+    /* Return the handle */
+    return hdo;
 }
 
 
-/*
- * @implemented
- */
-HDRVOBJ
+BOOL
 APIENTRY
-EngCreateDriverObj(
-	IN PVOID        pvObj,
-	IN FREEOBJPROC  pFreeObjProc,
-	IN HDEV         hdev
-	)
+EngDeleteDriverObj(
+	IN HDRVOBJ hdo,
+	IN BOOL    bCallBack,
+	IN BOOL    bLocked)
 {
-  PDRIVERGDI DrvObjInt;
-  PDRIVEROBJ DrvObjUser;
-  PW32PROCESS CurrentWin32Process;
+    PEDRIVEROBJ pedo;
 
-  /* Create DRIVEROBJ */
-  DrvObjInt = EngAllocMem(0, sizeof (DRIVERGDI), TAG_DRIVEROBJ);
-  if (DrvObjInt == NULL)
+    /* Lock the object */
+    pedo = DRIVEROBJ_LockObject(hdo);
+    if (!pedo)
     {
-      DPRINT1("Failed to allocate memory for a DRIVERGDI structure!\n");
-      return NULL;
+        return FALSE;
     }
 
-  /* fill user object */
-  DrvObjUser = GDIToObj(DrvObjInt, DRIVER);
-  DrvObjUser->pvObj = pvObj;
-  DrvObjUser->pFreeProc = pFreeObjProc;
-  DrvObjUser->hdev = hdev;
-  DrvObjUser->dhpdev = ((GDIDEVICE*)hdev)->hPDev;
+    /* Manually call cleanup callback */
+    if (bCallBack)
+    {
+        if (!pedo->drvobj.pFreeProc(pedo->drvobj.pvObj))
+        {
+            /* Callback failed */
+            DRIVEROBJ_UnlockObject(pedo);
+            return FALSE;
+        }
+    }
 
-  /* fill internal object */
-  ExInitializeFastMutex(&DrvObjInt->Lock);
-  CurrentWin32Process = PsGetCurrentProcessWin32Process();
-  IntEngLockProcessDriverObjs(CurrentWin32Process);
-  InsertTailList(&CurrentWin32Process->DriverObjListHead, &DrvObjInt->ListEntry);
-  IntEngUnLockProcessDriverObjs(CurrentWin32Process);
+    /* Prevent cleanup callback from being called again */
+    pedo->drvobj.pFreeProc = NULL;
 
-  return (HDRVOBJ)DrvObjUser;
+    /* NOTE: We don't care about the bLocked param, as our handle manager
+       allows freeing the object, while we hold any number of locks. */
+
+    /* Free the object */
+    return DRIVEROBJ_FreeObjectByHandle(hdo);
 }
 
 
-/*
- * @implemented
- */
-BOOL
+PDRIVEROBJ
 APIENTRY
-EngDeleteDriverObj(
-	IN HDRVOBJ  hdo,
-	IN BOOL  bCallBack,
-	IN BOOL  bLocked
-	)
+EngLockDriverObj(
+    IN HDRVOBJ hdo)
 {
-  PDRIVEROBJ DrvObjUser = (PDRIVEROBJ)hdo;
-  PDRIVERGDI DrvObjInt = ObjToGDI(DrvObjUser, DRIVER);
-  PW32PROCESS CurrentWin32Process;
+    PEDRIVEROBJ pedo;
 
-  /* Make sure the obj is locked */
-  if (!bLocked)
-    {
-      if (!ExTryToAcquireFastMutex(&DrvObjInt->Lock))
-        {
-          return FALSE;
-        }
-    }
+    /* Lock the object */
+    pedo = DRIVEROBJ_LockObject(hdo);
 
-  /* Call the free-proc */
-  if (bCallBack)
-    {
-      if (!DrvObjUser->pFreeProc(DrvObjUser))
-        {
-          return FALSE;
-        }
-    }
-
-  /* Free the DRIVEROBJ */
-  CurrentWin32Process = PsGetCurrentProcessWin32Process();
-  IntEngLockProcessDriverObjs(CurrentWin32Process);
-  RemoveEntryList(&DrvObjInt->ListEntry);
-  IntEngUnLockProcessDriverObjs(CurrentWin32Process);
-  EngFreeMem(DrvObjInt);
-
-  return TRUE;
+    /* Return pointer to the DRIVEROBJ structure */
+    return &pedo->drvobj;
 }
 
 
-/*
- * @implemented
- */
-PDRIVEROBJ
+BOOL
 APIENTRY
-EngLockDriverObj( IN HDRVOBJ hdo )
+EngUnlockDriverObj(
+    IN HDRVOBJ hdo)
 {
-  PDRIVEROBJ DrvObjUser = (PDRIVEROBJ)hdo;
-  PDRIVERGDI DrvObjInt = ObjToGDI(DrvObjUser, DRIVER);
+    PEDRIVEROBJ pedo;
 
-  if (!ExTryToAcquireFastMutex(&DrvObjInt->Lock))
+    /* First lock to get a pointer to the object */
+    pedo = DRIVEROBJ_LockObject(hdo);
+    if(!pedo)
     {
-      return NULL;
+        /* Object could not be locked, fail. */
+        return FALSE;
     }
 
-  return DrvObjUser;
+    /* Unlock object */
+    DRIVEROBJ_UnlockObject(pedo);
+
+    /* Check if we still hold a lock */
+    if (pedo->baseobj.cExclusiveLock < 1)
+    {
+        /* Object wasn't locked before, fail. */
+        return FALSE;
+    }
+
+    /* Unlock again */
+    DRIVEROBJ_UnlockObject(pedo);
+
+    /* Success */
+    return TRUE;
 }
 
-
-/*
- * @implemented
- */
-BOOL
-APIENTRY
-EngUnlockDriverObj ( IN HDRVOBJ hdo )
-{
-  PDRIVERGDI DrvObjInt = ObjToGDI((PDRIVEROBJ)hdo, DRIVER);
-
-  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&DrvObjInt->Lock);
-  return TRUE;
-}
-
-/* EOF */
-

Modified: trunk/reactos/subsystems/win32/win32k/eng/objects.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/eng/objects.h?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/eng/objects.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/eng/objects.h [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -50,12 +50,6 @@
   ULONG EnumMax;
   ENUMRECTS EnumRects;
 } CLIPGDI, *PCLIPGDI;
-
-typedef struct _DRIVERGDI {
-  DRIVEROBJ    DriverObj;
-  LIST_ENTRY   ListEntry;
-  FAST_MUTEX   Lock;
-} DRIVERGDI, *PDRIVERGDI;
 
 /*ei What is this for? */
 typedef struct _DRVFUNCTIONSGDI {

Added: trunk/reactos/subsystems/win32/win32k/include/driverobj.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/driverobj.h?rev=40068&view=auto
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/driverobj.h (added)
+++ trunk/reactos/subsystems/win32/win32k/include/driverobj.h [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -1,0 +1,23 @@
+#ifndef _WIN32K_DRIVEROBJ_H
+#define _WIN32K_DRIVEROBJ_H
+
+#include "gdiobj.h"
+
+/* Object structure */
+typedef struct _EDRIVEROBJ
+{
+    BASEOBJECT baseobj;
+    DRIVEROBJ drvobj;
+    PVOID reserved;
+} EDRIVEROBJ, *PEDRIVEROBJ;
+
+/* Cleanup function */
+BOOL INTERNAL_CALL DRIVEROBJ_Cleanup(PVOID pObject);
+
+
+#define DRIVEROBJ_AllocObjectWithHandle()  ((PEDRIVEROBJ)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_DRIVEROBJ))
+#define DRIVEROBJ_FreeObjectByHandle(hdo) GDIOBJ_FreeObjByHandle((HGDIOBJ)hdo, GDI_OBJECT_TYPE_DRIVEROBJ)
+#define DRIVEROBJ_LockObject(hdo) ((PEDRIVEROBJ)GDIOBJ_LockObj((HGDIOBJ)hdo, GDI_OBJECT_TYPE_DRIVEROBJ))
+#define DRIVEROBJ_UnlockObject(pdo) GDIOBJ_UnlockObjByPtr((POBJ)pdo)
+
+#endif /* !_WIN32K_DRIVEROBJ_H */

Propchange: trunk/reactos/subsystems/win32/win32k/include/driverobj.h
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: trunk/reactos/subsystems/win32/win32k/include/inteng.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/inteng.h?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/inteng.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/inteng.h [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -33,16 +33,6 @@
 #define ROP3_TO_ROP4(Rop3) ((((Rop3) >> 8) & 0xff00) | (((Rop3) >> 16) & 0x00ff))
 
 /* Definitions of IntEngXxx functions */
-
-#define IntEngLockProcessDriverObjs(W32Process) \
-  ExEnterCriticalRegionAndAcquireFastMutexUnsafe(&(W32Process)->DriverObjListLock)
-
-#define IntEngUnLockProcessDriverObjs(W32Process) \
-  ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(&(W32Process)->DriverObjListLock)
-
-VOID FASTCALL
-IntEngCleanupDriverObjs(struct _EPROCESS *Process,
-                        PW32PROCESS Win32Process);
 
 BOOL APIENTRY
 IntEngLineTo(SURFOBJ *Surface,

Modified: trunk/reactos/subsystems/win32/win32k/include/win32k.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/win32k.h?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/win32k.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/win32k.h [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -28,6 +28,7 @@
 #include <include/dce.h>
 #include <include/dib.h>
 #include <include/driver.h>
+#include <include/driverobj.h>
 #include <include/error.h>
 #include <include/floatobj.h>
 #include <include/gdiobj.h>

Modified: trunk/reactos/subsystems/win32/win32k/main/dllmain.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/main/dllmain.c?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/main/dllmain.c [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -136,7 +136,6 @@
       DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
       IntCleanupMenus(Process, Win32Process);
       IntCleanupCurIcons(Process, Win32Process);
-      IntEngCleanupDriverObjs(Process, Win32Process);
       CleanupMonitorImpl();
 
       /* no process windows should exist at this point, or the function will assert! */

Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c?rev=40068&r1=40067&r2=40068&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c [iso-8859-1] Tue Mar 17 03:30:15 2009
@@ -70,7 +70,7 @@
   {0, 0,                     TAG_TTFD,         NULL},             /* 19 TTFD, unused */
   {0, 0,                     TAG_RC,           NULL},             /* 1a RC, unused */
   {0, 0,                     TAG_TEMP,         NULL},             /* 1b TEMP, unused */
-  {0, 0,                     TAG_DRVOBJ,       NULL},             /* 1c DRVOBJ, unused */
+  {0, sizeof(EDRIVEROBJ),    TAG_DRVOBJ,       DRIVEROBJ_Cleanup},/* 1c DRVOBJ */
   {0, 0,                     TAG_DCIOBJ,       NULL},             /* 1d DCIOBJ, unused */
   {0, 0,                     TAG_SPOOL,        NULL},             /* 1e SPOOL, unused */
   {0, 0,                     0,                NULL},             /* 1f reserved entry */
@@ -537,7 +537,8 @@
 
             Object = Entry->KernelData;
 
-            if (Object->cExclusiveLock == 0)
+            if (Object->cExclusiveLock == 0 ||
+                Object->Tid == (PW32THREAD)PsGetCurrentThreadWin32Thread())
             {
                 BOOL Ret;
                 PW32PROCESS W32Process = PsGetCurrentProcessWin32Process();
@@ -571,14 +572,16 @@
             else
             {
                 /*
-                 * The object is currently locked, so freeing is forbidden!
+                 * The object is currently locked by another thread, so freeing is forbidden!
                  */
                 DPRINT1("Object->cExclusiveLock = %d\n", Object->cExclusiveLock);
                 GDIDBG_TRACECALLER();
                 GDIDBG_TRACELOCKER(GDI_HANDLE_GET_INDEX(hObj));
                 (void)InterlockedExchangePointer((PVOID*)&Entry->ProcessId, PrevProcId);
                 /* do not assert here for it will call again from dxg.sys it being call twice */
-                //ASSERT(FALSE);
+
+                DelayExecution();
+                goto LockHandle;
             }
         }
         else



More information about the Ros-diffs mailing list