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.

293 lines
7.2 KiB

  1. /*++
  2. Copyright (c) 1998-2002 Microsoft Corporation
  3. Module Name:
  4. close.c
  5. Abstract:
  6. This module contains code for cleanup and close IRPs.
  7. Author:
  8. Keith Moore (keithmo) 10-Jun-1998
  9. Revision History:
  10. --*/
  11. #include "precomp.h"
  12. #ifdef ALLOC_PRAGMA
  13. #pragma alloc_text( PAGE, UlClose )
  14. #endif // ALLOC_PRAGMA
  15. #if 0
  16. NOT PAGEABLE -- UlCleanup
  17. #endif
  18. /*
  19. Relationship between Cleanup & Close IRPs --> IOCTLs won't be called after the
  20. handle has been "Cleaned", but there can be a race between IOCTLs & Cleanup.
  21. Close is called only when all IOCTLs are completed. Abnormal termination of an
  22. application (e.g. AV) will exercize the cleanup paths in a different way than
  23. CloseHandle(). Make sure we have tests that do abnormal termination.
  24. */
  25. //
  26. // Public functions.
  27. //
  28. /***************************************************************************++
  29. Routine Description:
  30. This is the routine that handles Cleanup IRPs in UL. Cleanup IRPs
  31. are issued after the last handle to the file object is closed.
  32. Arguments:
  33. pDeviceObject - Supplies a pointer to the target device object.
  34. pIrp - Supplies a pointer to IO request packet.
  35. Return Value:
  36. NTSTATUS - Completion status.
  37. --***************************************************************************/
  38. NTSTATUS
  39. UlCleanup(
  40. IN PDEVICE_OBJECT pDeviceObject,
  41. IN PIRP pIrp
  42. )
  43. {
  44. NTSTATUS status;
  45. PIO_STACK_LOCATION pIrpSp;
  46. UL_ENTER_DRIVER( "UlCleanup", pIrp );
  47. //
  48. // Snag the current IRP stack pointer.
  49. //
  50. pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
  51. //
  52. // app pool or control channel?
  53. //
  54. if (pDeviceObject == g_pUlAppPoolDeviceObject &&
  55. IS_APP_POOL( pIrpSp->FileObject ))
  56. {
  57. //
  58. // App pool, let's detach this process from the app pool.
  59. // The detach will also take care of the Irp completion
  60. // for us.
  61. //
  62. UlTrace(OPEN_CLOSE,(
  63. "UlCleanup: cleanup on AppPool object %p\n",
  64. pIrpSp->FileObject
  65. ));
  66. status = UlDetachProcessFromAppPool( pIrp, pIrpSp );
  67. UL_LEAVE_DRIVER("UlCleanup");
  68. RETURN(status);
  69. }
  70. if (pDeviceObject == g_pUlFilterDeviceObject &&
  71. IS_FILTER_PROCESS( pIrpSp->FileObject ))
  72. {
  73. //
  74. // filter channel
  75. //
  76. UlTrace(OPEN_CLOSE,(
  77. "UlCleanup: cleanup on FilterProcess object %p\n",
  78. pIrpSp->FileObject
  79. ));
  80. status = UlDetachFilterProcess(
  81. GET_FILTER_PROCESS(pIrpSp->FileObject)
  82. );
  83. MARK_INVALID_FILTER_CHANNEL( pIrpSp->FileObject );
  84. }
  85. else if (pDeviceObject == g_pUlControlDeviceObject &&
  86. IS_CONTROL_CHANNEL( pIrpSp->FileObject ))
  87. {
  88. PUL_CONTROL_CHANNEL pControlChannel =
  89. GET_CONTROL_CHANNEL( pIrpSp->FileObject );
  90. UlTrace(OPEN_CLOSE,(
  91. "UlCleanup: cleanup on ControlChannel object %p, %p\n",
  92. pIrpSp->FileObject,pControlChannel
  93. ));
  94. MARK_INVALID_CONTROL_CHANNEL( pIrpSp->FileObject );
  95. UlCleanUpControlChannel( pControlChannel );
  96. status = STATUS_SUCCESS;
  97. }
  98. else if (pDeviceObject == g_pUcServerDeviceObject &&
  99. IS_SERVER( pIrpSp->FileObject ))
  100. {
  101. UlTrace(OPEN_CLOSE,(
  102. "UlCleanup: cleanup on Server object %p\n",
  103. pIrpSp->FileObject
  104. ));
  105. MARK_INVALID_SERVER( pIrpSp->FileObject );
  106. status = STATUS_SUCCESS;
  107. }
  108. else
  109. {
  110. UlTrace(OPEN_CLOSE,(
  111. "UlCleanup: cleanup on invalid object %p\n",
  112. pIrpSp->FileObject
  113. ));
  114. status = STATUS_INVALID_DEVICE_REQUEST;
  115. }
  116. pIrp->IoStatus.Status = status;
  117. UlCompleteRequest( pIrp, IO_NO_INCREMENT );
  118. UL_LEAVE_DRIVER( "UlCleanup" );
  119. RETURN(status);
  120. } // UlCleanup
  121. /***************************************************************************++
  122. Routine Description:
  123. This is the routine that handles Close IRPs in UL. Close IRPs are
  124. issued after the last reference to the file object is removed.
  125. Once the close IRP is called, it is guaranteed by IO Manager that no
  126. other IOCTL call will happen for the object we are about to close.
  127. Therefore actual cleanup for the object must happen at this time,
  128. but * not * at the cleanup time.
  129. Arguments:
  130. pDeviceObject - Supplies a pointer to the target device object.
  131. pIrp - Supplies a pointer to IO request packet.
  132. Return Value:
  133. NTSTATUS - Completion status.
  134. --***************************************************************************/
  135. NTSTATUS
  136. UlClose(
  137. IN PDEVICE_OBJECT pDeviceObject,
  138. IN PIRP pIrp
  139. )
  140. {
  141. NTSTATUS status;
  142. PIO_STACK_LOCATION pIrpSp;
  143. UNREFERENCED_PARAMETER( pDeviceObject );
  144. //
  145. // Sanity check.
  146. //
  147. PAGED_CODE();
  148. UL_ENTER_DRIVER( "UlClose", pIrp );
  149. status = STATUS_SUCCESS;
  150. //
  151. // Snag the current IRP stack pointer.
  152. //
  153. pIrpSp = IoGetCurrentIrpStackLocation( pIrp );
  154. //
  155. // We have to delete the associated object.
  156. //
  157. if (pDeviceObject == g_pUlAppPoolDeviceObject &&
  158. IS_EX_APP_POOL( pIrpSp->FileObject ))
  159. {
  160. UlTrace(OPEN_CLOSE, (
  161. "UlClose: closing AppPool object %p\n",
  162. pIrpSp->FileObject
  163. ));
  164. UlCloseAppPoolProcess(GET_APP_POOL_PROCESS(pIrpSp->FileObject));
  165. }
  166. else if (pDeviceObject == g_pUlFilterDeviceObject &&
  167. IS_EX_FILTER_PROCESS( pIrpSp->FileObject ))
  168. {
  169. UlTrace(OPEN_CLOSE, (
  170. "UlClose: closing Filter object %p\n",
  171. pIrpSp->FileObject
  172. ));
  173. UlCloseFilterProcess(GET_FILTER_PROCESS(pIrpSp->FileObject));
  174. }
  175. else if (pDeviceObject == g_pUcServerDeviceObject &&
  176. IS_EX_SERVER(pIrpSp->FileObject ))
  177. {
  178. PUC_PROCESS_SERVER_INFORMATION pServInfo;
  179. pServInfo = (PUC_PROCESS_SERVER_INFORMATION)
  180. pIrpSp->FileObject->FsContext;
  181. UlTrace(OPEN_CLOSE, (
  182. "UlClose: closing Server object %p, %p\n",
  183. pIrpSp->FileObject, pServInfo
  184. ));
  185. //
  186. // Free our context.
  187. //
  188. UcCloseServerInformation(pServInfo);
  189. }
  190. else if (pDeviceObject == g_pUlControlDeviceObject &&
  191. IS_EX_CONTROL_CHANNEL( pIrpSp->FileObject ))
  192. {
  193. PUL_CONTROL_CHANNEL pControlChannel =
  194. GET_CONTROL_CHANNEL( pIrpSp->FileObject );
  195. UlTrace(OPEN_CLOSE, (
  196. "UlClose: closing control channel object %p, %p\n",
  197. pIrpSp->FileObject, pControlChannel
  198. ));
  199. UlCloseControlChannel( pControlChannel );
  200. }
  201. else
  202. {
  203. ASSERT(!"Invalid Device Object !");
  204. }
  205. pIrp->IoStatus.Status = status;
  206. UlCompleteRequest( pIrp, IO_NO_INCREMENT );
  207. UL_LEAVE_DRIVER( "UlClose" );
  208. RETURN(status);
  209. } // UlClose