windows-nt/Source/XPSP1/NT/base/fs/mup/cleanup.c

405 lines
8.5 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
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;
PFILE_OBJECT FileObject;
MupDeviceObject;
PAGED_CODE();
if (MupEnableDfs) {
if ((MupDeviceObject->DeviceObject.DeviceType == FILE_DEVICE_DFS) ||
(MupDeviceObject->DeviceObject.DeviceType ==
FILE_DEVICE_DFS_FILE_SYSTEM)) {
status = DfsFsdCleanup((PDEVICE_OBJECT) MupDeviceObject, Irp);
return( status );
}
}
FsRtlEnterFileSystem();
try {
irpSp = IoGetCurrentIrpStackLocation( Irp );
FileObject = irpSp->FileObject;
MUP_TRACE_HIGH(TRACE_IRP, MupCleanup_Entry,
LOGPTR(MupDeviceObject)
LOGPTR(Irp)
LOGPTR(FileObject));
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 );
MUP_TRACE_ERROR_HIGH(status, ALL_ERROR, MupCleanup_Error_FileClosed,
LOGSTATUS(status)
LOGPTR(Irp)
LOGPTR(FileObject)
LOGPTR(MupDeviceObject));
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:
if (((PFCB)fsContext)->BlockHeader.BlockState == BlockStateActive) {
MupCleanupFcb( MupDeviceObject,
Irp,
(PFCB)fsContext
);
status = STATUS_SUCCESS;
}
else {
status = STATUS_INVALID_HANDLE;
MUP_TRACE_HIGH(ERROR, MupCleanup_Error1,
LOGSTATUS(status)
LOGPTR(Irp)
LOGPTR(FileObject)
LOGPTR(MupDeviceObject));
}
MupCompleteRequest( Irp, STATUS_SUCCESS );
MupDereferenceFcb( (PFCB)fsContext );
break;
#ifdef MUPDBG
default:
//
// This is not one of ours.
//
KeBugCheckEx( FILE_SYSTEM, 2, 0, 0, 0 );
break;
#endif
}
} except ( EXCEPTION_EXECUTE_HANDLER ) {
status = GetExceptionCode();
}
FsRtlExitFileSystem();
MUP_TRACE_HIGH(TRACE_IRP, MupCleanup_Exit,
LOGSTATUS(status)
LOGPTR(Irp)
LOGPTR(FileObject)
LOGPTR(MupDeviceObject));
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
//
ExAcquireResourceExclusiveLite( &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 {
ExReleaseResourceLite( &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;
}