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/ntg…
==============================================================================
--- 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/en…
==============================================================================
--- 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/en…
==============================================================================
--- 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/in…
==============================================================================
--- 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/in…
==============================================================================
--- 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/in…
==============================================================================
--- 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/ma…
==============================================================================
--- 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/ob…
==============================================================================
--- 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