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

📄 sfilter.c

📁 经典的文件透明加解密程序
💻 C
📖 第 1 页 / 共 5 页
字号:
			&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;
}

#if DBG && WINVER >= 0x0501
VOID
DriverUnload(
	IN PDRIVER_OBJECT DriverObject
	)
/*++

Routine Description:

	This routine is called when a driver can be unloaded.  This performs all of
	the necessary cleanup for unloading the driver from memory.  Note that an
	error can NOT be returned from this routine.
	// 执行所有从内存中卸载驱动必要的清除操作,注意错误不能从这个例程返回
	
	When a request is made to unload a driver the IO System will cache that
	information and not actually call this routine until the following states
	have occurred:
	- All device objects which belong to this filter are at the top of their
	  respective attachment chains.
	- All handle counts for all device objects which belong to this filter have
	  gone to zero.
	// 当发出卸载一个驱动请求,IO系统将缓冲那个信息且不真正调用这个例程直到下面状态发生:
		- 所有属于这个过滤的设备对象在他们各自附着链的顶部
		- 所有设备对象的句柄计数已经成为0


	WARNING: Microsoft does not officially support the unloading of File
			 System Filter Drivers.  This is an example of how to unload
			 your driver if you would like to use it during development.
			 This should not be made available in production code.

Arguments:

	DriverObject - Driver object for this module

Return Value:

	None.

--*/
{
	PSFILTER_DEVICE_EXTENSION DevExt;
	PFAST_IO_DISPATCH FastIoDispatch;
	NTSTATUS Status;
	ULONG NumDevices;
	ULONG i;
	LARGE_INTEGER Interval;
#	define DEVOBJ_LIST_SIZE 64
	PDEVICE_OBJECT DevList[DEVOBJ_LIST_SIZE];

	ASSERT(DriverObject == gSFilterDriverObject);

	// 
	// Log we are unloading
	// 我们卸载时做日志
	// 
	SF_LOG_PRINT(SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
				  ("SFilter!DriverUnload:						Unloading driver (%p)\n",
					DriverObject));

	// 
	// Don't get anymore file system change notifications
	// 不得到任何文件系统改变通知
	// 
	IoUnregisterFsRegistrationChange(DriverObject, SfFsNotification);

	// 
	// This is the loop that will go through all of the devices we are attached
	// to and detach from them.  Since we don't know how many there are and
	// we don't want to allocate memory (because we can't return an error)
	// we will free them in chunks using a local array on the stack.
	// 这是遍历我们附着到的所有设备且断开他们的循环。因为我们不知道有多少且
	// 我们不想分配内存(因为我们不能返回错误)。
	// 我们将使用堆栈上的本地数组按块释放他们
	// 
	for (;;)
	{
		// 
		// Get what device objects we can for this driver.  Quit if there
		// are not any more.  Note that this routine should always be
		// defined since this routine is only compiled for Windows XP and
		// later.
		// 为这个驱动得到设备对象。如果没有了,就退出。注意这个例程应该被定义
		// 因为这个例程仅为Windows XP及以后的OS编译。
		// 

		ASSERT(NULL != gSfDynamicFunctions.EnumerateDeviceObjectList);
		Status = (gSfDynamicFunctions.EnumerateDeviceObjectList)(
			DriverObject,
			DevList,
			sizeof(DevList),
			&NumDevices
			);

		if (NumDevices <= 0)
			break;

		NumDevices = min(NumDevices, DEVOBJ_LIST_SIZE);

		// 
		// First go through the list and detach each of the devices.
		// Our control device object does not have a DeviceExtension and
		// is not attached to anything so don't detach it.
		// 首先遍历列表且断开每个设备。我们的控制设备对象没有DeviceExtension
		// 且未附着到任何事情,因此不断开它。
		// 
		for (i=0; i < NumDevices; i++)
		{
			DevExt = DevList[i]->DeviceExtension;
			if (NULL != DevExt)
				IoDetachDevice(DevExt->AttachedToDeviceObject);
		}

		// 
		// The IO Manager does not currently add a reference count to a device
		// object for each outstanding IRP.  This means there is no way to
		// know if there are any outstanding IRPs on the given device.
		// We are going to wait for a reasonable amount of time for pending
		// irps to complete. 
		// IO Manager当前不为每个未处理的IRPs增加设备对象的引用计数。这意味着无法知道
		// 给定设备是否存在未处理的IRPs.我们将等待合理的时间完成这些IRPs。
		// 象opLocks和目录改变通知的重负荷系统,可能发生问题
		// 
		// WARNING: This does not work 100% of the time and the driver may be
		//		 unloaded before all IRPs are completed.  This can easily
		//		 occur under stress situations and if a long lived IRP is
		//		 pending (like oplocks and directory change notifications).
		//		 The system will fault when this Irp actually completes.
		//		 This is a sample of how to do this during testing.  This
		//		 is not recommended for production code.
		// 
		Interval.QuadPart = (5 * DELAY_ONE_SECOND);	  // delay 5 seconds
		KeDelayExecutionThread(KernelMode, FALSE, &Interval);

		// 
		// Now go back through the list and delete the device objects.
		// 现在回到且遍历列表且删除设备对象
		// 
		for (i=0; i < NumDevices; i++)
		{
			// 
			// See if this is our control device object.  If not then cleanup
			// the device extension.  If so then clear the global pointer
			// that references it.
			// 看是否我们的控制设备对象。如果不是那么清除设备扩展。如果是清除引用它的全局指针。
			// 
			if (NULL != DevList[i]->DeviceExtension)
				SfCleanupMountedDevice(DevList[i]);
			else
			{
				ASSERT(DevList[i] == gSFilterControlDeviceObject);
				gSFilterControlDeviceObject = NULL;
			}

			// 
			// Delete the device object, remove reference counts added by
			// IoEnumerateDeviceObjectList.  Note that the delete does
			// not actually occur until the reference count goes to zero.
			// 删除设备对象,删除由IoEnumerateDeviceObjectList增加的引用计数。
			// 注意删除直到引用计数降到0时才真正发生
			// 
			IoDeleteDevice(DevList[i]);
			ObDereferenceObject(DevList[i]);
		}
	}

	// 
	// Free our FastIO table
	// 释放我们的FastIO表
	// 
	FastIoDispatch = DriverObject->FastIoDispatch;
	DriverObject->FastIoDispatch = NULL;
	ExFreePool(FastIoDispatch);

	ExDeletePagedLookasideList(&gFsCtxLookAsideList);
	ExDeletePagedLookasideList(&gFileNameLookAsideList);
	ExDeleteNPagedLookasideList(&gReadWriteCompletionCtxLookAsideList);

	ZwClose(gRuleFileHandle);
	ExDeleteResourceLite(&gRulesResource);
	if (gRules)
		ExFreePoolWithTag(gRules, SFLT_POOL_TAG);
}
#endif

