Source code of Windows XP (NT5)
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.

404 lines
8.5 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. cleanup.c
  5. Abstract:
  6. This module implements the file cleanup routine for MUP.
  7. Author:
  8. Manny Weiser (mannyw) 28-Dec-1991
  9. Revision History:
  10. --*/
  11. #include "mup.h"
  12. //
  13. // The debug trace level
  14. //
  15. #define Dbg (DEBUG_TRACE_CLEANUP)
  16. //
  17. // local procedure prototypes
  18. //
  19. NTSTATUS
  20. MupCleanupVcb (
  21. IN PMUP_DEVICE_OBJECT MupDeviceObject,
  22. IN PIRP Irp,
  23. IN PVCB Vcb
  24. );
  25. NTSTATUS
  26. MupCleanupFcb (
  27. IN PMUP_DEVICE_OBJECT MupDeviceObject,
  28. IN PIRP Irp,
  29. IN PFCB Fcb
  30. );
  31. #ifdef ALLOC_PRAGMA
  32. #pragma alloc_text( PAGE, MupCleanup )
  33. #pragma alloc_text( PAGE, MupCleanupFcb )
  34. #pragma alloc_text( PAGE, MupCleanupVcb )
  35. #endif
  36. NTSTATUS
  37. MupCleanup (
  38. IN PMUP_DEVICE_OBJECT MupDeviceObject,
  39. IN PIRP Irp
  40. )
  41. /*++
  42. Routine Description:
  43. This routine implements the the cleanup IRP.
  44. Arguments:
  45. MupDeviceObject - Supplies the device object to use.
  46. Irp - Supplies the Irp being processed
  47. Return Value:
  48. NTSTATUS - The status for the Irp
  49. --*/
  50. {
  51. PIO_STACK_LOCATION irpSp;
  52. NTSTATUS status;
  53. BLOCK_TYPE blockType;
  54. PVOID fsContext, fsContext2;
  55. PFILE_OBJECT FileObject;
  56. MupDeviceObject;
  57. PAGED_CODE();
  58. if (MupEnableDfs) {
  59. if ((MupDeviceObject->DeviceObject.DeviceType == FILE_DEVICE_DFS) ||
  60. (MupDeviceObject->DeviceObject.DeviceType ==
  61. FILE_DEVICE_DFS_FILE_SYSTEM)) {
  62. status = DfsFsdCleanup((PDEVICE_OBJECT) MupDeviceObject, Irp);
  63. return( status );
  64. }
  65. }
  66. FsRtlEnterFileSystem();
  67. try {
  68. irpSp = IoGetCurrentIrpStackLocation( Irp );
  69. FileObject = irpSp->FileObject;
  70. MUP_TRACE_HIGH(TRACE_IRP, MupCleanup_Entry,
  71. LOGPTR(MupDeviceObject)
  72. LOGPTR(Irp)
  73. LOGPTR(FileObject));
  74. DebugTrace(+1, Dbg, "MupCleanup\n", 0);
  75. DebugTrace( 0, Dbg, "MupDeviceObject = %08lx\n", (ULONG)MupDeviceObject);
  76. DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp);
  77. DebugTrace( 0, Dbg, "FileObject = %08lx\n", (ULONG)irpSp->FileObject);
  78. //
  79. // Get the a referenced pointer to the node and make sure it is
  80. // not being closed.
  81. //
  82. if ((blockType = MupDecodeFileObject( irpSp->FileObject,
  83. &fsContext,
  84. &fsContext2 )) == BlockTypeUndefined) {
  85. DebugTrace(0, Dbg, "The file is closed\n", 0);
  86. FsRtlExitFileSystem();
  87. MupCompleteRequest( Irp, STATUS_INVALID_HANDLE );
  88. status = STATUS_INVALID_HANDLE;
  89. DebugTrace(-1, Dbg, "MupCleanup -> %08lx\n", status );
  90. MUP_TRACE_ERROR_HIGH(status, ALL_ERROR, MupCleanup_Error_FileClosed,
  91. LOGSTATUS(status)
  92. LOGPTR(Irp)
  93. LOGPTR(FileObject)
  94. LOGPTR(MupDeviceObject));
  95. return status;
  96. }
  97. //
  98. // Decide how to handle this IRP.
  99. //
  100. switch ( blockType ) {
  101. case BlockTypeVcb: // Cleanup MUP
  102. status = MupCleanupVcb( MupDeviceObject,
  103. Irp,
  104. (PVCB)fsContext
  105. );
  106. MupCompleteRequest( Irp, STATUS_SUCCESS );
  107. MupDereferenceVcb( (PVCB)fsContext );
  108. //
  109. // Cleanup the UNC Provider
  110. //
  111. if ( fsContext2 != NULL ) {
  112. MupCloseUncProvider((PUNC_PROVIDER)fsContext2 );
  113. MupDereferenceUncProvider( (PUNC_PROVIDER)fsContext2 );
  114. MupAcquireGlobalLock();
  115. MupProviderCount--;
  116. MupReleaseGlobalLock();
  117. }
  118. status = STATUS_SUCCESS;
  119. break;
  120. case BlockTypeFcb:
  121. if (((PFCB)fsContext)->BlockHeader.BlockState == BlockStateActive) {
  122. MupCleanupFcb( MupDeviceObject,
  123. Irp,
  124. (PFCB)fsContext
  125. );
  126. status = STATUS_SUCCESS;
  127. }
  128. else {
  129. status = STATUS_INVALID_HANDLE;
  130. MUP_TRACE_HIGH(ERROR, MupCleanup_Error1,
  131. LOGSTATUS(status)
  132. LOGPTR(Irp)
  133. LOGPTR(FileObject)
  134. LOGPTR(MupDeviceObject));
  135. }
  136. MupCompleteRequest( Irp, STATUS_SUCCESS );
  137. MupDereferenceFcb( (PFCB)fsContext );
  138. break;
  139. #ifdef MUPDBG
  140. default:
  141. //
  142. // This is not one of ours.
  143. //
  144. KeBugCheckEx( FILE_SYSTEM, 2, 0, 0, 0 );
  145. break;
  146. #endif
  147. }
  148. } except ( EXCEPTION_EXECUTE_HANDLER ) {
  149. status = GetExceptionCode();
  150. }
  151. FsRtlExitFileSystem();
  152. MUP_TRACE_HIGH(TRACE_IRP, MupCleanup_Exit,
  153. LOGSTATUS(status)
  154. LOGPTR(Irp)
  155. LOGPTR(FileObject)
  156. LOGPTR(MupDeviceObject));
  157. DebugTrace(-1, Dbg, "MupCleanup -> %08lx\n", status);
  158. return status;
  159. }
  160. NTSTATUS
  161. MupCleanupVcb (
  162. IN PMUP_DEVICE_OBJECT MupDeviceObject,
  163. IN PIRP Irp,
  164. IN PVCB Vcb
  165. )
  166. /*++
  167. Routine Description:
  168. The routine cleans up a VCB.
  169. Arguments:
  170. MupDeviceObject - A pointer the the MUP device object.
  171. Irp - Supplies the IRP associated with the cleanup.
  172. Vcb - Supplies the VCB for the MUP.
  173. Return Value:
  174. NTSTATUS - An appropriate completion status
  175. --*/
  176. {
  177. NTSTATUS status;
  178. PIO_STACK_LOCATION irpSp;
  179. MupDeviceObject;
  180. PAGED_CODE();
  181. DebugTrace(+1, Dbg, "MupCleanupVcb...\n", 0);
  182. //
  183. // Now acquire exclusive access to the Vcb
  184. //
  185. ExAcquireResourceExclusiveLite( &MupVcbLock, TRUE );
  186. status = STATUS_SUCCESS;
  187. try {
  188. //
  189. // Ensure that this VCB is still active.
  190. //
  191. MupVerifyBlock( Vcb, BlockTypeVcb );
  192. irpSp = IoGetCurrentIrpStackLocation( Irp );
  193. IoRemoveShareAccess( irpSp->FileObject,
  194. &Vcb->ShareAccess );
  195. } finally {
  196. ExReleaseResourceLite( &MupVcbLock );
  197. DebugTrace(-1, Dbg, "MupCleanupVcb -> %08lx\n", status);
  198. }
  199. //
  200. // And return to our caller
  201. //
  202. return status;
  203. }
  204. NTSTATUS
  205. MupCleanupFcb (
  206. IN PMUP_DEVICE_OBJECT MupDeviceObject,
  207. IN PIRP Irp,
  208. IN PFCB Fcb
  209. )
  210. /*++
  211. Routine Description:
  212. The routine cleans up a FCB.
  213. Arguments:
  214. MupDeviceObject - A pointer the the MUP device object.
  215. Irp - Supplies the IRP associated with the cleanup.
  216. Vcb - Supplies the VCB for the MUP.
  217. Return Value:
  218. NTSTATUS - An appropriate completion status
  219. --*/
  220. {
  221. NTSTATUS status;
  222. PIO_STACK_LOCATION irpSp;
  223. BOOLEAN holdingGlobalLock;
  224. PLIST_ENTRY listEntry, nextListEntry;
  225. PCCB ccb;
  226. MupDeviceObject;
  227. PAGED_CODE();
  228. DebugTrace(+1, Dbg, "MupCleanupVcb...\n", 0);
  229. //
  230. // Now acquire exclusive access to the Vcb
  231. //
  232. MupAcquireGlobalLock();
  233. holdingGlobalLock = TRUE;
  234. status = STATUS_SUCCESS;
  235. try {
  236. //
  237. // Ensure that this FCB is still active.
  238. //
  239. MupVerifyBlock( Fcb, BlockTypeFcb );
  240. Fcb->BlockHeader.BlockState = BlockStateClosing;
  241. MupReleaseGlobalLock();
  242. holdingGlobalLock = FALSE;
  243. irpSp = IoGetCurrentIrpStackLocation( Irp );
  244. //
  245. // Loop through the list of CCBs, and release the open reference
  246. // to each one. We must be careful because:
  247. //
  248. // (1) We cannot dereference the Ccb with the CcbListLock held.
  249. // (2) Dereferncing a Ccb may cause it to be removed from this
  250. // list and freed.
  251. //
  252. ACQUIRE_LOCK( &MupCcbListLock );
  253. listEntry = Fcb->CcbList.Flink;
  254. while ( listEntry != &Fcb->CcbList ) {
  255. nextListEntry = listEntry->Flink;
  256. RELEASE_LOCK( &MupCcbListLock );
  257. ccb = CONTAINING_RECORD( listEntry, CCB, ListEntry );
  258. MupDereferenceCcb( ccb );
  259. ACQUIRE_LOCK( &MupCcbListLock );
  260. listEntry = nextListEntry;
  261. }
  262. RELEASE_LOCK( &MupCcbListLock );
  263. } finally {
  264. if ( holdingGlobalLock ) {
  265. MupReleaseGlobalLock();
  266. }
  267. DebugTrace(-1, Dbg, "MupCleanupFcb -> %08lx\n", status);
  268. }
  269. //
  270. // And return to our caller
  271. //
  272. return status;
  273. }