diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /filesys/miniFilter/ctx/CtxInit.c | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'filesys/miniFilter/ctx/CtxInit.c')
| -rw-r--r-- | filesys/miniFilter/ctx/CtxInit.c | 908 |
1 files changed, 908 insertions, 0 deletions
diff --git a/filesys/miniFilter/ctx/CtxInit.c b/filesys/miniFilter/ctx/CtxInit.c new file mode 100644 index 00000000..2654b9f9 --- /dev/null +++ b/filesys/miniFilter/ctx/CtxInit.c @@ -0,0 +1,908 @@ +/*++ + +Copyright (c) 1999 - 2003 Microsoft Corporation + +Module Name: + + ContextInit.c + +Abstract: + + This is the main module of the kernel mode filter driver implementing + the context sample. + + +Environment: + + Kernel mode + + +--*/ + +#include "pch.h" + +// +// Global variables +// + +CTX_GLOBAL_DATA Globals; + + +// +// Local function prototypes +// + +DRIVER_INITIALIZE DriverEntry; +NTSTATUS +DriverEntry ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ); + +NTSTATUS +CtxUnload ( + _In_ FLT_FILTER_UNLOAD_FLAGS Flags + ); + +VOID +CtxContextCleanup ( + _In_ PFLT_CONTEXT Context, + _In_ FLT_CONTEXT_TYPE ContextType + ); + +NTSTATUS +CtxInstanceSetup ( + _In_ PCFLT_RELATED_OBJECTS FltObjects, + _In_ FLT_INSTANCE_SETUP_FLAGS Flags, + _In_ DEVICE_TYPE VolumeDeviceType, + _In_ FLT_FILESYSTEM_TYPE VolumeFilesystemType + ); + +NTSTATUS +CtxInstanceQueryTeardown ( + _In_ PCFLT_RELATED_OBJECTS FltObjects, + _In_ FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags + ); + +VOID +CtxInstanceTeardownStart ( + _In_ PCFLT_RELATED_OBJECTS FltObjects, + _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags + ); + +VOID +CtxInstanceTeardownComplete ( + _In_ PCFLT_RELATED_OBJECTS FltObjects, + _In_ FLT_INSTANCE_TEARDOWN_FLAGS Flags + ); + +#if DBG + +VOID +CtxInitializeDebugLevel ( + _In_ PUNICODE_STRING RegistryPath + ); + +#endif + +// +// Assign text sections for each routine. +// + +#ifdef ALLOC_PRAGMA +#pragma alloc_text(INIT, DriverEntry) + +#if DBG +#pragma alloc_text(INIT, CtxInitializeDebugLevel) +#endif + +#pragma alloc_text(PAGE, CtxUnload) +#pragma alloc_text(PAGE, CtxContextCleanup) +#pragma alloc_text(PAGE, CtxInstanceSetup) +#pragma alloc_text(PAGE, CtxInstanceQueryTeardown) +#pragma alloc_text(PAGE, CtxInstanceTeardownStart) +#pragma alloc_text(PAGE, CtxInstanceTeardownComplete) +#endif + + +// +// Filters callback routines +// + +FLT_OPERATION_REGISTRATION Callbacks[] = { + + { IRP_MJ_CREATE, + FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, + CtxPreCreate, + CtxPostCreate }, + + { IRP_MJ_CLEANUP, + FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, + CtxPreCleanup, + NULL }, + + { IRP_MJ_CLOSE, + FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, + CtxPreClose, + NULL }, + + { IRP_MJ_SET_INFORMATION, + FLTFL_OPERATION_REGISTRATION_SKIP_PAGING_IO, + CtxPreSetInfo, + CtxPostSetInfo }, + + { IRP_MJ_OPERATION_END } +}; + +const FLT_CONTEXT_REGISTRATION ContextRegistration[] = { + + { FLT_INSTANCE_CONTEXT, + 0, + CtxContextCleanup, + CTX_INSTANCE_CONTEXT_SIZE, + CTX_INSTANCE_CONTEXT_TAG }, + + { FLT_FILE_CONTEXT, + 0, + CtxContextCleanup, + CTX_FILE_CONTEXT_SIZE, + CTX_FILE_CONTEXT_TAG }, + + { FLT_STREAM_CONTEXT, + 0, + CtxContextCleanup, + CTX_STREAM_CONTEXT_SIZE, + CTX_STREAM_CONTEXT_TAG }, + + { FLT_STREAMHANDLE_CONTEXT, + 0, + CtxContextCleanup, + CTX_STREAMHANDLE_CONTEXT_SIZE, + CTX_STREAMHANDLE_CONTEXT_TAG }, + + { FLT_CONTEXT_END } +}; + +// +// Filters registration data structure +// + +FLT_REGISTRATION FilterRegistration = { + + sizeof( FLT_REGISTRATION ), // Size + FLT_REGISTRATION_VERSION, // Version + 0, // Flags + ContextRegistration, // Context + Callbacks, // Operation callbacks + CtxUnload, // Filters unload routine + CtxInstanceSetup, // InstanceSetup routine + CtxInstanceQueryTeardown, // InstanceQueryTeardown routine + CtxInstanceTeardownStart, // InstanceTeardownStart routine + CtxInstanceTeardownComplete, // InstanceTeardownComplete routine + NULL, NULL, NULL // Unused naming support callbacks +}; + +// +// Filter driver initialization and unload routines +// + +NTSTATUS +DriverEntry ( + _In_ PDRIVER_OBJECT DriverObject, + _In_ PUNICODE_STRING RegistryPath + ) +/*++ + +Routine Description: + + This is the initialization routine for this filter driver. It registers + itself with the filter manager and initializes all its global data structures. + +Arguments: + + DriverObject - Pointer to driver object created by the system to + represent this driver. + + RegistryPath - Unicode string identifying where the parameters for this + driver are located in the registry. + +Return Value: + + Returns STATUS_SUCCESS. + +--*/ +{ + NTSTATUS status; + + // + // Default to NonPagedPoolNx for non paged pool allocations where supported. + // + + ExInitializeDriverRuntime( DrvRtPoolNxOptIn ); + + RtlZeroMemory( &Globals, sizeof( Globals ) ); + +#if DBG + + // + // Initialize global debug level + // + + CtxInitializeDebugLevel( RegistryPath ); + +#else + + UNREFERENCED_PARAMETER( RegistryPath ); + +#endif + + DebugTrace( DEBUG_TRACE_LOAD_UNLOAD, + ("[Ctx]: Driver being loaded\n") ); + + + + // + // Register with the filter manager + // + + status = FltRegisterFilter( DriverObject, + &FilterRegistration, + &Globals.Filter ); + + if (!NT_SUCCESS( status )) { + + return status; + } + + // + // Start filtering I/O + // + + status = FltStartFiltering( Globals.Filter ); + + if (!NT_SUCCESS( status )) { + + FltUnregisterFilter( Globals.Filter ); + } + + DebugTrace( DEBUG_TRACE_LOAD_UNLOAD, + ("[Ctx]: Driver loaded complete (Status = 0x%08X)\n", + status) ); + + return status; +} + +#if DBG + +VOID +CtxInitializeDebugLevel ( + _In_ PUNICODE_STRING RegistryPath + ) +/*++ + +Routine Description: + + This routine tries to read the filter DebugLevel parameter from + the registry. This value will be found in the registry location + indicated by the RegistryPath passed in. + +Arguments: + + RegistryPath - The path key passed to the driver during DriverEntry. + +Return Value: + + None. + +--*/ +{ + OBJECT_ATTRIBUTES attributes; + HANDLE driverRegKey; + NTSTATUS status; + ULONG resultLength; + UNICODE_STRING valueName; + UCHAR buffer[sizeof( KEY_VALUE_PARTIAL_INFORMATION ) + sizeof( LONG )]; + + Globals.DebugLevel = DEBUG_TRACE_ERROR; + + // + // Open the desired registry key + // + + InitializeObjectAttributes( &attributes, + RegistryPath, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL ); + + status = ZwOpenKey( &driverRegKey, + KEY_READ, + &attributes ); + + if (NT_SUCCESS( status )) { + + // + // Read the DebugFlags value from the registry. + // + + RtlInitUnicodeString( &valueName, L"DebugLevel" ); + + status = ZwQueryValueKey( driverRegKey, + &valueName, + KeyValuePartialInformation, + buffer, + sizeof(buffer), + &resultLength ); + + if (NT_SUCCESS( status )) { + + Globals.DebugLevel = *((PULONG) &(((PKEY_VALUE_PARTIAL_INFORMATION) buffer)->Data)); + } + + // + // Close the registry entry + // + + ZwClose( driverRegKey ); + + } + +} + +#endif + +NTSTATUS +CtxUnload ( + _In_ FLT_FILTER_UNLOAD_FLAGS Flags + ) +/*++ + +Routine Description: + + This is the unload routine for this filter driver. This is called + when the minifilter is about to be unloaded. We can fail this unload + request if this is not a mandatory unloaded indicated by the Flags + parameter. + +Arguments: + + Flags - Indicating if this is a mandatory unload. + +Return Value: + + Returns the final status of this operation. + +--*/ +{ + UNREFERENCED_PARAMETER( Flags ); + + PAGED_CODE(); + + DebugTrace( DEBUG_TRACE_LOAD_UNLOAD, + ("[Ctx]: Unloading driver\n") ); + + + FltUnregisterFilter( Globals.Filter ); + Globals.Filter = NULL; + + return STATUS_SUCCESS; +} + +VOID +CtxContextCleanup ( + _In_ PFLT_CONTEXT Context, + _In_ FLT_CONTEXT_TYPE ContextType + ) +{ + PCTX_INSTANCE_CONTEXT instanceContext; + PCTX_FILE_CONTEXT fileContext; + PCTX_STREAM_CONTEXT streamContext; + PCTX_STREAMHANDLE_CONTEXT streamHandleContext; + + PAGED_CODE(); + + switch(ContextType) { + + case FLT_INSTANCE_CONTEXT: + + instanceContext = (PCTX_INSTANCE_CONTEXT) Context; + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Cleaning up instance context for volume %wZ (Context = %p)\n", + &instanceContext->VolumeName, + Context) ); + + // + // Here the filter should free memory or synchronization objects allocated to + // objects within the instance context. The instance context itself should NOT + // be freed. It will be freed by Filter Manager when the ref count on the + // context falls to zero. + // + + CtxFreeUnicodeString( &instanceContext->VolumeName ); + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Instance context cleanup complete.\n") ); + + break; + + + case FLT_FILE_CONTEXT: + + fileContext = (PCTX_FILE_CONTEXT) Context; + + DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS, + ("[Ctx]: Cleaning up file context for file %wZ (FileContext = %p)\n", + &fileContext->FileName, + fileContext) ); + + + // + // Free the file name + // + + if (fileContext->FileName.Buffer != NULL) { + + CtxFreeUnicodeString(&fileContext->FileName); + } + + DebugTrace( DEBUG_TRACE_FILE_CONTEXT_OPERATIONS, + ("[Ctx]: File context cleanup complete.\n") ); + + break; + + case FLT_STREAM_CONTEXT: + + streamContext = (PCTX_STREAM_CONTEXT) Context; + + DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS, + ("[Ctx]: Cleaning up stream context for file %wZ (StreamContext = %p) \n\tCreateCount = %x \n\tCleanupCount = %x, \n\tCloseCount = %x\n", + &streamContext->FileName, + streamContext, + streamContext->CreateCount, + streamContext->CleanupCount, + streamContext->CloseCount) ); + + // + // Delete the resource and memory the memory allocated for the resource + // + + if (streamContext->Resource != NULL) { + + ExDeleteResourceLite( streamContext->Resource ); + CtxFreeResource( streamContext->Resource ); + } + + // + // Free the file name + // + + if (streamContext->FileName.Buffer != NULL) { + + CtxFreeUnicodeString(&streamContext->FileName); + } + + DebugTrace( DEBUG_TRACE_STREAM_CONTEXT_OPERATIONS, + ("[Ctx]: Stream context cleanup complete.\n") ); + + break; + + case FLT_STREAMHANDLE_CONTEXT: + + streamHandleContext = (PCTX_STREAMHANDLE_CONTEXT) Context; + + DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS, + ("[Ctx]: Cleaning up stream handle context for file %wZ (StreamContext = %p)\n", + &streamHandleContext->FileName, + streamHandleContext) ); + + // + // Delete the resource and memory the memory allocated for the resource + // + + if (streamHandleContext->Resource != NULL) { + + ExDeleteResourceLite( streamHandleContext->Resource ); + CtxFreeResource( streamHandleContext->Resource ); + } + + // + // Free the file name + // + + if (streamHandleContext->FileName.Buffer != NULL) { + + CtxFreeUnicodeString(&streamHandleContext->FileName); + } + + DebugTrace( DEBUG_TRACE_STREAMHANDLE_CONTEXT_OPERATIONS, + ("[Ctx]: Stream handle context cleanup complete.\n") ); + + break; + + } + +} + +// +// Instance setup/teardown routines. +// + +NTSTATUS +CtxInstanceSetup ( + _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 + +--*/ +{ + PCTX_INSTANCE_CONTEXT instanceContext = NULL; + NTSTATUS status = STATUS_SUCCESS; + ULONG volumeNameLength; + + UNREFERENCED_PARAMETER( Flags ); + UNREFERENCED_PARAMETER( VolumeDeviceType ); + UNREFERENCED_PARAMETER( VolumeFilesystemType ); + + PAGED_CODE(); + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance setup started (Volume = %p, Instance = %p)\n", + FltObjects->Volume, + FltObjects->Instance) ); + + + // + // Allocate and initialize the context for this volume + // + + + // + // Allocate the instance context + // + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Allocating instance context (Volume = %p, Instance = %p)\n", + FltObjects->Volume, + FltObjects->Instance) ); + + status = FltAllocateContext( FltObjects->Filter, + FLT_INSTANCE_CONTEXT, + CTX_INSTANCE_CONTEXT_SIZE, + NonPagedPool, + &instanceContext ); + + if (!NT_SUCCESS( status )) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, + ("[Ctx]: Failed to allocate instance context (Volume = %p, Instance = %p, Status = 0x%x)\n", + FltObjects->Volume, + FltObjects->Instance, + status) ); + + goto CtxInstanceSetupCleanup; + } + + // + // Get the NT volume name length + // + + status = FltGetVolumeName( FltObjects->Volume, NULL, &volumeNameLength ); + + if( !NT_SUCCESS( status ) && + (status != STATUS_BUFFER_TOO_SMALL) ) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, + ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n", + FltObjects->Volume, + FltObjects->Instance, + status) ); + + goto CtxInstanceSetupCleanup; + } + + // + // Allocate a string big enough to take the volume name + // + + instanceContext->VolumeName.MaximumLength = (USHORT) volumeNameLength; + status = CtxAllocateUnicodeString( &instanceContext->VolumeName ); + + if( !NT_SUCCESS( status )) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, + ("[Ctx]: Failed to allocate volume name string. (Volume = %p, Instance = %p, Status = 0x%x)\n", + FltObjects->Volume, + FltObjects->Instance, + status) ); + + goto CtxInstanceSetupCleanup; + } + + // + // Get the NT volume name + // + + status = FltGetVolumeName( FltObjects->Volume, &instanceContext->VolumeName, &volumeNameLength ); + + if( !NT_SUCCESS( status ) ) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, + ("[Ctx]: Unexpected failure in FltGetVolumeName. (Volume = %p, Instance = %p, Status = 0x%x)\n", + FltObjects->Volume, + FltObjects->Instance, + status) ); + + goto CtxInstanceSetupCleanup; + } + + + instanceContext->Instance = FltObjects->Instance; + instanceContext->Volume = FltObjects->Volume; + + // + // Set the instance context. + // + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Setting instance context %p for volume %wZ (Volume = %p, Instance = %p)\n", + instanceContext, + &instanceContext->VolumeName, + FltObjects->Volume, + FltObjects->Instance) ); + + status = FltSetInstanceContext( FltObjects->Instance, + FLT_SET_CONTEXT_KEEP_IF_EXISTS, + instanceContext, + NULL ); + + if( !NT_SUCCESS( status )) { + + DebugTrace( DEBUG_TRACE_INSTANCES | DEBUG_TRACE_ERROR, + ("[Ctx]: Failed to set instance context for volume %wZ (Volume = %p, Instance = %p, Status = 0x%08X)\n", + &instanceContext->VolumeName, + FltObjects->Volume, + FltObjects->Instance, + status) ); + goto CtxInstanceSetupCleanup; + } + + +CtxInstanceSetupCleanup: + + // + // 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 ) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Releasing instance context %p (Volume = %p, Instance = %p)\n", + instanceContext, + FltObjects->Volume, + FltObjects->Instance) ); + + FltReleaseContext( instanceContext ); + } + + + if (NT_SUCCESS( status )) { + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will attach to the volume.\n", + FltObjects->Volume, + FltObjects->Instance) ); + } else { + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance setup complete (Volume = %p, Instance = %p). Filter will not attach to the volume.\n", + FltObjects->Volume, + FltObjects->Instance) ); + } + + return status; +} + + +NTSTATUS +CtxInstanceQueryTeardown ( + _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, + ("[Ctx]: Instance query teardown started (Instance = %p)\n", + FltObjects->Instance) ); + + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance query teadown ended (Instance = %p)\n", + FltObjects->Instance) ); + return STATUS_SUCCESS; +} + + +VOID +CtxInstanceTeardownStart ( + _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, + ("[Ctx]: Instance teardown start started (Instance = %p)\n", + FltObjects->Instance) ); + + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance teardown start ended (Instance = %p)\n", + FltObjects->Instance) ); +} + + +VOID +CtxInstanceTeardownComplete ( + _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. + +--*/ +{ + PCTX_INSTANCE_CONTEXT instanceContext; + NTSTATUS status; + + UNREFERENCED_PARAMETER( Flags ); + + PAGED_CODE(); + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance teardown complete started (Instance = %p)\n", + FltObjects->Instance) ); + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Getting instance context (Volume = %p, Instance = %p)\n", + FltObjects->Volume, + FltObjects->Instance) ); + + status = FltGetInstanceContext( FltObjects->Instance, + &instanceContext ); + + if (NT_SUCCESS( status )) { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Instance teardown for volume %wZ (Volume = %p, Instance = %p, InstanceContext = %p)\n", + &instanceContext->VolumeName, + FltObjects->Volume, + FltObjects->Instance, + instanceContext) ); + + + // + // Here the filter may perform any teardown of its own structures associated + // with this instance. + // + // The filter should not free memory or synchronization objects allocated to + // objects within the instance context. That should be performed in the + // cleanup callback for the instance context + // + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS, + ("[Ctx]: Releasing instance context %p for volume %wZ (Volume = %p, Instance = %p)\n", + instanceContext, + &instanceContext->VolumeName, + FltObjects->Volume, + FltObjects->Instance) ); + + FltReleaseContext( instanceContext ); + } else { + + DebugTrace( DEBUG_TRACE_INSTANCE_CONTEXT_OPERATIONS | DEBUG_TRACE_ERROR, + ("[Ctx]: Failed to get instance context (Volume = %p, Instance = %p Status = 0x%x)\n", + FltObjects->Volume, + FltObjects->Instance, + status) ); + } + + DebugTrace( DEBUG_TRACE_INSTANCES, + ("[Ctx]: Instance teardown complete ended (Instance = %p)\n", + FltObjects->Instance) ); +} + |
