📄 sfilter.c
字号:
//========================== 指定头文件 ===========================
#include "sfilter.h"
//===================== 指定每个函数的内存页面属性 =====================
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#if DBG && WINVER >= 0x0501
#pragma alloc_text(PAGE, DriverUnload)
#endif
#pragma alloc_text(INIT, SfReadDriverParameters)
#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(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)
#endif
#endif
//==========================全局变量============================
PDRIVER_OBJECT gSFilterDriverObject = NULL; //保存由/O管理器生成并传入的"驱动对象"
PDEVICE_OBJECT gSFilterControlDeviceObject = NULL; //保存由本过滤驱动生成的"控制设备对象"
FAST_MUTEX gSfilterAttachLock; //定义一个"快速互斥"结构变量(对象)
// ======================== 设备类型名 ===========================
static const PCHAR DeviceTypeNames[] = {
"",
"BEEP",
"CD_ROM",
"CD_ROM_FILE_SYSTEM",
"CONTROLLER",
"DATALINK",
"DFS",
"DISK",
"DISK_FILE_SYSTEM",
"FILE_SYSTEM",
"INPORT_PORT",
"KEYBOARD",
"MAILSLOT",
"MIDI_IN",
"MIDI_OUT",
"MOUSE",
"MULTI_UNC_PROVIDER",
"NAMED_PIPE",
"NETWORK",
"NETWORK_BROWSER",
"NETWORK_FILE_SYSTEM",
"NULL",
"PARALLEL_PORT",
"PHYSICAL_NETCARD",
"PRINTER",
"SCANNER",
"SERIAL_MOUSE_PORT",
"SERIAL_PORT",
"SCREEN",
"SOUND",
"STREAMS",
"TAPE",
"TAPE_FILE_SYSTEM",
"TRANSPORT",
"UNKNOWN",
"VIDEO",
"VIRTUAL_DISK",
"WAVE_IN",
"WAVE_OUT",
"8042_PORT",
"NETWORK_REDIRECTOR",
"BATTERY",
"BUS_EXTENDER",
"MODEM",
"VDM",
"MASS_STORAGE",
"SMB",
"KS",
"CHANGER",
"SMARTCARD",
"ACPI",
"DVD",
"FULLSCREEN_VIDEO",
"DFS_FILE_SYSTEM",
"DFS_VOLUME",
"SERENUM",
"TERMSRV",
"KSEC"
};
//========================== 驱动入口函数 ===========================
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath )
{
PFAST_IO_DISPATCH fastIoDispatch; //定义FAST_IO_DISPATCH结构变量
UNICODE_STRING nameString; //定义名字串结构变量
NTSTATUS status; //状态码
ULONG i;
//---------------------------------------------------------------------------------------
#if WINVER >= 0x0501 //条件编译,如果OS版本是WinXP以上,编译这两句,否则不编译
SfLoadDynamicFunctions(); //
SfGetCurrentVersion(); //
#endif //条件编译结束语句
//---------------------------------------------------------------------------------------
SfReadDriverParameters( RegistryPath ); //
gSFilterDriverObject = DriverObject; //将I/O管理器传入的驱动对象保存到全局变量gSFilterDriverObject中
//---------------------------------------------------------------------------------------
#if DBG && WINVER >= 0x0501 //若OS版本是xp以上且生成checked版,编译这些语句,否则不编译
if (NULL != gSfDynamicFunctions.EnumerateDeviceObjectList)
{
gSFilterDriverObject->DriverUnload = DriverUnload; //注册驱动卸载函数
}
#endif //条件编译结束语句
ExInitializeFastMutex( &gSfilterAttachLock ); //初始化"FastMutex(快速互斥)"对象,尔后多线程只能互斥访问它
//----------------------------------创建控制设备对象--------------------------------
//创建控制设备名称
RtlInitUnicodeString( &nameString, L"\\FileSystem\\Filters\\SFilter" ); //用来创建文件系统控制设备对象
//创建控制设备对象
status = IoCreateDevice( DriverObject,
0, //没有"设备扩展"
&nameString, //设备名: FileSystem\\Filters\\SFilter
FILE_DEVICE_DISK_FILE_SYSTEM, //设备类型: 磁盘文件系统
FILE_DEVICE_SECURE_OPEN, //设备特征: 对发送到CDO的打开请求进行安全检查
FALSE, //生成一个在用户模式下使用的设备
&gSFilterControlDeviceObject ); //接收生成的"控制设备对象"
if (status == STATUS_OBJECT_PATH_NOT_FOUND) //判断是否"未找到路径"
{
RtlInitUnicodeString( &nameString, L"\\FileSystem\\SFilterCDO" ); //重新创建"控制设备名称"
status = IoCreateDevice( DriverObject, 0,
&nameString, //设备名: FileSystem\\SFilterCDO
FILE_DEVICE_DISK_FILE_SYSTEM,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&gSFilterControlDeviceObject ); //接收生成的"控制设备对象"
}
if (!NT_SUCCESS( status )) //判断IoCreateDevice调用是否成功
{
KdPrint(( "SFilter!DriverEntry: Error creating control device object \"%wZ\", status=%08x\n", &nameString, status ));
return status; //错误返回(创建CDO失败)
}
//----------------------------------注册IRP派遣函数---------------------------------
//注册默认派遣函数
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) //ntifs.h中定义的IRP类型码中最大的一个是IRP_MJ_MAXIMUM_FUNCTION(主功能码)
{
DriverObject->MajorFunction[i] = SfPassThrough; //将驱动的所有派遣函数都设为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;
//-------------------------------注册FastIo派遣函数---------------------------------
fastIoDispatch = ExAllocatePoolWithTag( NonPagedPool, //从非分页池中分配
sizeof( FAST_IO_DISPATCH ), //要分配的字节数
SFLT_POOL_TAG ); //指定一个4字节的标签(前面已宏定义:'tlFS')
if (!fastIoDispatch) //内存分配失败
{
IoDeleteDevice( gSFilterControlDeviceObject ); //删除上面创建的CDO
return STATUS_INSUFFICIENT_RESOURCES; //返回一个错误status码(资源不足)
}
RtlZeroMemory( fastIoDispatch, sizeof( FAST_IO_DISPATCH ) ); //分配成功(为FastIo分派表分配存贮),清0分派表
DriverObject->FastIoDispatch = fastIoDispatch; //将FastIo分派表保存到驱动对象的FastIoDispatch域
fastIoDispatch->SizeOfFastIoDispatch = sizeof( FAST_IO_DISPATCH ); //设置FastIo分派表的长度域
fastIoDispatch->FastIoCheckIfPossible = SfFastIoCheckIfPossible; //设置FastIo分派函数,共21个
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;
//--------------------------------注册fsFilter回调函数-------------------------------
#if WINVER >= 0x0501 //如果OS版本为WinXP以上,编译这段代码,否则不编译
{
FS_FILTER_CALLBACKS fsFilterCallbacks;
if (NULL != gSfDynamicFunctions.RegisterFileSystemFilterCallbacks)
{
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 );
return status;
}
}
}
#endif //条件编译结束语句
//---------------------------------------------------------------------------------------
status = IoRegisterFsRegistrationChange( DriverObject, SfFsNotification );
if (!NT_SUCCESS( status ))
{
KdPrint(( "SFilter!DriverEntry: Error registering FS change notification, status=%08x\n", status ));
DriverObject->FastIoDispatch = NULL; //注销指向fastIo函数组的指针为NULL
ExFreePoolWithTag( fastIoDispatch, SFLT_POOL_TAG ); //释放分配给fastIo函数组的内存
IoDeleteDevice( gSFilterControlDeviceObject ); //删除上面创建的CDO
return status; //错误返回
}
{
PDEVICE_OBJECT rawDeviceObject;
PFILE_OBJECT fileObject;
RtlInitUnicodeString( &nameString, L"\\Device\\RawDisk" );
status = IoGetDeviceObjectPointer( &nameString, FILE_READ_ATTRIBUTES, &fileObject, &rawDeviceObject );
if (NT_SUCCESS( status ))
{
SfFsNotification( rawDeviceObject, TRUE );
ObDereferenceObject( fileObject );
}
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;
}
//========================== 驱动卸载函数 ===========================
#if DBG && WINVER >= 0x0501
VOID DriverUnload( IN PDRIVER_OBJECT DriverObject )
{
PSFILTER_DEVICE_EXTENSION devExt;
PFAST_IO_DISPATCH fastIoDispatch;
NTSTATUS status;
ULONG numDevices;
ULONG i;
LARGE_INTEGER interval;
PDEVICE_OBJECT devList[DEVOBJ_LIST_SIZE];
ASSERT(DriverObject == gSFilterDriverObject);
SF_LOG_PRINT( SFDEBUG_DISPLAY_ATTACHMENT_NAMES, ("SFilter!DriverUnload: Unloading driver (%p)\n", DriverObject) );
IoUnregisterFsRegistrationChange( DriverObject, SfFsNotification );
for (;;)
{
ASSERT( NULL != gSfDynamicFunctions.EnumerateDeviceObjectList );
status = (gSfDynamicFunctions.EnumerateDeviceObjectList)( DriverObject, devList, sizeof(devList), &numDevices);
if (numDevices <= 0)
{
break;
}
numDevices = min( numDevices, DEVOBJ_LIST_SIZE );
for (i=0; i < numDevices; i++)
{
devExt = devList[i]->DeviceExtension;
if (NULL != devExt)
{
IoDetachDevice( devExt->AttachedToDeviceObject );
}
}
interval.QuadPart = (5 * DELAY_ONE_SECOND); //delay 5 seconds
KeDelayExecutionThread( KernelMode, FALSE, &interval );
for (i=0; i < numDevices; i++)
{
if (NULL != devList[i]->DeviceExtension)
{
SfCleanupMountedDevice( devList[i] );
}
else
{
ASSERT(devList[i] == gSFilterControlDeviceObject);
gSFilterControlDeviceObject = NULL;
}
IoDeleteDevice( devList[i] );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -