summaryrefslogtreecommitdiffstats
path: root/private/ntos/mailslot/cleanup.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/mailslot/cleanup.c
downloadNT4.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.c690
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;
+}