#if WINVER >= 0x0501
VOID
SfLoadDynamicFunctions (
	)
/*++

Routine Description:

	// 试图载入不是所有操作系统都支持的例程的函数指针。
	// 这些函数指针然后被存储于全局结构SpyDynamicFunctions中
	This routine tries to load the function pointers for the routines that
	are not supported on all versions of the OS.  These function pointers are
	then stored in the global structure SpyDynamicFunctions.

	This support allows for one driver to be built that will run on all 
	versions of the OS Windows 2000 and greater.  Note that on Windows 2000, 
	the functionality may be limited.
	
Arguments:

	None.
	
Return Value:

	None.

--*/
{
	UNICODE_STRING FunctionName;

	RtlZeroMemory(&gSfDynamicFunctions, sizeof(gSfDynamicFunctions));

	// 
	// For each routine that we would want to use, lookup its address in the
	// kernel or hal.  If it is not present, that field in our global
	// SpyDynamicFunctions structure will be set to NULL.
	// 对于每个我们想使用的例程,在kernel或HAL中查找他的地址。
	// 如果不存在,在我们的SpyDynamicFunctions结构中的那个字段将被设置为NULL。
	// 

	RtlInitUnicodeString(&FunctionName, L"FsRtlRegisterFileSystemFilterCallbacks");
	gSfDynamicFunctions.RegisterFileSystemFilterCallbacks = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoAttachDeviceToDeviceStackSafe");
	gSfDynamicFunctions.AttachDeviceToDeviceStackSafe = MmGetSystemRoutineAddress(&FunctionName);
	
	RtlInitUnicodeString(&FunctionName, L"IoEnumerateDeviceObjectList");
	gSfDynamicFunctions.EnumerateDeviceObjectList = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetLowerDeviceObject");
	gSfDynamicFunctions.GetLowerDeviceObject = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetDeviceAttachmentBaseRef");
	gSfDynamicFunctions.GetDeviceAttachmentBaseRef = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetDiskDeviceObject");
	gSfDynamicFunctions.GetDiskDeviceObject = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"IoGetAttachedDeviceReference");
	gSfDynamicFunctions.GetAttachedDeviceReference = MmGetSystemRoutineAddress(&FunctionName);

	RtlInitUnicodeString(&FunctionName, L"RtlGetVersion");
	gSfDynamicFunctions.GetVersion = MmGetSystemRoutineAddress(&FunctionName);
}

VOID
SfGetCurrentVersion (
	)
