📄 ctxinit.c
字号:
/*++
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
//
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
//
// 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;
//
// 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_FILE_SYSTEM_CONTROL,
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_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
};
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,
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 );
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_STREAM_CONTEXT streamContext;
PCTX_STREAMHANDLE_CONTEXT streamHandleContext;
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_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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -