⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfilter.c

📁 文件系统过滤驱动的详细代码,含有中文说明及注释
💻 C
📖 第 1 页 / 共 5 页
字号:

//========================== 指定头文件 ===========================

#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 + -