/*++

Routine Description:
  
    // 基于可用的正确的例程读当前的OS版本
	This routine reads the current OS version using the correct routine based
	on what routine is available.

Arguments:

	None.
	
Return Value:

	None.

--*/
{
	if (NULL != gSfDynamicFunctions.GetVersion)
	{
		RTL_OSVERSIONINFOW VersionInfo;
		NTSTATUS Status;

		// 
		// VERSION NOTE: RtlGetVersion does a bit more than we need, but
		// we are using it if it is available to show how to use it.  It
		// is available on Windows XP and later.  RtlGetVersion and
		// RtlVerifyVersionInfo (both documented in the IFS Kit docs) allow
		// you to make correct choices when you need to change logic based
		// on the current OS executing your code.
		//  RtlGetVersion执行多于我们需要的事情,但如果可用我们使用它以显示如何使用它。
		//  RtlGetVersion和RtlVerifyVersionInfo允许我们当基于当前OS执行你的代码时执行正确的选择
		// 
		VersionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);

		Status = (gSfDynamicFunctions.GetVersion)(&VersionInfo);

		ASSERT(NT_SUCCESS(Status));

		gSfOsMajorVersion = VersionInfo.dwMajorVersion;
		gSfOsMinorVersion = VersionInfo.dwMinorVersion;
		
	}
	else
	{
		PsGetVersion(&gSfOsMajorVersion,
			&gSfOsMinorVersion,
			NULL,
			NULL
			);
	}
}
#endif

VOID
SfFsNotification(
	IN PDEVICE_OBJECT DeviceObject,
	IN BOOLEAN FsActive
	)
/*++

Routine Description:

	// 当一个文件系统或者被登记或者取消登记自己作为一个活动文件系统时被调用
	This routine is invoked whenever a file system has either registered or
	unregistered itself as an active file system.

	For the former case, this routine creates a device object and attaches it
	to the specified file system's device object.  This allows this driver
	to filter all requests to that file system.  Specifically we are looking
	for MOUNT requests so we can attach to newly mounted volumes.
	// 对于前者,这个历程创建一个设备对象且附着它到指定文件系统的设备对象。
	// 这允许这个驱动过滤到那个文件系统的所有请求。尤其是我们查找MOUNT请求,
	// 因而我们可以附着到新安装的卷上

	For the latter case, this file system's device object is located,
	detached, and deleted.  This removes this file system as a filter for
	the specified file system.
	// 对于后者,这个文件系统的设备对象被定位,断开且删除。
	// 这删除这个文件系统作为特定文件系统的过滤器

Arguments:

	// 文件系统设备对象的指针
	DeviceObject - Pointer to the file system's device object.

	// 布尔值指示是否文件系统已经登记(TRUE)或者取消登记(FALSE)自己作为一个活动的文件系统
	FsActive - Boolean indicating whether the file system has registered
		(TRUE) or unregistered (FALSE) itself as an active file system.

Return Value:

	None.

--*/
{
	UNICODE_STRING Name;
	WCHAR NameBuffer[MAX_DEVNAME_LENGTH];

	PAGED_CODE();

	// 
	// Init local Name buffer
	// 
	RtlInitEmptyUnicodeString(&Name, NameBuffer, sizeof(NameBuffer));

	SfGetObjectName(DeviceObject, &Name);

	// 
	// Display the names of all the file system we are notified of
	// 显示我们被通知的所有文件系统的名字
	// 
	SF_LOG_PRINT(SFDEBUG_DISPLAY_ATTACHMENT_NAMES,
		("SFilter!SfFsNotification:					%s	%p \"%wZ\" (%s)\n",
		(FsActive) ? "Activating file system  " : "Deactivating file system",
		DeviceObject,
		&Name,
		GET_DEVICE_TYPE_NAME(DeviceObject->DeviceType))
		);

	// 
	// Handle attaching/detaching from the given file system.
	// 处理附着/断开给定文件系统
	// 
	if (FsActive)
		SfAttachToFileSystemDevice(DeviceObject, &Name);
	else
		SfDetachFromFileSystemDevice(DeviceObject);
}


// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /
// 
//				IRP Handling Routines
// 
// // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // // /


NTSTATUS
SfPassThrough(
	IN PDEVICE_OBJECT DeviceObject,
	IN PIRP Irp
	)
/*++

Routine Description:

	This routine is the main dispatch routine for the general purpose file
	system driver.  It simply passes requests onto the next driver in the
	stack, which is presumably a disk file system.

Arguments:

	DeviceObject - Pointer to the device object for this driver.

	Irp - Pointer to the request packet representing the I/O request.

Return Value:

	The function value is the status of the operation.

Note:

	A note to file system filter implementers:  
		This routine actually "passes" through the request by taking this
		driver out of the IRP stack.  If the driver would like to pass the
		I/O request through, but then also see the result, then rather than
		taking itself out of the loop it could keep itself in by copying the
		caller's parameters to the next stack location and then set its own
		completion routine.  
		这个例程通过将这个驱动取出IRP堆栈而真正

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -