You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
204 lines
5.7 KiB
204 lines
5.7 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: drvobj.cxx
|
|
*
|
|
* DRVOBJ object code. The DRVOBJ is an engine object which tracks
|
|
* driver managed pre-process resource that need to be freed upon
|
|
* client-side process termination.
|
|
*
|
|
* Created: 18-Jan-1994 19:27:17
|
|
* Author: Gilman Wong [gilmanw]
|
|
*
|
|
* Copyright (c) 1994-1999 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngCreateDriverObj
|
|
*
|
|
* Allocate an object that will be own by the process and cleaned up at
|
|
* process termination if it's still left around.
|
|
*
|
|
* History:
|
|
* 18-Jan-1994 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HDRVOBJ APIENTRY EngCreateDriverObj(PVOID pvObj, FREEOBJPROC pFreeObjProc, HDEV hdev)
|
|
{
|
|
HDRVOBJ hdoRet = (HDRVOBJ) 0;
|
|
PDRVOBJ pdo = (PDRVOBJ) ALLOCOBJ(sizeof(DRVOBJ), DRVOBJ_TYPE, FALSE);
|
|
|
|
if (pdo != (PDRVOBJ) NULL)
|
|
{
|
|
PDEVOBJ po(hdev);
|
|
|
|
pdo->pvObj = pvObj;
|
|
pdo->pFreeProc = pFreeObjProc;
|
|
pdo->hdev = hdev;
|
|
pdo->dhpdev = po.dhpdev();
|
|
pdo->Process = PsGetCurrentProcess();
|
|
|
|
hdoRet = (HDRVOBJ) HmgInsertObject((HOBJ) pdo, 0, DRVOBJ_TYPE);
|
|
|
|
|
|
if (hdoRet != (HDRVOBJ) 0)
|
|
{
|
|
// Don't free the PDEV until the DRIVEROBJ is destroyed.
|
|
|
|
po.vReferencePdev();
|
|
}
|
|
else
|
|
{
|
|
WARNING("EngCreateDriverObj(): HmgInsertObject failed\n");
|
|
FREEOBJ(pdo, DRVOBJ_TYPE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("EngCreateDriverObj(): ALLOCOBJ failed\n");
|
|
}
|
|
|
|
return(hdoRet);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngLockDriverObj
|
|
*
|
|
* This grabs an exclusive lock on this object for the calling thread.
|
|
* This will fail if the handle is invalid, the object is already locked
|
|
* by another thread, or the caller isn't the correct PID (the PID that
|
|
* created the object).
|
|
*
|
|
* History:
|
|
* 31-May-1994 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
DRIVEROBJ * APIENTRY EngLockDriverObj(HDRVOBJ hdo)
|
|
{
|
|
DRIVEROBJ *pDriverObj = NULL;
|
|
|
|
DRVOBJ *pdo = (DRVOBJ *) HmgLock((HOBJ) hdo, DRVOBJ_TYPE);
|
|
|
|
if (pdo)
|
|
{
|
|
PDEVOBJ po(pdo->hdev);
|
|
ASSERTGDI(po.bValid(), "Expected a valid hdev");
|
|
|
|
//
|
|
// Since a DRVOBJ is derived from a DRIVEROBJ, this automatically
|
|
// points to the DRIVEROBJ part of the object:
|
|
//
|
|
|
|
pDriverObj = pdo;
|
|
}
|
|
|
|
return(pDriverObj);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngUnlockDriverObj
|
|
*
|
|
* Unlocks the handle. Note this call assumes the handle passed in is
|
|
* valid, if it isn't we are in big trouble, the handle table will be
|
|
* corrupted, a particular object will have its lock count messed up
|
|
* making it undeletable.
|
|
*
|
|
* History:
|
|
* 31-May-1994 -by- Patrick Haluptzok patrickh
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL APIENTRY EngUnlockDriverObj(HDRVOBJ hdo)
|
|
{
|
|
//
|
|
// Note to be paranoid we could lock it again and if that succeeds
|
|
// unlock it twice to make the engine immune to hosed up drivers.
|
|
//
|
|
|
|
PBYTE pjTemp = (PBYTE) HmgLock((HOBJ) hdo, DRVOBJ_TYPE);
|
|
|
|
ASSERTGDI(pjTemp != NULL, "ERROR EngUnlockDriverObj failed - bad handle, driver error");
|
|
|
|
if (pjTemp)
|
|
{
|
|
DEC_EXCLUSIVE_REF_CNT(pjTemp);
|
|
DEC_EXCLUSIVE_REF_CNT(pjTemp);
|
|
return(TRUE);
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* EngDeleteDriverObj
|
|
*
|
|
* This is called by the driver to delete the handle it created for the
|
|
* object it created.
|
|
*
|
|
* Deletes the DRVOBJ. The FreeObjProc in the DRVOBJ is optionally called
|
|
* before the DRVOBJ is freed.
|
|
*
|
|
* Returns:
|
|
* TRUE if sucessful, FALSE otherwise.
|
|
*
|
|
* History:
|
|
* 18-Jan-1994 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL APIENTRY EngDeleteDriverObj(HDRVOBJ hdo, BOOL bCallFreeProc, BOOL bLocked)
|
|
{
|
|
GDIFunctionID(EngDeleteDriverObj);
|
|
|
|
PDRVOBJ pdo;
|
|
DRIVEROBJ *pDriverObj;
|
|
|
|
if (pdo = (PDRVOBJ) HmgLock((HOBJ) hdo, DRVOBJ_TYPE))
|
|
{
|
|
PDEVOBJ po(pdo->hdev);
|
|
BOOL bDeleteOK = TRUE;
|
|
ASSERTGDI(po.bValid(), "Expected valid hdev");
|
|
|
|
pDriverObj = pdo;
|
|
|
|
if (bCallFreeProc)
|
|
{
|
|
ASSERTGDI(PsGetCurrentProcess() == pdo->Process,
|
|
"Unexpected process context for clean-up");
|
|
|
|
GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
|
|
bDeleteOK = (*pdo->pFreeProc)(pDriverObj);
|
|
GreReleaseSemaphoreEx(po.hsemDevLock());
|
|
}
|
|
|
|
if(bDeleteOK)
|
|
{
|
|
PDRVOBJ pdoTemp;
|
|
if ((pdoTemp = (PDRVOBJ) HmgRemoveObject((HOBJ) hdo, bLocked ? 2 : 1, 0, TRUE, DRVOBJ_TYPE)) != NULL)
|
|
{
|
|
po.vUnreferencePdev();
|
|
FREEOBJ(pdoTemp, DRVOBJ_TYPE);
|
|
return(TRUE);
|
|
}
|
|
else
|
|
{
|
|
WARNING("HmgRemoveObject failed\n");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("Driver failed to delete the object\n");
|
|
}
|
|
|
|
DEC_EXCLUSIVE_REF_CNT(pdo);
|
|
}
|
|
else
|
|
{
|
|
WARNING("Failed to lock hdo\n");
|
|
}
|
|
|
|
return(FALSE);
|
|
}
|