[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