2005-06-16 20:46:39 +00:00
|
|
|
/*
|
2009-03-17 00:30:15 +00:00
|
|
|
* COPYRIGHT: GPL, see COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS win32 kernel mode sunsystem
|
2005-06-16 20:46:39 +00:00
|
|
|
* PURPOSE: GDI DRIVEROBJ Functions
|
2015-11-10 17:41:55 +00:00
|
|
|
* FILE: win32ss/gdi/eng/driverobj.c
|
2009-03-17 00:30:15 +00:00
|
|
|
* PROGRAMER: Timo Kreuzer
|
2005-06-16 20:46:39 +00:00
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/** Includes ******************************************************************/
|
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2005-06-29 07:09:25 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
|
|
|
|
/** Internal interface ********************************************************/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief DRIVEROBJ cleanup function
|
2005-06-16 20:46:39 +00:00
|
|
|
*/
|
2014-05-22 11:45:53 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
DRIVEROBJ_vCleanup(PVOID pObject)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
PEDRIVEROBJ pedo = pObject;
|
|
|
|
FREEOBJPROC pFreeProc;
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
pFreeProc = pedo->drvobj.pFreeProc;
|
|
|
|
if (pFreeProc)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2014-07-28 13:03:19 +00:00
|
|
|
NT_VERIFY(pFreeProc(&pedo->drvobj));
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/** Public interface **********************************************************/
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2013-01-01 09:40:48 +00:00
|
|
|
_Must_inspect_result_
|
2005-06-16 20:46:39 +00:00
|
|
|
HDRVOBJ
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2005-06-16 20:46:39 +00:00
|
|
|
EngCreateDriverObj(
|
2013-01-01 09:40:48 +00:00
|
|
|
_In_ PVOID pvObj,
|
|
|
|
_In_opt_ FREEOBJPROC pFreeObjProc,
|
|
|
|
_In_ HDEV hdev)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
PEDRIVEROBJ pedo;
|
|
|
|
HDRVOBJ hdo;
|
2009-03-20 18:02:55 +00:00
|
|
|
PDEVOBJ *ppdev = (PDEVOBJ*)hdev;
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Allocate a new DRIVEROBJ */
|
|
|
|
pedo = DRIVEROBJ_AllocObjectWithHandle();
|
|
|
|
if (!pedo)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
return NULL;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
2009-03-17 00:30:15 +00:00
|
|
|
hdo = pedo->baseobj.hHmgr;
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Fill in fields */
|
|
|
|
pedo->drvobj.pvObj = pvObj;
|
|
|
|
pedo->drvobj.pFreeProc = pFreeObjProc;
|
|
|
|
pedo->drvobj.hdev = hdev;
|
2009-08-16 12:57:41 +00:00
|
|
|
pedo->drvobj.dhpdev = ppdev->dhpdev;
|
2009-03-17 00:30:15 +00:00
|
|
|
|
|
|
|
/* Unlock the object */
|
|
|
|
DRIVEROBJ_UnlockObject(pedo);
|
|
|
|
|
|
|
|
/* Return the handle */
|
|
|
|
return hdo;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2005-06-16 20:46:39 +00:00
|
|
|
EngDeleteDriverObj(
|
2013-01-01 09:40:48 +00:00
|
|
|
_In_ _Post_ptr_invalid_ HDRVOBJ hdo,
|
|
|
|
_In_ BOOL bCallBack,
|
|
|
|
_In_ BOOL bLocked)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
PEDRIVEROBJ pedo;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Lock the object */
|
2014-01-29 18:32:14 +00:00
|
|
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
2009-03-17 00:30:15 +00:00
|
|
|
if (!pedo)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
return FALSE;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Manually call cleanup callback */
|
|
|
|
if (bCallBack)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2014-07-28 13:03:19 +00:00
|
|
|
if (!pedo->drvobj.pFreeProc(&pedo->drvobj))
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Callback failed */
|
|
|
|
DRIVEROBJ_UnlockObject(pedo);
|
|
|
|
return FALSE;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
|
|
|
}
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Prevent cleanup callback from being called again */
|
|
|
|
pedo->drvobj.pFreeProc = NULL;
|
|
|
|
|
2014-01-29 18:32:14 +00:00
|
|
|
/* Unlock if the caller indicates it is locked */
|
|
|
|
if (bLocked)
|
|
|
|
DRIVEROBJ_UnlockObject(pedo);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2014-01-29 18:32:14 +00:00
|
|
|
/* Now delete the object */
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
GDIOBJ_vDeleteObject(&pedo->baseobj);
|
|
|
|
return TRUE;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PDRIVEROBJ
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2009-03-17 00:30:15 +00:00
|
|
|
EngLockDriverObj(
|
2013-01-01 09:40:48 +00:00
|
|
|
_In_ HDRVOBJ hdo)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
PEDRIVEROBJ pedo;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Lock the object */
|
2014-01-29 18:32:14 +00:00
|
|
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Return pointer to the DRIVEROBJ structure */
|
2021-06-09 16:27:12 +00:00
|
|
|
return pedo ? &pedo->drvobj : NULL;
|
2005-06-16 20:46:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2009-03-17 00:30:15 +00:00
|
|
|
EngUnlockDriverObj(
|
2013-01-01 09:40:48 +00:00
|
|
|
_In_ _Post_ptr_invalid_ HDRVOBJ hdo)
|
2005-06-16 20:46:39 +00:00
|
|
|
{
|
2009-03-17 00:30:15 +00:00
|
|
|
PEDRIVEROBJ pedo;
|
2009-03-17 01:06:34 +00:00
|
|
|
ULONG cLocks;
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* First lock to get a pointer to the object */
|
2014-01-29 18:32:14 +00:00
|
|
|
pedo = DRIVEROBJ_TryLockObject(hdo);
|
2009-03-17 00:30:15 +00:00
|
|
|
if(!pedo)
|
|
|
|
{
|
|
|
|
/* Object could not be locked, fail. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock object */
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
cLocks = pedo->baseobj.cExclusiveLock;
|
|
|
|
DRIVEROBJ_UnlockObject(pedo);
|
2005-06-16 20:46:39 +00:00
|
|
|
|
2009-03-17 00:30:15 +00:00
|
|
|
/* Check if we still hold a lock */
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
if (cLocks < 2)
|
2009-03-17 00:30:15 +00:00
|
|
|
{
|
|
|
|
/* Object wasn't locked before, fail. */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unlock again */
|
|
|
|
DRIVEROBJ_UnlockObject(pedo);
|
|
|
|
|
|
|
|
/* Success */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2005-06-16 20:46:39 +00:00
|
|
|
|