📄 metadatamanagerinit.c
字号:
}
DebugTrace( DEBUG_TRACE_INFO,
("[Fmm]: Context cleanup complete.\n") );
}
//
// Instance setup/teardown routines.
//
NTSTATUS
FmmInstanceSetup (
__in PCFLT_RELATED_OBJECTS FltObjects,
__in FLT_INSTANCE_SETUP_FLAGS Flags,
__in DEVICE_TYPE VolumeDeviceType,
__in FLT_FILESYSTEM_TYPE VolumeFilesystemType
)
/*++
Routine Description:
This routine is called whenever a new instance is created on a volume. This
gives us a chance to decide if we need to attach to this volume or not.
Arguments:
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance and its associated volume.
Flags - Flags describing the reason for this attach request.
Return Value:
STATUS_SUCCESS - attach
STATUS_FLT_DO_NOT_ATTACH - do not attach
--*/
{
PFMM_INSTANCE_CONTEXT instanceContext = NULL;
PDEVICE_OBJECT diskDeviceObject;
NTSTATUS status = STATUS_SUCCESS;
UNREFERENCED_PARAMETER( Flags );
UNREFERENCED_PARAMETER( VolumeDeviceType );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance setup started (Volume = %p, Instance = %p)\n",
FltObjects->Volume,
FltObjects->Instance) );
//
// Check if the file system mounted is ntfs
//
// The sample picks NTFS as an example. The metadata
// handling demostrated in the sample can be applied
// to any file system
//
if (VolumeFilesystemType != FLT_FSTYPE_NTFS) {
//
// An unknown file system is mounted which we do not care
//
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Unsupported file system mounted (Volume = %p, Instance = %p)\n",
FltObjects->Volume,
FltObjects->Instance) );
status = STATUS_NOT_SUPPORTED;
goto FmmInstanceSetupCleanup;
}
//
// Get the disk device object and make sure it is a disk device type and does not
// have any of the device characteristics we do not support.
//
// The sample picks the device characteristics to demonstrate how to access and
// check the device characteristics in order to make a decision to attach. The
// metadata handling demostrated in the sample is not limited to the
// characteristics we have used in the sample.
//
status = FltGetDiskDeviceObject( FltObjects->Volume, &diskDeviceObject );
if (!NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
("[Fmm]: Failed to get device object (Volume = %p, Status = 0x%08X)\n",
FltObjects->Volume,
status) );
goto FmmInstanceSetupCleanup;
}
if (diskDeviceObject->DeviceType != FILE_DEVICE_DISK ||
FlagOn( diskDeviceObject->Characteristics, FMM_UNSUPPORTED_DEVICE_CHARACS )) {
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Unsupported device type or device characteristics (Volume = %p, Instance = %p DiskDeviceObjectDeviceTYpe = 0x%x, DiskDeviceObjectCharacteristics = 0x%x)\n",
FltObjects->Volume,
FltObjects->Instance,
diskDeviceObject->DeviceType,
diskDeviceObject->Characteristics) );
ObDereferenceObject( diskDeviceObject );
status = STATUS_NOT_SUPPORTED;
goto FmmInstanceSetupCleanup;
}
ObDereferenceObject( diskDeviceObject );
//
// Allocate and initialize the context for this volume
//
status = FltAllocateContext( FltObjects->Filter,
FLT_INSTANCE_CONTEXT,
FMM_INSTANCE_CONTEXT_SIZE,
NonPagedPool,
&instanceContext );
if( !NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
("[Fmm]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
FltObjects->Volume,
FltObjects->Instance,
status) );
goto FmmInstanceSetupCleanup;
}
ASSERT( instanceContext != NULL );
RtlZeroMemory( instanceContext, FMM_INSTANCE_CONTEXT_SIZE );
instanceContext->Flags = 0;
instanceContext->Instance = FltObjects->Instance;
instanceContext->Volume = FltObjects->Volume;
ExInitializeResourceLite( &instanceContext->MetadataResouce );
//
// Set the instance context.
//
status = FltSetInstanceContext( FltObjects->Instance,
FLT_SET_CONTEXT_KEEP_IF_EXISTS,
instanceContext,
NULL );
if( !NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR,
("[Fmm]: Failed to set instance context (Volume = %p, Instance = %p, Status = 0x%08X)\n",
FltObjects->Volume,
FltObjects->Instance,
status) );
goto FmmInstanceSetupCleanup;
}
//
// Acquire exclusive access to the instance context
//
FmmAcquireResourceExclusive( &instanceContext->MetadataResouce );
//
// Sanity - the instance context cannot be in a transition state during instance setup
//
ASSERT( !FlagOn( instanceContext->Flags, INSTANCE_CONTEXT_F_TRANSITION) );
//
// Open the filter metadata on disk
//
// The sample will attach to volume if it finds its metadata file on the volume.
// If this is a manual attachment then the sample filter will create its metadata
// file and attach to the volume.
//
status = FmmOpenMetadata( instanceContext,
(BOOLEAN) FlagOn( Flags, FLTFL_INSTANCE_SETUP_MANUAL_ATTACHMENT ) );
//
// Relinquish exclusive access to the instance context
//
FmmReleaseResource( &instanceContext->MetadataResouce);
if (!NT_SUCCESS( status )) {
goto FmmInstanceSetupCleanup;
}
FmmInstanceSetupCleanup:
//
// If FltAllocateContext suceeded then we MUST release the context,
// irrespective of whether FltSetInstanceContext suceeded or not.
//
// FltAllocateContext increments the ref count by one.
// A successful FltSetInstanceContext increments the ref count by one
// and also associates the context with the file system object
//
// FltReleaseContext decrements the ref count by one.
//
// When FltSetInstanceContext succeeds, calling FltReleaseContext will
// leave the context with a ref count of 1 corresponding to the internal
// reference to the context from the file system structures
//
// When FltSetInstanceContext fails, calling FltReleaseContext will
// leave the context with a ref count of 0 which is correct since
// there is no reference to the context from the file system structures
//
if ( instanceContext != NULL ) {
FltReleaseContext( instanceContext );
}
if (NT_SUCCESS( status )) {
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n",
FltObjects->Volume,
FltObjects->Instance) );
} else {
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n",
FltObjects->Volume,
FltObjects->Instance) );
}
return status;
}
NTSTATUS
FmmInstanceQueryTeardown (
__in PCFLT_RELATED_OBJECTS FltObjects,
__in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags
)
/*++
Routine Description:
This is called when an instance is being manually deleted by a
call to FltDetachVolume or FilterDetach thereby giving us a
chance to fail that detach request.
Arguments:
FltObjects - Pointer to the FLT_RELATED_OBJECTS data structure containing
opaque handles to this filter, instance and its associated volume.
Flags - Indicating where this detach request came from.
Return Value:
Returns the status of this operation.
--*/
{
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance query teardown started (Instance = %p)\n",
FltObjects->Instance) );
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance query teadown ended (Instance = %p)\n",
FltObjects->Instance) );
return STATUS_SUCCESS;
}
VOID
FmmInstanceTeardownStart (
__in PCFLT_RELATED_OBJECTS FltObjects,
__in FLT_INSTANCE_TEARDOWN_FLAGS Flags
)
/*++
Routine Description:
This routine is called at the start 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.
--*/
{
UNREFERENCED_PARAMETER( FltObjects );
UNREFERENCED_PARAMETER( Flags );
PAGED_CODE();
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance teardown start started (Instance = %p)\n",
FltObjects->Instance) );
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance teardown start ended (Instance = %p)\n",
FltObjects->Instance) );
}
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->MetadataResouce );
//
// Sanity - the instance context cannot be in a transition state during instance teardown complete
//
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->MetadataResouce );
FltReleaseContext( instanceContext );
}
DebugTrace( DEBUG_TRACE_INSTANCES,
("[Fmm]: Instance teardown complete ended (Instance = %p)\n",
FltObjects->Instance) );
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -