📄 datastore.c
字号:
SetFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED );
}
if (fileName.Buffer != NULL) {
FmmFreeUnicodeString( &fileName );
}
return status;
}
VOID
FmmCloseMetadata (
__in PFMM_INSTANCE_CONTEXT InstanceContext
)
/*++
Routine Description:
This routine closes the filters handle to the metadata file.
Arguments:
InstanceContext - Instance context for this instance.
Return Value:
Void.
Note:
The caller must hold the instance context resource when this routine is called.
--*/
{
PAGED_CODE();
ASSERT( InstanceContext->MetadataHandle );
ASSERT( InstanceContext->MetadataFileObject );
DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: Closing metadata file ... (Volume = %p)\n",
InstanceContext->Volume ) );
//
// Dereference the file object and close the file handle.
//
ObDereferenceObject( InstanceContext->MetadataFileObject );
InstanceContext->MetadataFileObject = NULL;
//
// Mark the beginning of a file system operation
//
FmmBeginFileSystemOperation( InstanceContext );
FltClose( InstanceContext->MetadataHandle );
//
// Mark the end of a file system operation
//
FmmEndFileSystemOperation( InstanceContext );
InstanceContext->MetadataHandle = NULL;
//
// Reset flag to indicate filter metadata is closed
//
ClearFlag( InstanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED );
}
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;
}
NTSTATUS
FmmReacquireMetadataFileReferences (
__inout PFLT_CALLBACK_DATA Cbd
)
/*++
Routine Description:
This routine re-acquires 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 NULL the MetadataOpenTriggerFileObject in the instance context
if it was successfully able to open 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]: FmmReacquireMetadataFileReferences -> Failed to get instance context.\n") );
goto FmmReacquireMetadataFileReferencesCleanup;
}
//
// 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]: FmmReacquireMetadataFileReferences -> Failed to get exclusive access to instance context since it is in a state of transition.\n") );
} else {
//
// Re-open the metadata only if the trigger file object match the file object that
// caused this function to be called
//
if (instanceContext->MetadataOpenTriggerFileObject == Cbd->Iopb->TargetFileObject) {
//
// Open the filter metadata file (do not read the file since we already have
// stuff in memory and do not create if the file does not exist
//
if (!FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_METADATA_OPENED )) {
DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmReacquireMetadataFileReferences -> Re-acquiring references to metadata handle and file object (InstanceContext = %p, VolumeFileObject = %p)\n",
instanceContext,
Cbd->Iopb->TargetFileObject) );
status = FmmOpenMetadata( instanceContext,
FALSE );
//
// Reset the trigger file object since the volume open failed.
//
instanceContext->MetadataOpenTriggerFileObject = NULL;
} else {
DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmReacquireMetadataFileReferences -> Exit without attempting to re-acquire 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 )) );
}
} else {
DebugTrace( DEBUG_TRACE_METADATA_OPERATIONS,
("[Fmm]: FmmReacquireMetadataFileReferences -> Exit without attempting to re-acquire 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 );
FmmReacquireMetadataFileReferencesCleanup:
//
// Release the references we have acquired
//
if (instanceContext != NULL) {
FltReleaseContext( instanceContext );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -