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;
UNREFERENCED_PARAMETER(RegistryPath);
#if
WINVER >= 0x0501
//
//
Try to load the dynamic functions that may be available for our use.
//
试图载入动态函数
//
SfLoadDynamicFunctions();
//
//
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.
//
得到OS版本
//
SfGetCurrentVersion();
#endif
//
//
Save our Driver Object, set our UNLOAD routine
//
保存我们的驱动对象,设置我们的UNLOAD例程
//
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;
}
//
//
Setup other global variables
//
设置其它全局变量
//
ExInitializeFastMutex(
&
gSfilterAttachLock);
ExInitializePagedLookasideList(
&
gFsCtxLookAsideList,
NULL,
NULL,
0
,
FSCTX_GENERIC_TABLE_POOL_SIZE,
SFLT_POOL_TAG,
0
);
ExInitializePagedLookasideList(
&
gFileNameLookAsideList,
NULL,
NULL,
0
,
MAX_PATH
*
sizeof
(WCHAR),
SFLT_POOL_TAG,
0
);
ExInitializeNPagedLookasideList(
&
gReadWriteCompletionCtxLookAsideList,
NULL,
NULL,
0
,
sizeof
(READ_WRITE_COMPLETION_CONTEXT),
SFLT_POOL_TAG,
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)
{
//
//
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.
//
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));
ExDeleteResourceLite(
&
gRulesResource);
return
Status;
}
}
else
if
(
!
NT_SUCCESS(Status))
{
KdPrint((
"
SFilter!DriverEntry: Error creating control device object \
"
%
wZ\
"
, Status=%08x\n
"
,
&
NameString, Status));
ExDeleteResourceLite(
&
gRulesResource);
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]
=
SfCleanup;
DriverObject
->
MajorFunction[IRP_MJ_CLOSE]
=
SfClose;
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;
//
//
Allocate fast I/O data structure and fill it in.
//
分配快速I/O数据结构且填入它
//
//
NOTE: The following FastIo Routines are not supported:
//
AcquireFileForNtCreateSection
//
ReleaseFileForNtCreateSection
//
AcquireForModWrite
//
ReleaseForModWrite
//
AcquireForCcFlush
//
ReleaseForCcFlush
//
//
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).
//
由于历史的原因,这些快速IO不发送到过滤驱动,而是直接发送到基础文件系统。
//
在WINXP及以后版本,如果你想拦截这些回调,你可以使用新的系
//
统例程FsRtlRegisterFileSystemFilterCallbacks
//
FastIoDispatch
=
ExAllocatePoolWithTag(NonPagedPool,
sizeof
(FAST_IO_DISPATCH), SFLT_POOL_TAG);
if
(
!
FastIoDispatch)
{
IoDeleteDevice(gSFilterControlDeviceObject);
ExDeleteResourceLite(
&
gRulesResource);
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)
{
//
//
Setup the callbacks for the operations we receive through
//
the FsFilter interface.
//
为我们通过FsFilter接口接收的操作设置回调
//
//
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;
FsFilterCallbacks.PreAcquireForModifiedPageWriter
=
SfPreFsFilterPassThrough;
FsFilterCallbacks.PostAcquireForModifiedPageWriter
=
SfPostFsFilterPassThrough;
FsFilterCallbacks.PreReleaseForModifiedPageWriter
=
SfPreFsFilterPassThrough;
FsFilterCallbacks.PostReleaseForModifiedPageWriter
=
SfPostFsFilterPassThrough;
Status
=
(gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)(DriverObject,
&
FsFilterCallbacks);
if
(
!
NT_SUCCESS(Status))
{
DriverObject
->
FastIoDispatch
=
NULL;
ExFreePool(FastIoDispatch);
IoDeleteDevice(gSFilterControlDeviceObject);
ExDeleteResourceLite(
&
gRulesResource);
return
Status;
}
}
}
#endif
//
//
The registered callback routine "SfFsNotification" will be called
//
whenever a new file systems is loaded or when any file system is
//
unloaded.
//
当一个新的文件系统被装入或者当任何文件系统被卸载时,注册的回调函数
//
SfFsNotification将被调用
//
//
VERSION NOTE:
//
//
On Windows XP and later this will also enumerate all existing file
//
systems (except the RAW file systems). On Windows 2000 this does not
//
enumerate the file systems that were loaded before this filter was
//
loaded.
//
Status
=
IoRegisterFsRegistrationChange(DriverObject, SfFsNotification);
if
(
!
NT_SUCCESS(Status))
{
KdPrint((
"
SFilter!DriverEntry: Error registering FS change notification, Status=%08x\n
"
, Status));
DriverObject
->
FastIoDispatch
=
NULL;
ExFreePool(FastIoDispatch);
IoDeleteDevice(gSFilterControlDeviceObject);
ExDeleteResourceLite(
&
gRulesResource);
return
Status;
}
//
//
Attempt to attach to the appropriate RAW file system device objects
//
since they are not enumerated by IoRegisterFsRegistrationChange.
//
试图附着到合适的RAW文件系统设备对象,因为他们没有被IoRegisterFsRegistrationChange枚举
//
{
PDEVICE_OBJECT RawDeviceObject;
PFILE_OBJECT FileObject;
//
//
Attach to RawDisk device
//
附着到RawDisk设备
//
RtlInitUnicodeString(
&
NameString, L
"
\\Device\\RawDisk
"
);
Status
=
IoGetDeviceObjectPointer(
&
NameString,
FILE_READ_ATTRIBUTES,
&
FileObject,
&
RawDeviceObject
);
if
(NT_SUCCESS(Status))
{
SfFsNotification(RawDeviceObject, TRUE);
ObDereferenceObject(FileObject);
}
//
//
Attach to the RawCdRom device
//
附着到RawCdRom设备
//
RtlInitUnicodeString(
&
NameString, L
"
\\Device\\RawCdRom
"
);
Status
=
IoGetDeviceObjectPointer(
&
NameString,
FILE_READ_ATTRIBUTES,
&
FileObject,
&
RawDeviceObject
);
if
(NT_SUCCESS(Status))
{
SfFsNotification(RawDeviceObject, TRUE);
ObDereferenceObject(FileObject);
}
}
//
//
Clear the initializing flag on the control device object since we
//
have now successfully initialized everything.
//
清除控制设备对象上的初始化标志,因为我们现在成功完成初始化
//
ClearFlag(gSFilterControlDeviceObject
->
Flags, DO_DEVICE_INITIALIZING);
IoRegisterDriverReinitialization(DriverObject, SfDriverReinitialization, NULL);
return
STATUS_SUCCESS;
}