📄 sfilter.c
字号:
IN BOOLEAN IsFile
);
NTSTATUS
SfLoadRules(
OUT PHANDLE FileHandle
);
ULONG
SfMatchRules(
IN PCWSTR FileName
);
BOOLEAN
SfMatchWithPattern(
IN PCWSTR Pattern,
IN PCWSTR Name
);
BOOLEAN
SfMatchOkay(
IN PCWSTR Pattern
);
NTSTATUS
SfForwardIrpSyncronously(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
/////////////////////////////////////////////////////////////////////////////
//
// Assign text sections for each routine.
//
/////////////////////////////////////////////////////////////////////////////
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#if DBG && WINVER >= 0x0501
#pragma alloc_text(PAGE, DriverUnload)
#endif
#pragma alloc_text(PAGE, SfFsNotification)
#pragma alloc_text(PAGE, SfCreate)
#pragma alloc_text(PAGE, SfCleanupClose)
#pragma alloc_text(PAGE, SfFsControl)
#pragma alloc_text(PAGE, SfFsControlMountVolume)
#pragma alloc_text(PAGE, SfFsControlMountVolumeComplete)
#pragma alloc_text(PAGE, SfFsControlLoadFileSystem)
#pragma alloc_text(PAGE, SfFsControlLoadFileSystemComplete)
#pragma alloc_text(PAGE, SfFastIoCheckIfPossible)
#pragma alloc_text(PAGE, SfFastIoRead)
#pragma alloc_text(PAGE, SfFastIoWrite)
#pragma alloc_text(PAGE, SfFastIoQueryBasicInfo)
#pragma alloc_text(PAGE, SfFastIoQueryStandardInfo)
#pragma alloc_text(PAGE, SfFastIoLock)
#pragma alloc_text(PAGE, SfFastIoUnlockSingle)
#pragma alloc_text(PAGE, SfFastIoUnlockAll)
#pragma alloc_text(PAGE, SfFastIoUnlockAllByKey)
#pragma alloc_text(PAGE, SfFastIoDeviceControl)
#pragma alloc_text(PAGE, SfFastIoDetachDevice)
#pragma alloc_text(PAGE, SfFastIoQueryNetworkOpenInfo)
#pragma alloc_text(PAGE, SfFastIoMdlRead)
#pragma alloc_text(PAGE, SfFastIoPrepareMdlWrite)
#pragma alloc_text(PAGE, SfFastIoMdlWriteComplete)
#pragma alloc_text(PAGE, SfFastIoReadCompressed)
#pragma alloc_text(PAGE, SfFastIoWriteCompressed)
#pragma alloc_text(PAGE, SfFastIoQueryOpen)
#pragma alloc_text(PAGE, SfAttachDeviceToDeviceStack)
#pragma alloc_text(PAGE, SfAttachToFileSystemDevice)
#pragma alloc_text(PAGE, SfDetachFromFileSystemDevice)
#pragma alloc_text(PAGE, SfAttachToMountedDevice)
#pragma alloc_text(PAGE, SfIsAttachedToDevice)
#pragma alloc_text(PAGE, SfIsAttachedToDeviceW2K)
#pragma alloc_text(INIT, SfReadDriverParameters)
#pragma alloc_text(INIT, SfLoadRules)
#pragma alloc_text(PAGE, SfIsShadowCopyVolume)
#if WINVER >= 0x0501
#pragma alloc_text(INIT, SfLoadDynamicFunctions)
#pragma alloc_text(INIT, SfGetCurrentVersion)
#pragma alloc_text(PAGE, SfEnumerateFileSystemVolumes)
#pragma alloc_text(PAGE, SfIsAttachedToDeviceWXPAndLater)
#pragma alloc_text(PAGE, SfGetBaseDeviceObjectName)
#endif
#endif
/////////////////////////////////////////////////////////////////////////////
//
// Functions
//
/////////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
Routine Description:
// 创建设备对象且登记它监视所有的活动文件系统
This is the initialization routine for the SFILTER file system filter
driver. This routine creates the device object that represents this
driver in the system and registers it for watching all file systems that
register or unregister themselves as active file systems.
Arguments:
DriverObject - Pointer to driver object created by the system.
Return Value:
The function value is the final status from the initialization operation.
--*/
{
PFAST_IO_DISPATCH fastIoDispatch;
UNICODE_STRING nameString;
NTSTATUS status;
ULONG i;
#if WINVER >= 0x0501
// 试图载入动态函数
// Try to load the dynamic functions that may be available for our use.
//
SfLoadDynamicFunctions();
// 得到OS版本
// Now get the current OS version that we will use to determine what logic
// paths to take when this driver is built to run on various OS version.
//
SfGetCurrentVersion();
#endif
// 得到注册表值
// Get Registry values
//
SfReadDriverParameters( RegistryPath );
// 保存我们的驱动对象,设置我们的UNLOAD例程
// Save our Driver Object, set our UNLOAD routine
//
gSFilterDriverObject = DriverObject;
#if DBG && WINVER >= 0x0501
//
// MULTIVERSION NOTE:
// 如果我们可以枚举我们驱动拥有的显著的设备对象,仅支持测试环境的卸载
// We can only support unload for testing environments if we can enumerate
// the outstanding device objects that our driver has.
//
// 卸载只用于开发环境
// Unload is useful for development purposes. It is not recommended for
// production versions
//
if (NULL != gSfDynamicFunctions.EnumerateDeviceObjectList) {
gSFilterDriverObject->DriverUnload = DriverUnload;
}
#endif
// 初始化一个资源变量,可被用于同步一线程集合,
// 在释放资源占用内存前调用ExDeleteResourceLite
//
status = ExInitializeResourceLite(&gRulesResource);
if (!NT_SUCCESS(status))
{
KdPrint(("SFilter!DriverEntry: ExInitializeResourceLite failed, Status=%08x\n", status));
return status;
}
//// 从SystemRoot目录的xefs.dat中检索匹配规则
////
//status = SfLoadRules(&gRuleFileHandle);
//if (!NT_SUCCESS(status))
//{
// ExDeleteResourceLite(&gRulesResource);
// KdPrint(("SFilter!DriverEntry: SfLoadRules failed, Status=%08x\n", status));
// return status;
//}
// 设置其它全局变量
// Setup other global variables
//
ExInitializeFastMutex( &gSfilterAttachLock );
// #define FSCTX_GENERIC_TABLE_POOL_SIZE sizeof(FILE_CONTEXT) + 32
ExInitializePagedLookasideList(
&gFsCtxLookAsideList,
NULL,
NULL,
0,
FSCTX_GENERIC_TABLE_POOL_SIZE,
SFLT_POOL_TAG_MYSELF,
0
);
ExInitializePagedLookasideList(
&gFileContextLookAsideList,
NULL,
NULL,
0,
sizeof(FILE_CONTEXT),
SFLT_POOL_TAG_MYSELF,
0
);
ExInitializePagedLookasideList(
&gFileNameLookAsideList,
NULL,
NULL,
0,
MAX_PATH * sizeof(WCHAR),
SFLT_POOL_TAG_MYSELF,
0
);
ExInitializeNPagedLookasideList(
&gReadWriteCompletionCtxLookAsideList,
NULL,
NULL,
0,
sizeof(READ_WRITE_COMPLETION_CONTEXT),
SFLT_POOL_TAG_MYSELF,
0
);
// 初始化用于名字缓冲的后视列表。避免在堆栈上有一个大名字缓冲。它也被名字查找例程使用(NLxxx)
// Initialize the lookaside list for name buffering. This is used in
// several places to avoid having a large name buffer on the stack. It is
// also needed by the name lookup routines (NLxxx).
//
ExInitializePagedLookasideList( &gSfNameBufferLookasideList,
NULL,
NULL,
0,
SFILTER_LOOKASIDE_SIZE,
SFLT_POOL_TAG_NAME_BUFFER,
0 );
// 创建控制设备对象,这个对象代表这个驱动。注意它没有设备扩展。
// Create the Control Device Object (CDO). This object represents this
// driver. Note that it does not have a device extension.
//
RtlInitUnicodeString( &nameString, L"\\FileSystem\\Filters\\SFilterCDO" );
status = IoCreateDevice( DriverObject,
0, //has no device extension
&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject );
if (status == STATUS_OBJECT_PATH_NOT_FOUND) {
// XP以前的版本名字空间中未加入Filters路径,所以将我们的控制设备对象放入
// 对象名字空间的\FileSystem部分
// This must be a version of the OS that doesn't have the Filters
// path in its namespace. This was added in Windows XP.
//
// We will try just putting our control device object in the
// \FileSystem portion of the object name space.
//
RtlInitUnicodeString( &nameString, L"\\FileSystem\\SFilterCDO" );
status = IoCreateDevice( DriverObject,
0, //has no device extension
&nameString,
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject );
if (!NT_SUCCESS( status )) {
KdPrint( ("SFilter!DriverEntry: Error creating control device object \"%wZ\", status=%08x\n",
&nameString,
status ));
return status;
}
} else if (!NT_SUCCESS( status )) {
KdPrint(( "SFilter!DriverEntry: Error creating control device object \"%wZ\", status=%08x\n",
&nameString, status ));
return status;
}
//
// Initialize the driver object with this device driver's entry points.
//
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = SfPassThrough;
}
//
// We will use SfCreate for all the create operations
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = SfCreate;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = SfFsControl;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = SfCleanupClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = SfCleanupClose;
DriverObject->MajorFunction[IRP_MJ_READ] = SfRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = SfWrite;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = SfDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = SfSetInformation;
// 分配快速I/O数据结构且填入它
// Allocate fast I/O data structure and fill it in.
//
// NOTE: The following FastIo Routines are not supported:
// AcquireFileForNtCreateSection
// ReleaseFileForNtCreateSection
// AcquireForModWrite
// ReleaseForModWrite
// AcquireForCcFlush
// ReleaseForCcFlush
// 由于历史的原因,这些快速IO不发送到过滤驱动,而是直接发送到基础文件系统。
// 在WINXP及以后版本,如果你想拦截这些回调,你可以使用新的系统例程FsRtlRegisterFileSystemFilterCallbacks
// For historical reasons these FastIO's have never been sent to filters
// by the NT I/O system. Instead, they are sent directly to the base
// file system. On Windows XP and later OS releases, you can use the new
// system routine "FsRtlRegisterFileSystemFilterCallbacks" if you need to
// intercept these callbacks (see below).
//
fastIoDispatch = ExAllocatePoolWithTag( NonPagedPool,
sizeof( FAST_IO_DISPATCH ),
SFLT_POOL_TAG_FASTIO );
if (!fastIoDispatch) {
IoDeleteDevice( gSFilterControlDeviceObject );
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory( fastIoDispatch, sizeof( FAST_IO_DISPATCH ) );
fastIoDispatch->SizeOfFastIoDispatch = sizeof( FAST_IO_DISPATCH );
fastIoDispatch->FastIoCheckIfPossible = SfFastIoCheckIfPossible;
fastIoDispatch->FastIoRead = SfFastIoRead;
fastIoDispatch->FastIoWrite = SfFastIoWrite;
fastIoDispatch->FastIoQueryBasicInfo = SfFastIoQueryBasicInfo;
fastIoDispatch->FastIoQueryStandardInfo = SfFastIoQueryStandardInfo;
fastIoDispatch->FastIoLock = SfFastIoLock;
fastIoDispatch->FastIoUnlockSingle = SfFastIoUnlockSingle;
fastIoDispatch->FastIoUnlockAll = SfFastIoUnlockAll;
fastIoDispatch->FastIoUnlockAllByKey = SfFastIoUnlockAllByKey;
fastIoDispatch->FastIoDeviceControl = SfFastIoDeviceControl;
fastIoDispatch->FastIoDetachDevice = SfFastIoDetachDevice;
fastIoDispatch->FastIoQueryNetworkOpenInfo = SfFastIoQueryNetworkOpenInfo;
fastIoDispatch->MdlRead = SfFastIoMdlRead;
fastIoDispatch->MdlReadComplete = SfFastIoMdlReadComplete;
fastIoDispatch->PrepareMdlWrite = SfFastIoPrepareMdlWrite;
fastIoDispatch->MdlWriteComplete = SfFastIoMdlWriteComplete;
fastIoDispatch->FastIoReadCompressed = SfFastIoReadCompressed;
fastIoDispatch->FastIoWriteCompressed = SfFastIoWriteCompressed;
fastIoDispatch->MdlReadCompleteCompressed = SfFastIoMdlReadCompleteCompressed;
fastIoDispatch->MdlWriteCompleteCompressed = SfFastIoMdlWriteCompleteCompressed;
fastIoDispatch->FastIoQueryOpen = SfFastIoQueryOpen;
DriverObject->FastIoDispatch = fastIoDispatch;
//
// VERSION NOTE:
//
// There are 6 FastIO routines for which file system filters are bypassed as
// the requests are passed directly to the base file system. These 6 routines
// are AcquireFileForNtCreateSection, ReleaseFileForNtCreateSection,
// AcquireForModWrite, ReleaseForModWrite, AcquireForCcFlush, and
// ReleaseForCcFlush.
//
// In Windows XP and later, the FsFilter callbacks were introduced to allow
// filters to safely hook these operations. See the IFS Kit documentation for
// more details on how these new interfaces work.
//
// MULTIVERSION NOTE:
//
// If built for Windows XP or later, this driver is built to run on
// multiple versions. When this is the case, we will test
// for the presence of FsFilter callbacks registration API. If we have it,
// then we will register for those callbacks, otherwise, we will not.
//
#if WINVER >= 0x0501
{
FS_FILTER_CALLBACKS fsFilterCallbacks;
if (NULL != gSfDynamicFunctions.RegisterFileSystemFilterCallbacks) {
// 为我们通过FsFilter接口接收的操作设置回调
// Setup the callbacks for the operations we receive through
// the FsFilter interface.
//
// NOTE: You only need to register for those routines you really
// need to handle. SFilter is registering for all routines
// simply to give an example of how it is done.
//
fsFilterCallbacks.SizeOfFsFilterCallbacks = sizeof( FS_FILTER_CALLBACKS );
fsFilterCallbacks.PreAcquireForSectionSynchronization = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostAcquireForSectionSynchronization = SfPostFsFilterPassThrough;
fsFilterCallbacks.PreReleaseForSectionSynchronization = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostReleaseForSectionSynchronization = SfPostFsFilterPassThrough;
fsFilterCallbacks.PreAcquireForCcFlush = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostAcquireForCcFlush = SfPostFsFilterPassThrough;
fsFilterCallbacks.PreReleaseForCcFlush = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostReleaseForCcFlush = SfPostFsFilterPassThrough;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -