|
|
/******************************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); }
|