NTSTATUS FmmReleaseMetadataFileReferences ( __inout PFLT_CALLBACK_DATA Cbd ) /*++ Routine Description: This routine releases all references to the metadata file on the specified instance. Arguments: Cbd - Supplies a pointer to the callbackData which declares the requested operation. Return Value: Status Note: This routine takes care of the synchronization needed to access the metadata file object and handle This routine will also set the MetadataOpenTriggerFileObject in the instance context to the file object of the volume that triggered the release of the metadata file references. --*/ { NTSTATUS status = STATUS_SUCCESS; PFMM_INSTANCE_CONTEXT instanceContext = NULL; PAGED_CODE(); // // Get the instance context // status = FltGetInstanceContext( Cbd->Iopb->TargetInstance, &instanceContext ); if (!NT_SUCCESS( status )) { DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS, ("[Fmm]: FmmReleaseMetadataFileReferences -> Failed to get instance context.\n") ); goto FmmReleaseMetadataFileReferencesCleanup; } // // Acquire exclusive access to the instance context // FmmAcquireResourceExclusive( &instanceContext->MetadataResouce); if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION)) { // // If this instance context is in a transition state, it implies that // the instance context lock has been released while sending an operation // down to the file system. The reason for doing so is to prevent a potential // deadlock if an underlying filter sends an IO to the top of the filter // stack while we are holding the resource // // We have managed to acquire this resource in this state of transition. // It would be incorrect to use or modify the instance context in any way // in this situation. So we simply let go. // status = STATUS_FILE_LOCK_CONFLICT; DebugTrace( DEBUG_TRACE_ERROR | DEBUG_TRACE_METADATA_OPERATIONS, ("[Fmm]: FmmReleaseMetadataFileReferences -> Failed to get exclusive access to instance context since it is in a state of transition.\n") ); } else { // // Close the metadata file if it is open // if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED )) { DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS, ("[Fmm]: FmmReleaseMetadataFileReferences -> Releasing references to metadata handle and file object (InstanceContext = %p VolumeFileObject = %p)\n", instanceContext, Cbd->Iopb->TargetFileObject) ); // // Close the metadata file object // FmmCloseMetadata( instanceContext ); // // Save the volume file object for which we are releasing our references // instanceContext->MetadataOpenTriggerFileObject = Cbd->Iopb->TargetFileObject; } else { DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS, ("[Fmm]: FmmReleaseMetadataFileReferences -> Exit without attempting to release references to metadata handle and file object (InstanceContext = %p, VolumeFileObject = %p, MetadataOpenTriggerFileObject = %p, MetadataAlreadyOpen = 0x%x)\n", instanceContext, Cbd->Iopb->TargetFileObject, instanceContext->MetadataOpenTriggerFileObject, FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED )) ); } } // // Relinquish exclusive access to the instance context // FmmReleaseResource( &instanceContext->MetadataResouce); FmmReleaseMetadataFileReferencesCleanup: // // Release the references we have acquired // if (instanceContext != NULL) { FltReleaseContext( instanceContext ); } return status; }
VOID FmmInstanceTeardownComplete ( _In_ PCFLT_RELATED_OBJECTS FltObjects, _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags ) /*++ Routine Description: This routine is called at the end of instance teardown. Arguments: FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing opaque handles to this filter, instance and its associated volume. Flags - Reason why this instance is been deleted. Return Value: None. --*/ { PFMM_INSTANCE_CONTEXT instanceContext; NTSTATUS status; UNREFERENCED_PARAMETER( Flags ); PAGED_CODE(); DebugTrace( DEBUG_TRACE_INSTANCES, ("[Fmm]: Instance teardown complete started (Instance = %p)\n", FltObjects->Instance) ); status = FltGetInstanceContext( FltObjects->Instance, &instanceContext ); if (NT_SUCCESS( status )) { // // Acquire exclusive access to the instance context // FmmAcquireResourceExclusive( &instanceContext->MetadataResource ); // // Sanity - the instance context cannot be in a transition state during instance teardown complete // FLT_ASSERT( !FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION) ); if (FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED )) { // // Close the metadata file // FmmCloseMetadata( instanceContext ); } // // Relinquish exclusive access to the instance context // FmmReleaseResource( &instanceContext->MetadataResource ); FltReleaseContext( instanceContext ); } DebugTrace( DEBUG_TRACE_INSTANCES, ("[Fmm]: Instance teardown complete ended (Instance = %p)\n", FltObjects->Instance) ); }