Leaked source code of windows server 2003
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

  1. /******************************Module*Header*******************************\
  2. * Module Name: drvobj.cxx
  3. *
  4. * DRVOBJ object code. The DRVOBJ is an engine object which tracks
  5. * driver managed pre-process resource that need to be freed upon
  6. * client-side process termination.
  7. *
  8. * Created: 18-Jan-1994 19:27:17
  9. * Author: Gilman Wong [gilmanw]
  10. *
  11. * Copyright (c) 1994-1999 Microsoft Corporation
  12. *
  13. \**************************************************************************/
  14. #include "precomp.hxx"
  15. /******************************Public*Routine******************************\
  16. * EngCreateDriverObj
  17. *
  18. * Allocate an object that will be own by the process and cleaned up at
  19. * process termination if it's still left around.
  20. *
  21. * History:
  22. * 18-Jan-1994 -by- Gilman Wong [gilmanw]
  23. * Wrote it.
  24. \**************************************************************************/
  25. HDRVOBJ APIENTRY EngCreateDriverObj(PVOID pvObj, FREEOBJPROC pFreeObjProc, HDEV hdev)
  26. {
  27. HDRVOBJ hdoRet = (HDRVOBJ) 0;
  28. PDRVOBJ pdo = (PDRVOBJ) ALLOCOBJ(sizeof(DRVOBJ), DRVOBJ_TYPE, FALSE);
  29. if (pdo != (PDRVOBJ) NULL)
  30. {
  31. PDEVOBJ po(hdev);
  32. pdo->pvObj = pvObj;
  33. pdo->pFreeProc = pFreeObjProc;
  34. pdo->hdev = hdev;
  35. pdo->dhpdev = po.dhpdev();
  36. pdo->Process = PsGetCurrentProcess();
  37. hdoRet = (HDRVOBJ) HmgInsertObject((HOBJ) pdo, 0, DRVOBJ_TYPE);
  38. if (hdoRet != (HDRVOBJ) 0)
  39. {
  40. // Don't free the PDEV until the DRIVEROBJ is destroyed.
  41. po.vReferencePdev();
  42. }
  43. else
  44. {
  45. WARNING("EngCreateDriverObj(): HmgInsertObject failed\n");
  46. FREEOBJ(pdo, DRVOBJ_TYPE);
  47. }
  48. }
  49. else
  50. {
  51. WARNING("EngCreateDriverObj(): ALLOCOBJ failed\n");
  52. }
  53. return(hdoRet);
  54. }
  55. /******************************Public*Routine******************************\
  56. * EngLockDriverObj
  57. *
  58. * This grabs an exclusive lock on this object for the calling thread.
  59. * This will fail if the handle is invalid, the object is already locked
  60. * by another thread, or the caller isn't the correct PID (the PID that
  61. * created the object).
  62. *
  63. * History:
  64. * 31-May-1994 -by- Patrick Haluptzok patrickh
  65. * Wrote it.
  66. \**************************************************************************/
  67. DRIVEROBJ * APIENTRY EngLockDriverObj(HDRVOBJ hdo)
  68. {
  69. DRIVEROBJ *pDriverObj = NULL;
  70. DRVOBJ *pdo = (DRVOBJ *) HmgLock((HOBJ) hdo, DRVOBJ_TYPE);
  71. if (pdo)
  72. {
  73. PDEVOBJ po(pdo->hdev);
  74. ASSERTGDI(po.bValid(), "Expected a valid hdev");
  75. //
  76. // Since a DRVOBJ is derived from a DRIVEROBJ, this automatically
  77. // points to the DRIVEROBJ part of the object:
  78. //
  79. pDriverObj = pdo;
  80. }
  81. return(pDriverObj);
  82. }
  83. /******************************Public*Routine******************************\
  84. * EngUnlockDriverObj
  85. *
  86. * Unlocks the handle. Note this call assumes the handle passed in is
  87. * valid, if it isn't we are in big trouble, the handle table will be
  88. * corrupted, a particular object will have its lock count messed up
  89. * making it undeletable.
  90. *
  91. * History:
  92. * 31-May-1994 -by- Patrick Haluptzok patrickh
  93. * Wrote it.
  94. \**************************************************************************/
  95. BOOL APIENTRY EngUnlockDriverObj(HDRVOBJ hdo)
  96. {
  97. //
  98. // Note to be paranoid we could lock it again and if that succeeds
  99. // unlock it twice to make the engine immune to hosed up drivers.
  100. //
  101. PBYTE pjTemp = (PBYTE) HmgLock((HOBJ) hdo, DRVOBJ_TYPE);
  102. ASSERTGDI(pjTemp != NULL, "ERROR EngUnlockDriverObj failed - bad handle, driver error");
  103. if (pjTemp)
  104. {
  105. DEC_EXCLUSIVE_REF_CNT(pjTemp);
  106. DEC_EXCLUSIVE_REF_CNT(pjTemp);
  107. return(TRUE);
  108. }
  109. return(FALSE);
  110. }
  111. /******************************Public*Routine******************************\
  112. * EngDeleteDriverObj
  113. *
  114. * This is called by the driver to delete the handle it created for the
  115. * object it created.
  116. *
  117. * Deletes the DRVOBJ. The FreeObjProc in the DRVOBJ is optionally called
  118. * before the DRVOBJ is freed.
  119. *
  120. * Returns:
  121. * TRUE if sucessful, FALSE otherwise.
  122. *
  123. * History:
  124. * 18-Jan-1994 -by- Gilman Wong [gilmanw]
  125. * Wrote it.
  126. \**************************************************************************/
  127. BOOL APIENTRY EngDeleteDriverObj(HDRVOBJ hdo, BOOL bCallFreeProc, BOOL bLocked)
  128. {
  129. GDIFunctionID(EngDeleteDriverObj);
  130. PDRVOBJ pdo;
  131. DRIVEROBJ *pDriverObj;
  132. if (pdo = (PDRVOBJ) HmgLock((HOBJ) hdo, DRVOBJ_TYPE))
  133. {
  134. PDEVOBJ po(pdo->hdev);
  135. BOOL bDeleteOK = TRUE;
  136. ASSERTGDI(po.bValid(), "Expected valid hdev");
  137. pDriverObj = pdo;
  138. if (bCallFreeProc)
  139. {
  140. ASSERTGDI(PsGetCurrentProcess() == pdo->Process,
  141. "Unexpected process context for clean-up");
  142. GreAcquireSemaphoreEx(po.hsemDevLock(), SEMORDER_DEVLOCK, NULL);
  143. bDeleteOK = (*pdo->pFreeProc)(pDriverObj);
  144. GreReleaseSemaphoreEx(po.hsemDevLock());
  145. }
  146. if(bDeleteOK)
  147. {
  148. PDRVOBJ pdoTemp;
  149. if ((pdoTemp = (PDRVOBJ) HmgRemoveObject((HOBJ) hdo, bLocked ? 2 : 1, 0, TRUE, DRVOBJ_TYPE)) != NULL)
  150. {
  151. po.vUnreferencePdev();
  152. FREEOBJ(pdoTemp, DRVOBJ_TYPE);
  153. return(TRUE);
  154. }
  155. else
  156. {
  157. WARNING("HmgRemoveObject failed\n");
  158. }
  159. }
  160. else
  161. {
  162. WARNING("Driver failed to delete the object\n");
  163. }
  164. DEC_EXCLUSIVE_REF_CNT(pdo);
  165. }
  166. else
  167. {
  168. WARNING("Failed to lock hdo\n");
  169. }
  170. return(FALSE);
  171. }