/*++ Copyright (c) 1989 Microsoft Corporation Module Name: cleanup.c Abstract: This module implements the file cleanup routine for MUP. Author: Manny Weiser (mannyw) 28-Dec-1991 Revision History: --*/ #include "mup.h" // // The debug trace level // #define Dbg (DEBUG_TRACE_CLEANUP) // // local procedure prototypes // NTSTATUS MupCleanupVcb ( IN PMUP_DEVICE_OBJECT MupDeviceObject, IN PIRP Irp, IN PVCB Vcb ); NTSTATUS MupCleanupFcb ( IN PMUP_DEVICE_OBJECT MupDeviceObject, IN PIRP Irp, IN PFCB Fcb ); #ifdef ALLOC_PRAGMA #pragma alloc_text( PAGE, MupCleanup ) #pragma alloc_text( PAGE, MupCleanupFcb ) #pragma alloc_text( PAGE, MupCleanupVcb ) #endif NTSTATUS MupCleanup ( IN PMUP_DEVICE_OBJECT MupDeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine implements the the cleanup IRP. Arguments: MupDeviceObject - Supplies the device object to use. Irp - Supplies the Irp being processed Return Value: NTSTATUS - The status for the Irp --*/ { PIO_STACK_LOCATION irpSp; NTSTATUS status; BLOCK_TYPE blockType; PVOID fsContext, fsContext2; MupDeviceObject; PAGED_CODE(); if (MupEnableDfs && MupDeviceObject->DeviceObject.DeviceType == FILE_DEVICE_DFS) { status = DfsFsdCleanup((PDEVICE_OBJECT) MupDeviceObject, Irp); return( status ); } FsRtlEnterFileSystem(); try { irpSp = IoGetCurrentIrpStackLocation( Irp ); DebugTrace(+1, Dbg, "MupCleanup\n", 0); DebugTrace( 0, Dbg, "MupDeviceObject = %08lx\n", (ULONG)MupDeviceObject); DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp); DebugTrace( 0, Dbg, "FileObject = %08lx\n", (ULONG)irpSp->FileObject); // // Get the a referenced pointer to the node and make sure it is // not being closed. // if ((blockType = MupDecodeFileObject( irpSp->FileObject, &fsContext, &fsContext2 )) == BlockTypeUndefined) { DebugTrace(0, Dbg, "The file is closed\n", 0); FsRtlExitFileSystem(); MupCompleteRequest( Irp, STATUS_INVALID_HANDLE ); status = STATUS_INVALID_HANDLE; DebugTrace(-1, Dbg, "MupCleanup -> %08lx\n", status ); return status; } // // Decide how to handle this IRP. // switch ( blockType ) { case BlockTypeVcb: // Cleanup MUP status = MupCleanupVcb( MupDeviceObject, Irp, (PVCB)fsContext ); MupCompleteRequest( Irp, STATUS_SUCCESS ); MupDereferenceVcb( (PVCB)fsContext ); // // Cleanup the UNC Provider // if ( fsContext2 != NULL ) { MupCloseUncProvider((PUNC_PROVIDER)fsContext2 ); MupDereferenceUncProvider( (PUNC_PROVIDER)fsContext2 ); MupAcquireGlobalLock(); MupProviderCount--; MupReleaseGlobalLock(); } status = STATUS_SUCCESS; break; case BlockTypeFcb: status = MupCleanupFcb( MupDeviceObject, Irp, (PFCB)fsContext ); MupCompleteRequest( Irp, STATUS_SUCCESS ); MupDereferenceFcb( (PFCB)fsContext ); status = STATUS_SUCCESS; break; #ifdef MUPDBG default: // // This is not one of ours. // KeBugCheck( FILE_SYSTEM ); break; #endif } } except ( EXCEPTION_EXECUTE_HANDLER ) { status = GetExceptionCode(); } FsRtlExitFileSystem(); DebugTrace(-1, Dbg, "MupCleanup -> %08lx\n", status); return status; } NTSTATUS MupCleanupVcb ( IN PMUP_DEVICE_OBJECT MupDeviceObject, IN PIRP Irp, IN PVCB Vcb ) /*++ Routine Description: The routine cleans up a VCB. Arguments: MupDeviceObject - A pointer the the MUP device object. Irp - Supplies the IRP associated with the cleanup. Vcb - Supplies the VCB for the MUP. Return Value: NTSTATUS - An appropriate completion status --*/ { NTSTATUS status; PIO_STACK_LOCATION irpSp; MupDeviceObject; PAGED_CODE(); DebugTrace(+1, Dbg, "MupCleanupVcb...\n", 0); // // Now acquire exclusive access to the Vcb // ExAcquireResourceExclusive( &MupVcbLock, TRUE ); status = STATUS_SUCCESS; try { // // Ensure that this VCB is still active. // MupVerifyBlock( Vcb, BlockTypeVcb ); irpSp = IoGetCurrentIrpStackLocation( Irp ); IoRemoveShareAccess( irpSp->FileObject, &Vcb->ShareAccess ); } finally { ExReleaseResource( &MupVcbLock ); DebugTrace(-1, Dbg, "MupCleanupVcb -> %08lx\n", status); } // // And return to our caller // return status; } NTSTATUS MupCleanupFcb ( IN PMUP_DEVICE_OBJECT MupDeviceObject, IN PIRP Irp, IN PFCB Fcb ) /*++ Routine Description: The routine cleans up a FCB. Arguments: MupDeviceObject - A pointer the the MUP device object. Irp - Supplies the IRP associated with the cleanup. Vcb - Supplies the VCB for the MUP. Return Value: NTSTATUS - An appropriate completion status --*/ { NTSTATUS status; PIO_STACK_LOCATION irpSp; BOOLEAN holdingGlobalLock; PLIST_ENTRY listEntry, nextListEntry; PCCB ccb; MupDeviceObject; PAGED_CODE(); DebugTrace(+1, Dbg, "MupCleanupVcb...\n", 0); // // Now acquire exclusive access to the Vcb // MupAcquireGlobalLock(); holdingGlobalLock = TRUE; status = STATUS_SUCCESS; try { // // Ensure that this FCB is still active. // MupVerifyBlock( Fcb, BlockTypeFcb ); Fcb->BlockHeader.BlockState = BlockStateClosing; MupReleaseGlobalLock(); holdingGlobalLock = FALSE; irpSp = IoGetCurrentIrpStackLocation( Irp ); // // Loop through the list of CCBs, and release the open reference // to each one. We must be careful because: // // (1) We cannot dereference the Ccb with the CcbListLock held. // (2) Dereferncing a Ccb may cause it to be removed from this // list and freed. // ACQUIRE_LOCK( &MupCcbListLock ); listEntry = Fcb->CcbList.Flink; while ( listEntry != &Fcb->CcbList ) { nextListEntry = listEntry->Flink; RELEASE_LOCK( &MupCcbListLock ); ccb = CONTAINING_RECORD( listEntry, CCB, ListEntry ); MupDereferenceCcb( ccb ); ACQUIRE_LOCK( &MupCcbListLock ); listEntry = nextListEntry; } RELEASE_LOCK( &MupCcbListLock ); } finally { if ( holdingGlobalLock ) { MupReleaseGlobalLock(); } DebugTrace(-1, Dbg, "MupCleanupFcb -> %08lx\n", status); } // // And return to our caller // return status; }