NTSTATUS
DriverEntry (
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
/*++
//
创建设备对象且登记它监视所有的活动文件系统
--*/
{
PFAST_IO_DISPATCH fastIoDispatch;
UNICODE_STRING nameString;
NTSTATUS status;
ULONG i;
#if WINVER >= 0x0501
//
试图载入动态函数
SfLoadDynamicFunctions();
//
得到
OS
版本
SfGetCurrentVersion();
#endif
//
得到注册表值
SfReadDriverParameters( RegistryPath );
//
保存我们的驱动对象,设置我们的
UNLOAD
例程
gSFilterDriverObject = DriverObject;
#if DBG && WINVER >= 0x0501
//
如果我们可以枚举我们驱动拥有的显著的设备对象,仅支持测试环境的卸载
//
卸载只用于开发环境
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;
}
//
设置其它全局变量
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 );
//
创建控制设备对象,这个对象代表这个驱动。注意它没有设备扩展。
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
部分
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;
}
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
DriverObject->MajorFunction[i] = SfPassThrough;
}
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
数据结构且填入它
//
由于历史的原因,这些快速
IO
不发送到过滤驱动,而是直接发送到基础文件系统。
//
在
WINXP
及以后版本,如果你想拦截这些回调,你可以使用新的系统例程
FsRtlRegisterFileSystemFilterCallbacks
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;
#if WINVER >= 0x0501
{
FS_FILTER_CALLBACKS fsFilterCallbacks;
if (NULL != gSfDynamicFunctions.RegisterFileSystemFilterCallbacks) {
//
为我们通过
FsFilter
接口接收的操作设置回调
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;
fsFilterCallbacks.PreAcquireForModifiedPageWriter = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostAcquireForModifiedPageWriter = SfPostFsFilterPassThrough;
fsFilterCallbacks.PreReleaseForModifiedPageWriter = SfPreFsFilterPassThrough;
fsFilterCallbacks.PostReleaseForModifiedPageWriter = SfPostFsFilterPassThrough;
status = (gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)( DriverObject,
&fsFilterCallbacks );
if (!NT_SUCCESS( status )) {
DriverObject->FastIoDispatch = NULL;
ExFreePoolWithTag( fastIoDispatch, SFLT_POOL_TAG_FASTIO );
IoDeleteDevice( gSFilterControlDeviceObject );
return status;
}
}
}
#endif
//
当一个新的文件系统被装入或者当任何文件系统被卸载时,注册的回调函数
// SfFsNotification
将被调用
status = IoRegisterFsRegistrationChange( DriverObject, SfFsNotification );
if (!NT_SUCCESS( status ))
{
KdPrint(( "SFilter!DriverEntry: Error registering FS change notification, status=%08x/n",
status ));
DriverObject->FastIoDispatch = NULL;
ExFreePoolWithTag( fastIoDispatch, SFLT_POOL_TAG_FASTIO );
IoDeleteDevice( gSFilterControlDeviceObject );
return status;
}
//
试图附着到合适的
RAW
文件系统设备对象,因为他们没有被
IoRegisterFsRegistrationChange
枚举
{
PDEVICE_OBJECT rawDeviceObject;
PFILE_OBJECT fileObject;
//
附着到
RawDisk
设备
RtlInitUnicodeString( &nameString, L"//Device//RawDisk" );
status = IoGetDeviceObjectPointer(
&nameString,
FILE_READ_ATTRIBUTES,
&fileObject,
&rawDeviceObject );
if (NT_SUCCESS( status )) {
SfFsNotification( rawDeviceObject, TRUE );
ObDereferenceObject( fileObject );
}
//
附着到
RawCdRom
设备
RtlInitUnicodeString( &nameString, L"//Device//RawCdRom" );
status = IoGetDeviceObjectPointer(
&nameString,
FILE_READ_ATTRIBUTES,
&fileObject,
&rawDeviceObject );
if (NT_SUCCESS( status ))
{
SfFsNotification( rawDeviceObject, TRUE );
ObDereferenceObject( fileObject );
}
}
//
清除控制设备对象上的初始化标志,因为我们现在成功完成初始化
ClearFlag( gSFilterControlDeviceObject->Flags, DO_DEVICE_INITIALIZING );
return STATUS_SUCCESS;
}