diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/mailslot/cleanup.c | |
download | NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2 NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip |
Diffstat (limited to 'private/ntos/mailslot/cleanup.c')
-rw-r--r-- | private/ntos/mailslot/cleanup.c | 690 |
1 files changed, 690 insertions, 0 deletions
diff --git a/private/ntos/mailslot/cleanup.c b/private/ntos/mailslot/cleanup.c new file mode 100644 index 000000000..ee00a985a --- /dev/null +++ b/private/ntos/mailslot/cleanup.c @@ -0,0 +1,690 @@ +/*++ + +Copyright (c) 1989 Microsoft Corporation + +Module Name: + + cleanup.c + +Abstract: + + This module implements the file cleanup routine for MSFS called by the + dispatch driver. + +Author: + + Manny Weiser (mannyw) 23-Jan-1991 + +Revision History: + +--*/ + +#include "mailslot.h" + +// +// The debug trace level +// + +#define Dbg (DEBUG_TRACE_CLEANUP) + +// +// local procedure prototypes +// + +NTSTATUS +MsCommonCleanup ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp + ); + +NTSTATUS +MsCleanupCcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PCCB Ccb + ); + +NTSTATUS +MsCleanupFcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PFCB Fcb + ); + +NTSTATUS +MsCleanupRootDcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PROOT_DCB RootDcb + ); + +NTSTATUS +MsCleanupVcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PVCB Vcb + ); + +#ifdef ALLOC_PRAGMA +#pragma alloc_text( PAGE, MsCleanupCcb ) +#pragma alloc_text( PAGE, MsCleanupFcb ) +#pragma alloc_text( PAGE, MsCleanupRootDcb ) +#pragma alloc_text( PAGE, MsCleanupVcb ) +#pragma alloc_text( PAGE, MsCommonCleanup ) +#pragma alloc_text( PAGE, MsFsdCleanup ) +#endif + +NTSTATUS +MsFsdCleanup ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp + ) + +/*++ + +Routine Description: + + This routine implements the FSD part of the NtCleanupFile API calls. + +Arguments: + + MsfsDeviceObject - Supplies the device object to use. + + Irp - Supplies the Irp being processed + +Return Value: + + NTSTATUS - The Fsd status for the Irp + +--*/ + +{ + NTSTATUS status; + + PAGED_CODE(); + DebugTrace(+1, Dbg, "MsFsdCleanup\n", 0); + + // + // Call the common cleanup routine. + // + + try { + + status = MsCommonCleanup( MsfsDeviceObject, Irp ); + + } except(MsExceptionFilter( GetExceptionCode() )) { + + // + // We had some trouble trying to perform the requested + // operation, so we'll abort the I/O request with + // the error status that we get back from the + // execption code. + // + + status = MsProcessException( MsfsDeviceObject, Irp, GetExceptionCode() ); + } + + // + // Return to our caller. + // + + DebugTrace(-1, Dbg, "MsFsdCleanup -> %08lx\n", status ); + return status; +} + + +NTSTATUS +MsCommonCleanup ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp + ) + +/*++ + +Routine Description: + + This is the common routine for cleaning up a file. + +Arguments: + + Irp - Supplies the Irp to process + +Return Value: + + NTSTATUS - the return status for the operation + +--*/ + +{ + PIO_STACK_LOCATION irpSp; + NTSTATUS status; + NODE_TYPE_CODE nodeTypeCode; + PVOID fsContext, fsContext2; + PVCB vcb; + + PAGED_CODE(); + irpSp = IoGetCurrentIrpStackLocation( Irp ); + + DebugTrace(+1, Dbg, "MsCommonCleanup\n", 0); + DebugTrace( 0, Dbg, "MsfsDeviceObject = %08lx\n", (ULONG)MsfsDeviceObject); + DebugTrace( 0, Dbg, "Irp = %08lx\n", (ULONG)Irp); + DebugTrace( 0, Dbg, "FileObject = %08lx\n", (ULONG)irpSp->FileObject); + + // + // Get the VCB we are trying to access. + // + + vcb = &MsfsDeviceObject->Vcb; + + // + // Acquire exclusive access to the VCB. + // + + MsAcquireExclusiveVcb( vcb ); + + try { + + // + // Get the a referenced pointer to the node and make sure it is + // not being closed. + // + + if ((nodeTypeCode = MsDecodeFileObject( irpSp->FileObject, + &fsContext, + &fsContext2 )) == NTC_UNDEFINED) { + + DebugTrace(0, Dbg, "The mailslot is disconnected\n", 0); + + MsCompleteRequest( Irp, STATUS_FILE_FORCED_CLOSED ); + status = STATUS_FILE_FORCED_CLOSED; + + DebugTrace(-1, Dbg, "MsCommonWrite -> %08lx\n", status ); + try_return( NOTHING ); + } + + // + // Decide how to handle this IRP. + // + + switch (nodeTypeCode) { + + case MSFS_NTC_FCB: // Cleanup a server handle to a mailslot file + + status = MsCleanupFcb( MsfsDeviceObject, + Irp, + (PFCB)fsContext); + + MsCompleteRequest( Irp, status ); + MsDereferenceFcb( (PFCB)fsContext ); + break; + + case MSFS_NTC_CCB: // Cleanup a client handle to a mailslot file + + status = MsCleanupCcb( MsfsDeviceObject, + Irp, + (PCCB)fsContext); + + MsCompleteRequest( Irp, STATUS_SUCCESS ); + MsDereferenceCcb( (PCCB)fsContext ); + status = STATUS_SUCCESS; + break; + + case MSFS_NTC_VCB: // Cleanup MSFS + + status = MsCleanupVcb( MsfsDeviceObject, + Irp, + (PVCB)fsContext); + + MsCompleteRequest( Irp, STATUS_SUCCESS ); + MsDereferenceVcb( (PVCB)fsContext ); + status = STATUS_SUCCESS; + break; + + case MSFS_NTC_ROOT_DCB: // Cleanup root directory + + status = MsCleanupRootDcb( MsfsDeviceObject, + Irp, + (PROOT_DCB)fsContext); + + MsCompleteRequest( Irp, STATUS_SUCCESS ); + MsDereferenceRootDcb( (PROOT_DCB)fsContext ); + status = STATUS_SUCCESS; + break; + + #ifdef MSDBG + default: + + // + // This is not one of ours. + // + + KeBugCheck( MAILSLOT_FILE_SYSTEM ); + break; + #endif + + } + + try_exit: NOTHING; + + } finally { + + MsReleaseVcb( vcb ); + DebugTrace(-1, Dbg, "MsCommonCleanup -> %08lx\n", status); + + } + + DebugTrace(-1, Dbg, "MsCommonCleanup -> %08lx\n", status); + return status; +} + + +NTSTATUS +MsCleanupCcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PCCB Ccb + ) + +/*++ + +Routine Description: + + The routine cleans up a CCB. + +Arguments: + + MsfsDeviceObject - A pointer the the mailslot file system device object. + + Irp - Supplies the IRP associated with the cleanup. + + Ccb - Supplies the CCB for the mailslot to clean up. + +Return Value: + + NTSTATUS - An appropriate completion status + +--*/ +{ + NTSTATUS status; + PFCB fcb; + + PAGED_CODE(); + DebugTrace(+1, Dbg, "MsCleanupCcb...\n", 0); + + // + // Get a pointer to the FCB. + // + + fcb = Ccb->Fcb; + + // + // Acquire exclusive access to the FCB + // + + MsAcquireExclusiveFcb( fcb ); + + status = STATUS_SUCCESS; + + try { + + // + // Ensure that this CCB still belongs to an active open mailslot. + // + + MsVerifyCcb( Ccb ); + + // + // Set the CCB to closing and remove this CCB from the active list. + // + + Ccb->Header.NodeState = NodeStateClosing; + RemoveEntryList( &Ccb->CcbLinks ); + + // + // Cleanup the share access. + // + + IoRemoveShareAccess( Ccb->FileObject, &fcb->ShareAccess ); + + } finally { + + MsReleaseFcb( fcb ); + DebugTrace(-1, Dbg, "MsCloseFcb -> %08lx\n", status); + } + + // + // And return to our caller + // + + return status; +} + + +NTSTATUS +MsCleanupFcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PFCB Fcb + ) + +/*++ + +Routine Description: + + This routine cleans up an FCB. All outstanding i/o on the file + object are completed with an error status. + +Arguments: + + MsfsDeviceObject - A pointer the the mailslot file system device object. + + Irp - Supplies the IRP associated with the cleanup. + + Fcb - Supplies the FCB for the mailslot to clean up. + +Return Value: + + NTSTATUS - An appropriate completion status + +--*/ +{ + NTSTATUS status; + PDATA_QUEUE dataQueue; + PDATA_ENTRY dataEntry; + PLIST_ENTRY listEntry; + PIRP oldIrp; + PCCB ccb; + PWORK_CONTEXT workContext; + PKTIMER timer; + + PAGED_CODE(); + DebugTrace(+1, Dbg, "MsCleanupFcb, Fcb = %08lx\n", (ULONG)Fcb); + + // + // Acquire exclusive access to the FCB. + // + + MsAcquireExclusiveFcb( Fcb ); + + status = STATUS_SUCCESS; + + try { + + // + // Ensure that this FCB still belongs to an active open mailslot. + // + + MsVerifyFcb( Fcb ); + + // + // Remove the entry from the prefix table, and then remove the full + // file name. + // + + MsAcquirePrefixTableLock(); + RtlRemoveUnicodePrefix( &Fcb->Vcb->PrefixTable, &Fcb->PrefixTableEntry ); + MsReleasePrefixTableLock(); + + // + // Remove ourselves from our parent DCB's queue. + // + + RemoveEntryList( &(Fcb->ParentDcbLinks) ); + + // + // Complete all outstanding I/O on this FCB. + // + + dataQueue = &Fcb->DataQueue; + dataQueue->QueueState = -1; + + for (listEntry = MsGetNextDataQueueEntry( dataQueue ); + !MsIsDataQueueEmpty(dataQueue); + listEntry = MsGetNextDataQueueEntry( dataQueue ) ) { + + // + // This is an outstanding I/O request on this FCB. + // Remove it from our queue and complete the request + // if one is outstanding. + // + + dataEntry = CONTAINING_RECORD( listEntry, DATA_ENTRY, ListEntry ); + + // + // Cancel the timer if there is a timer for the read request. + // + + workContext = dataEntry->TimeoutWorkContext; + if (workContext != NULL) { + + DebugTrace( 0, Dbg, "Cancelling a timer\n", 0); + + // + // There was a timer on this read operation. Attempt + // to cancel the operation. If the cancel operation + // is successful, then we must cleanup after the operation. + // If it was unsuccessful the timer DPC will run, and + // will eventually cleanup. + // + + timer = &workContext->Timer; + + if (KeCancelTimer( timer ) ) { + + // + // Release the reference to the FCB. + // + + MsDereferenceFcb( workContext->Fcb ); + + // + // Free the memory from the work context, the timer, + // and the DPC. + // + + ExFreePool( workContext ); + + } + + } + + oldIrp = MsRemoveDataQueueEntry( dataQueue, dataEntry ); + + if (oldIrp != NULL) { + + DebugTrace(0, Dbg, "Completing IRP %08lx\n", (ULONG)oldIrp ); + MsCompleteRequest( oldIrp, STATUS_FILE_FORCED_CLOSED ); + + } + + } + + // + // Now cleanup all the CCB's on this FCB, to ensure that new + // write IRP will not be processed. + // + + MsAcquireCcbListLock(); + + listEntry = Fcb->Specific.Fcb.CcbQueue.Flink; + + while( listEntry != &Fcb->Specific.Fcb.CcbQueue ) { + + ccb = (PCCB)CONTAINING_RECORD( listEntry, CCB, CcbLinks ); + + ccb->Header.NodeState = NodeStateClosing; + + // + // Get the next CCB on this FCB. + // + + listEntry = listEntry->Flink; + } + + MsReleaseCcbListLock(); + + // + // Cleanup the share access. + // + + IoRemoveShareAccess( Fcb->FileObject, &Fcb->ShareAccess); + + // + // Mark the FCB closing. + // + + Fcb->Header.NodeState = NodeStateClosing; + + } finally { + + ASSERT (MsIsDataQueueEmpty(dataQueue)); + + MsReleaseFcb( Fcb ); + DebugTrace(-1, Dbg, "MsCloseFcb -> %08lx\n", status); + } + + // + // Return to the caller. + // + + return status; + +} + + +NTSTATUS +MsCleanupRootDcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PROOT_DCB RootDcb + ) + +/*++ + +Routine Description: + + This routine cleans up a Root DCB. + +Arguments: + + MsfsDeviceObject - A pointer the the mailslot file system device object. + + Irp - Supplies the IRP associated with the cleanup. + + RootDcb - Supplies the root dcb for MSFS. + +Return Value: + + NTSTATUS - An appropriate completion status + +--*/ +{ + NTSTATUS status; + PIO_STACK_LOCATION irpSp; + + PAGED_CODE(); + DebugTrace(+1, Dbg, "MsCleanupRootDcb...\n", 0); + + // + // Now acquire exclusive access to the Vcb. + // + + MsAcquireExclusiveVcb( RootDcb->Vcb ); + + status = STATUS_SUCCESS; + + try { + + // + // Ensure that this root DCB is still active. + // + + MsVerifyRootDcb( RootDcb ); + + irpSp = IoGetCurrentIrpStackLocation( Irp ); + + IoRemoveShareAccess( irpSp->FileObject, + &RootDcb->ShareAccess ); + + } finally { + + MsReleaseVcb( RootDcb->Vcb ); + DebugTrace(-1, Dbg, "MsCleanupRootDcb -> %08lx\n", status); + + } + + // + // Return to the caller. + // + + return status; +} + + +NTSTATUS +MsCleanupVcb ( + IN PMSFS_DEVICE_OBJECT MsfsDeviceObject, + IN PIRP Irp, + IN PVCB Vcb + ) + +/*++ + +Routine Description: + + The routine cleans up a VCB. + +Arguments: + + MsfsDeviceObject - A pointer the the mailslot file system device object. + + Irp - Supplies the IRP associated with the cleanup. + + Vcb - Supplies the VCB for MSFS. + +Return Value: + + NTSTATUS - An appropriate completion status + +--*/ + +{ + NTSTATUS status; + PIO_STACK_LOCATION irpSp; + + PAGED_CODE(); + DebugTrace(+1, Dbg, "MsCleanupVcb...\n", 0); + + // + // Now acquire exclusive access to the Vcb + // + + MsAcquireExclusiveVcb( Vcb ); + + status = STATUS_SUCCESS; + + try { + + // + // Ensure that this VCB is still active. + // + + MsVerifyVcb( Vcb ); + + irpSp = IoGetCurrentIrpStackLocation( Irp ); + + IoRemoveShareAccess( irpSp->FileObject, + &Vcb->ShareAccess ); + + } finally { + + MsReleaseVcb( Vcb ); + DebugTrace(-1, Dbg, "MsCleanupVcb -> %08lx\n", status); + } + + // + // And return to our caller + // + + return status; +} |