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.9 KiB
404 lines
8.9 KiB
/*++
|
|
|
|
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;
|
|
}
|
|
|