VOID FatCloseWorker ( _In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PVOID Context ) /*++ Routine Description: This routine is a shim between the IO worker package and FatFspClose. Arguments: DeviceObject - Registration device object, unused Context - Context value, unused Return Value: None. --*/ { PAGED_CODE(); UNREFERENCED_PARAMETER( DeviceObject ); FsRtlEnterFileSystem(); FatFspClose (Context); FsRtlExitFileSystem(); }
VOID FatCloseWorker ( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context ) /*++ Routine Description: This routine is a shim between the IO worker package and FatFspClose. Arguments: DeviceObject - Registration device object, unused Context - Context value, unused Return Value: None. --*/ { FsRtlEnterFileSystem(); FatFspClose (Context); FsRtlExitFileSystem(); }
VOID SecondaryTryClose( IN PIRP_CONTEXT IrpContext2 OPTIONAL, IN PSECONDARY Secondary ) { IRP_CONTEXT irpContext; BOOLEAN secondaryResourceAcquired = FALSE; BOOLEAN acquiredVcb = FALSE; BOOLEAN wait; PFCB fcb; BOOLEAN acquiredFcb = FALSE; BOOLEAN removedFcb; PFCB nextFcb = NULL; PVOID restartKey; PLIST_ENTRY deletedFcbListEntry; DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles start\n") ); try { RtlZeroMemory( &irpContext, sizeof(IRP_CONTEXT) ); SetFlag( irpContext.Flags, IRP_CONTEXT_FLAG_WAIT ); SetFlag( irpContext.NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT ); irpContext.Vcb = &Secondary->VolDo->Vcb; secondaryResourceAcquired = SecondaryAcquireResourceSharedLite( &irpContext, &Secondary->Resource, FALSE ); if (secondaryResourceAcquired == FALSE) leave; wait = BooleanFlagOn( irpContext.Flags, IRP_CONTEXT_FLAG_WAIT ); acquiredVcb = FatAcquireExclusiveSecondaryVcb( &irpContext, irpContext.Vcb ); if (acquiredVcb == FALSE) leave; SetFlag( Secondary->VolDo->Vcb.NdFatFlags, ND_FAT_VCB_FLAG_TRY_CLOSE_FILES ); FatFspClose( &Secondary->VolDo->Vcb ); ClearFlag( Secondary->VolDo->Vcb.NdFatFlags, ND_FAT_VCB_FLAG_TRY_CLOSE_FILES ); DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles FatFspClose, Secondary->VolDo->Vcb.SecondaryOpenCount = %d\n", Secondary->VolDo->Vcb.SecondaryOpenFileCount) ); SetFlag( irpContext.NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES ); Secondary_TryCloseFilExts( Secondary ); } finally { ASSERT( nextFcb == NULL ); ClearFlag( irpContext.NdFatFlags, ND_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES ); if (acquiredVcb) FatReleaseSecondaryVcb( &irpContext, irpContext.Vcb ); DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles exit\n") ); ExAcquireFastMutex( &Secondary->FastMutex ); Secondary->TryCloseActive = FALSE; ExReleaseFastMutex( &Secondary->FastMutex ); if (secondaryResourceAcquired) SecondaryReleaseResourceLite( NULL, &Secondary->Resource ); Secondary_Dereference( Secondary ); } return; }
VOID SecondaryTryClose ( IN PSECONDARY Secondary ) { PIRP_CONTEXT irpContext; BOOLEAN secondaryResourceAcquired = FALSE; BOOLEAN acquiredVcb = FALSE; BOOLEAN wait; irpContext = FatAllocateIrpContext(); if (irpContext == NULL) { return; } DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles start\n") ); try { RtlZeroMemory( irpContext, sizeof(IRP_CONTEXT) ); SetFlag( irpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); SetFlag( irpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_SECONDARY_CONTEXT ); irpContext->Vcb = &Secondary->VolDo->Vcb; secondaryResourceAcquired = SecondaryAcquireResourceSharedLite( irpContext, &Secondary->VolDo->Resource, FALSE ); if (secondaryResourceAcquired == FALSE) { leave; } wait = BooleanFlagOn( irpContext->Flags, IRP_CONTEXT_FLAG_WAIT ); acquiredVcb = FatAcquireExclusiveVcb( irpContext, irpContext->Vcb ); if (acquiredVcb == FALSE) { leave; } FsRtlEnterFileSystem(); FatFspClose( &Secondary->VolDo->Vcb ); FsRtlExitFileSystem(); DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles FatFspClose, Secondary->VolDo->Vcb.SecondaryOpenCount = %d\n", Secondary->VolDo->Vcb.SecondaryOpenFileCount) ); SetFlag( irpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES ); Secondary_TryCloseFilExts( Secondary ); } finally { ClearFlag( irpContext->NdasFatFlags, NDAS_FAT_IRP_CONTEXT_FLAG_TRY_CLOSE_FILES ); if (acquiredVcb) { FatReleaseVcb( irpContext, irpContext->Vcb ); } DebugTrace2( 0, Dbg, ("Secondary_TryCloseFiles exit\n") ); ExAcquireFastMutex( &Secondary->FastMutex ); Secondary->TryCloseActive = FALSE; ExReleaseFastMutex( &Secondary->FastMutex ); if (secondaryResourceAcquired) SecondaryReleaseResourceLite( NULL, &Secondary->VolDo->Resource ); Secondary_Dereference(Secondary); FatFreeIrpContext(irpContext); } return; }
VOID FatPurgeReferencedFileObjects ( IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN FAT_FLUSH_TYPE FlushType ) /*++ Routine Description: This routine non-recursively walks from the given FcbOrDcb and trys to force Cc or Mm to close any sections it may be holding on to. Arguments: Fcb - Supplies a pointer to either an fcb or a dcb FlushType - Specifies the kind of flushing to perform Return Value: None. --*/ { PFCB OriginalFcb = Fcb; PFCB NextFcb; PAGED_CODE(); DebugTrace(+1, Dbg, "FatPurgeReferencedFileObjects, Fcb = %08lx\n", Fcb ); ASSERT( FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ); // // First, if we have a delayed close, force it closed. // FatFspClose(Fcb->Vcb); // // Walk the directory tree forcing sections closed. // // Note that it very important to get the next node to visit before // acting on the current node. This is because acting on a node may // make it, and an arbitrary number of direct ancestors, vanish. // Since we never visit ancestors in our top-down enumeration scheme, we // can safely continue the enumeration even when the tree is vanishing // beneath us. This is way cool. // while ( Fcb != NULL ) { NextFcb = FatGetNextFcbTopDown(IrpContext, Fcb, OriginalFcb); // // Check for the EA file fcb // if ( !FlagOn(Fcb->DirentFatFlags, FAT_DIRENT_ATTR_VOLUME_ID) ) { FatForceCacheMiss( IrpContext, Fcb, FlushType ); } Fcb = NextFcb; } DebugTrace(-1, Dbg, "FatPurgeReferencedFileObjects (VOID)\n", 0 ); return; }