|
MiniFilter 微过滤驱动是相对于SFilter传统过滤驱动而言的,传统文件过滤驱动相对来说较为复杂,且接口不清晰并不符合快速开发的需求,为了解决复杂的开发问题,微过滤驱动就此诞生,微过滤驱动在编写时更简单,多数IRP操作都由过滤管理器(FilterManager或Fltmgr)所接管,因为有了兼容层,所以在开发中不需要考虑底层IRP如何派发,更无需要考虑兼容性问题,用户只需要编写对应的回调函数处理请求即可,这极大的提高了文件过滤驱动的开发效率。
|
一、过滤驱动程序
|
右击项目->属性->配置属性->链接器->输入->附加依赖项->添加fltMgr.lib。 |
// MiniFilter.h
#pragma once
#include <fltKernel.h>
#include <ntifs.h>
#define TC_APP_NAME "KmdfTest"
#define LOG(format,...) \
DbgPrint("[%s] - %s %d: " format "\n", TC_APP_NAME, __FUNCTION__, __LINE__, ##__VA_ARGS__)
#define DRIVER_MEM_TAG 'T1T4'
typedef enum {
PACKET_NONE,
PACKET_ADD_PATH, // 添加路径
PACKET_DEL_PATH, // 移除路径
PACKET_SET_PATH, // 设置路径
PACKET_CLE_PATH // 清空路径
} PACKET_TYPE;
typedef enum {
FLT_PATH_TYPE_READONLY, // 只读保护 - 防止创建/修改/删除
FLT_PATH_TYPE_DELPROTECT, // 删除保护 - 防止删除
} FLT_PATH_TYPE;
typedef struct {
PACKET_TYPE Type;
wchar_t Path[260];
FLT_PATH_TYPE PathType;
} DATA_PACKET;
typedef struct _FLT_RULE {
LIST_ENTRY List;
wchar_t Path[260];
FLT_PATH_TYPE PathType;
} FLT_RULE, * PFLT_RULE;
typedef struct _FLT_RULE_LIST {
LIST_ENTRY HeadList;
KSPIN_LOCK SpinLock;
PFLT_RULE FltRule;
} FLT_RULE_LIST, * PFLT_RULE_LIST;
extern PFLT_FILTER gFilterHandle;
extern PFLT_PORT gFilterServerPort;
extern CONST FLT_REGISTRATION FilterRegistration;
NTSTATUS ConnectionNotify(
PFLT_PORT ClientPort,
PVOID ServerPortCookie,
PVOID ConnectionContext,
ULONG SizeOfContext,
PVOID* ConnectionPortCookie);
NTSTATUS DisconnectionNotify(
PVOID ConnectionContext);
NTSTATUS MessageNotify(
PVOID PortCookie,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnOutputBufferLength);
// Minifilter.c
#include "Minifilter.h"
PFLT_FILTER gFilterHandle = NULL;
PFLT_PORT gFilterServerPort = NULL;
void InitRuleList(PFLT_RULE_LIST Self)
{
InitializeListHead(&Self->HeadList);
KeInitializeSpinLock(&Self->SpinLock);
}
PFLT_RULE_LIST GetRuleListInstance()
{
static PFLT_RULE_LIST pRuleList = NULL;
if (!pRuleList) {
pRuleList = ExAllocatePoolWithTag(NonPagedPool, sizeof(FLT_RULE_LIST), DRIVER_MEM_TAG);
InitRuleList(pRuleList);
}
return pRuleList;
}
void ReviewRuleList()
{
PFLT_RULE_LIST Self = GetRuleListInstance();
PLIST_ENTRY pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = CONTAINING_RECORD(pList, FLT_RULE, List);
LOG("#Rule - Path: %ws, Type: %d", pRule->Path, pRule->PathType);
pList = pList->Flink;
}
}
BOOLEAN IsRuleExistFromList(PFLT_RULE_LIST Self, const wchar_t* FilePath, PFLT_RULE* Rule, BOOLEAN Contain)
{
PLIST_ENTRY pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = CONTAINING_RECORD(pList, FLT_RULE, List);
if (Contain) {
if (wcsstr(FilePath, pRule->Path) != NULL) {
*Rule = pRule;
return TRUE;
}
} else {
if (wcscmp(FilePath, pRule->Path) == 0) {
*Rule = pRule;
return TRUE;
}
}
pList = pList->Flink;
}
return FALSE;
}
void AddRuleToList(PFLT_RULE_LIST Self, PFLT_RULE Rule)
{
PFLT_RULE pRule = NULL;
PFLT_RULE pRuleMem = NULL;
KIRQL kIrql;
if (!Self || !Rule) {
LOG("Parameter invalid.");
return;
}
if (IsRuleExistFromList(Self, Rule->Path, &pRule, FALSE)) {
LOG("Path already exists.");
return;
}
pRuleMem = (PFLT_RULE)ExAllocatePoolWithTag(NonPagedPool, sizeof(FLT_RULE), DRIVER_MEM_TAG);
memset(pRuleMem, 0, sizeof(pRuleMem));
memcpy(pRuleMem->Path, Rule->Path, sizeof(pRuleMem->Path));
pRuleMem->PathType = Rule->PathType;
KeAcquireSpinLock(&Self->SpinLock, &kIrql);
InsertTailList(&Self->HeadList, &pRuleMem->List);
KeReleaseSpinLock(&Self->SpinLock, kIrql);
}
void DeleteRuleFromList(PFLT_RULE_LIST Self, const wchar_t* Path)
{
PLIST_ENTRY pList = NULL;
if (!Self || !Path) {
LOG("Parameter invalid.");
return;
}
pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = (PFLT_RULE)CONTAINING_RECORD(pList, FLT_RULE, List);
if (wcscmp(pRule->Path, Path) == 0) {
KIRQL kIrql;
KeAcquireSpinLock(&Self->SpinLock, &kIrql);
RemoveEntryList(&pRule->List);
KeReleaseSpinLock(&Self->SpinLock, kIrql);
ExFreePoolWithTag(pRule, DRIVER_MEM_TAG);
break;
}
pList = pList->Flink;
}
}
void SetRuleFromList(PFLT_RULE_LIST Self, const wchar_t* Path, PFLT_RULE Rule)
{
PLIST_ENTRY pList = NULL;
if (!Self || !Path || !Rule) {
LOG("Parameter invalid.");
return;
}
pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = (PFLT_RULE)CONTAINING_RECORD(pList, FLT_RULE, List);
if (wcscmp(pRule->Path, Path) == 0) {
KIRQL kIrql;
KeAcquireSpinLock(&Self->SpinLock, &kIrql);
// 直接更新链表项中的字段
wcsncpy(pRule->Path, Rule->Path, ARRAYSIZE(pRule->Path) - 1);
pRule->PathType = Rule->PathType;
KeReleaseSpinLock(&Self->SpinLock, kIrql);
return;
}
pList = pList->Flink;
}
// 如果未存在链表则添加规则
AddRuleToList(Self, Rule);
}
void CleRuleFromList(PFLT_RULE_LIST Self, FLT_PATH_TYPE PathType)
{
PLIST_ENTRY pList = NULL;
if (!Self || PathType < 0) {
LOG("Parameter invalid.");
return;
}
pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = (PFLT_RULE)CONTAINING_RECORD(pList, FLT_RULE, List);
pList = pList->Flink;
if (pRule->PathType == PathType) {
KIRQL kIrql;
KeAcquireSpinLock(&Self->SpinLock, &kIrql);
RemoveEntryList(&pRule->List);
KeReleaseSpinLock(&Self->SpinLock, kIrql);
ExFreePoolWithTag(pRule, DRIVER_MEM_TAG);
}
}
}
void CleanAllRule(PFLT_RULE_LIST Self)
{
PLIST_ENTRY pList = NULL;
if (!Self) {
return;
}
pList = Self->HeadList.Flink;
while (pList != &Self->HeadList) {
PFLT_RULE pRule = NULL;
KIRQL kIrql;
pRule = (PFLT_RULE)CONTAINING_RECORD(pList, FLT_RULE, List);
pList = pList->Flink;
KeAcquireSpinLock(&Self->SpinLock, &kIrql);
RemoveEntryList(&pRule->List);
KeReleaseSpinLock(&Self->SpinLock, kIrql);
ExFreePoolWithTag(pRule, DRIVER_MEM_TAG);
}
}
FLT_PREOP_CALLBACK_STATUS PreOperation(
PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID* CompletionContext)
{
PFLT_FILE_NAME_INFORMATION lpNameInfo = NULL;
NTSTATUS status;
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
// 获取路径信息
status = FltGetFileNameInformation(Data, FLT_FILE_NAME_NORMALIZED | FLT_FILE_NAME_QUERY_DEFAULT, &lpNameInfo);
if (NT_SUCCESS(status)) {
// 获取目标路径
UNICODE_STRING targetPath = lpNameInfo->Name;
// 链表匹配
PFLT_RULE rule;
if (IsRuleExistFromList(GetRuleListInstance(), targetPath.Buffer, &rule, TRUE)) {
UCHAR MajorFunction = Data->Iopb->MajorFunction;
if (rule->PathType == FLT_PATH_TYPE_READONLY) {
// -----------------------------------目录只读保护
LOG("RULE-READONLY: %wZ", &lpNameInfo->Name);
LOG("-----------Create.Options: 0x%08X", Data->Iopb->Parameters.Create.Options);
if (IRP_MJ_CREATE == MajorFunction) {
// 防止文件/文件夹创建
if ((Data->Iopb->Parameters.Create.Options & (FILE_WRITE_THROUGH | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_DIRECTORY_FILE))) {
LOG("-----FILE_WRITE_THROUGH | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_DIRECTORY_FILE\n");
// 允许拷出
if (!(Data->Iopb->Parameters.Create.Options & (FO_DISALLOW_EXCLUSIVE)) &&
(Data->Iopb->Parameters.Create.Options & (FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY))) {
LOG("-----FILE_NON_DIRECTORY_FILE | FILE_SEQUENTIAL_ONLY\n");
return FLT_PREOP_SUCCESS_WITH_CALLBACK;
}
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
// 防止文件/文件夹删除
if ((Data->Iopb->Parameters.Create.Options & (FILE_DELETE_ON_CLOSE))) {
LOG("-----FILE_DELETE_ON_CLOSE\n");
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
} else if (IRP_MJ_WRITE == MajorFunction) {
// 拒绝写操作
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
} else if (IRP_MJ_SET_INFORMATION == MajorFunction) {
// 拒绝修改操作
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
} else if (rule->PathType == FLT_PATH_TYPE_DELPROTECT) {
// -----------------------------------目录删除保护
LOG("RULE-DELPROTECT: %wZ", &lpNameInfo->Name);
if (IRP_MJ_CREATE == MajorFunction) {
if ((Data->Iopb->Parameters.Create.Options & (FILE_DELETE_ON_CLOSE))) {
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
} else if (IRP_MJ_SET_INFORMATION == MajorFunction) {
if (Data->Iopb->Parameters.SetFileInformation.FileInformationClass
== FileDispositionInformation) {
Data->IoStatus.Information = 0;
Data->IoStatus.Status = STATUS_ACCESS_DENIED;
return FLT_PREOP_COMPLETE;
}
}
}
}
}
//return FLT_PREOP_SUCCESS_NO_CALLBACK; // 无后续处理
return FLT_PREOP_SUCCESS_WITH_CALLBACK; // 允许后续处理
}
FLT_POSTOP_CALLBACK_STATUS PostOperation(
PFLT_CALLBACK_DATA Data,
PCFLT_RELATED_OBJECTS FltObjects,
PVOID CompletionContext,
FLT_POST_OPERATION_FLAGS Flags)
{
UNREFERENCED_PARAMETER(Data);
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(CompletionContext);
UNREFERENCED_PARAMETER(Flags);
return FLT_POSTOP_FINISHED_PROCESSING;
}
NTSTATUS InstanceUnload(
FLT_FILTER_UNLOAD_FLAGS Flags)
{
UNREFERENCED_PARAMETER(Flags);
LOG("Uninstall MiniFilter.");
CleanAllRule(GetRuleListInstance());
FltCloseCommunicationPort(gFilterServerPort);
FltUnregisterFilter(gFilterHandle);
return STATUS_SUCCESS;
}
NTSTATUS InstanceSetup(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_SETUP_FLAGS Flags,
DEVICE_TYPE VolumeDeviceType,
FLT_FILESYSTEM_TYPE VolumeFilesystemType)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
UNREFERENCED_PARAMETER(VolumeDeviceType);
UNREFERENCED_PARAMETER(VolumeFilesystemType);
LOG("Install MiniFilter.");
return STATUS_SUCCESS;
}
NTSTATUS InstanceQueryTeardown(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
LOG("Destroy MiniFilter.");
return STATUS_SUCCESS;
}
VOID InstanceTeardownStart(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_TEARDOWN_FLAGS Flags)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
LOG("Unbundle MiniFilter.");
}
VOID InstanceTeardownComplete(
PCFLT_RELATED_OBJECTS FltObjects,
FLT_INSTANCE_TEARDOWN_FLAGS Flags)
{
UNREFERENCED_PARAMETER(FltObjects);
UNREFERENCED_PARAMETER(Flags);
LOG("Unbundle finish MiniFilter.");
}
// 回调函数集
CONST FLT_OPERATION_REGISTRATION Callbacks[] = {
// 创建时触发 PreOperation(之前回调函数) / PostOperation(之后回调函数)
{ IRP_MJ_CREATE, 0, PreOperation, PostOperation },
// 写入触发
{ IRP_MJ_WRITE, 0, PreOperation, PostOperation },
// 设置时触发
{ IRP_MJ_SET_INFORMATION, 0, PreOperation, PostOperation },
// 结束标志
{ IRP_MJ_OPERATION_END }
};
// 过滤驱动数据结构
CONST FLT_REGISTRATION FilterRegistration = {
sizeof(FLT_REGISTRATION), // 结构大小(默认)
FLT_REGISTRATION_VERSION, // 结构版本(默认)
0, // 过滤器标志
NULL, // 上下文
Callbacks, // 注册回调函数集
InstanceUnload, // 驱动卸载函数
InstanceSetup, // 实例安装回调函数
InstanceQueryTeardown, // 实例销毁回调函数
InstanceTeardownStart, // 实例解除绑定时触发
InstanceTeardownComplete, // 实例解绑完成时触发
NULL, // GenerateFileName
NULL, // GenerateDestinationFileName
NULL // NormalizeNameComponent
};
NTSTATUS ConnectionNotify(
PFLT_PORT ClientPort,
PVOID ServerPortCookie,
PVOID ConnectionContext,
ULONG SizeOfContext,
PVOID* ConnectionPortCookie)
{
UNREFERENCED_PARAMETER(ClientPort);
UNREFERENCED_PARAMETER(ServerPortCookie);
UNREFERENCED_PARAMETER(ConnectionContext);
UNREFERENCED_PARAMETER(SizeOfContext);
UNREFERENCED_PARAMETER(ConnectionPortCookie);
LOG("Client connected.");
return STATUS_SUCCESS;
}
NTSTATUS DisconnectionNotify(
PVOID ConnectionContext)
{
UNREFERENCED_PARAMETER(ConnectionContext);
LOG("Client disconnected.");
return STATUS_SUCCESS;
}
NTSTATUS MessageNotify(
PVOID PortCookie,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnOutputBufferLength)
{
NTSTATUS status = STATUS_SUCCESS;
DATA_PACKET* packet = NULL;
FLT_RULE_LIST* ruleList = NULL;
UNREFERENCED_PARAMETER(PortCookie);
UNREFERENCED_PARAMETER(OutputBuffer);
UNREFERENCED_PARAMETER(OutputBufferLength);
UNREFERENCED_PARAMETER(ReturnOutputBufferLength);
if (InputBuffer == NULL || InputBufferLength == 0 || InputBufferLength != sizeof(DATA_PACKET)) {
return STATUS_INVALID_PARAMETER;
}
packet = (DATA_PACKET*)InputBuffer;
ruleList = GetRuleListInstance();
switch (packet->Type) {
case PACKET_ADD_PATH: {
FLT_RULE rule;
memset(rule.Path, 0, sizeof(rule.Path));
memcpy(rule.Path, packet->Path, sizeof(rule.Path));
rule.PathType = packet->PathType;
LOG("PACKET_ADD_PATH - %ws, %d", rule.Path, rule.PathType);
AddRuleToList(ruleList, &rule);
ReviewRuleList();
} break;
case PACKET_DEL_PATH: {
LOG("PACKET_DEL_PATH - %ws", packet->Path);
DeleteRuleFromList(ruleList, packet->Path);
ReviewRuleList();
} break;
case PACKET_SET_PATH: {
FLT_RULE rule;
memset(rule.Path, 0, sizeof(rule.Path));
memcpy(rule.Path, packet->Path, sizeof(rule.Path));
rule.PathType = packet->PathType;
LOG("PACKET_SET_PATH - %ws, %d", rule.Path, rule.PathType);
SetRuleFromList(ruleList, packet->Path, &rule);
ReviewRuleList();
} break;
case PACKET_CLE_PATH: {
FLT_PATH_TYPE PathType;
PathType = packet->PathType;
LOG("PACKET_CLE_PATH - %d", PathType);
CleRuleFromList(ruleList, PathType);
ReviewRuleList();
} break;
default: {
status = STATUS_INVALID_PARAMETER;
} break;
}
return status;
}
// Driver.c
#include "Minifilter.h"
#include <ntstrsafe.h>
// 驱动版本号
#define VERSION_STRING "1.0.0"
// 驱动信息
#define NT_ROOT_PREFIX L"\\Device\\KmdfTest"
#define DOS_ROOT_PREFIX L"\\DosDevices\\KmdfTest"
// 通信端口
#define MINIFILTER_PORT L"\\KmdfTestPort"
// 驱动控制码
#define TC_IOCTL_GET_DRIVER_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
// 设备对象全局指针
PDEVICE_OBJECT RootDeviceObject = NULL;
// IRP完成处理
NTSTATUS CompleteIrp(PIRP irp, NTSTATUS status, ULONG_PTR information)
{
irp->IoStatus.Status = status;
irp->IoStatus.Information = information;
// 调用方已完成所有I/O请求处理操作 并且不增加优先级
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}
// IOCTL回调处理
NTSTATUS ProcessDeviceControlIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpSp;
UNREFERENCED_PARAMETER(DeviceObject);
irpSp = IoGetCurrentIrpStackLocation(Irp);
switch (irpSp->Parameters.DeviceIoControl.IoControlCode) {
case TC_IOCTL_GET_DRIVER_VERSION: {
size_t versionLength;
LOG("TC_IOCTL_GET_DRIVER_VERSION.");
versionLength = strlen(VERSION_STRING) + 1;
memcpy(Irp->AssociatedIrp.SystemBuffer, VERSION_STRING, versionLength);
Irp->IoStatus.Information = versionLength;
Irp->IoStatus.Status = STATUS_SUCCESS;
} break;
default: {
return CompleteIrp(Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
}
}
return CompleteIrp(Irp, Irp->IoStatus.Status, Irp->IoStatus.Information);
}
// IRP回调处理 - 所有设备在这里分发请求
NTSTATUS IRP_CALL(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PIO_STACK_LOCATION irpStackL;
UNREFERENCED_PARAMETER(DeviceObject);
// 获取应用层参数传递
irpStackL = IoGetCurrentIrpStackLocation(Irp);
switch (irpStackL->MajorFunction) {
case IRP_MJ_CLOSE:
case IRP_MJ_CREATE: {
return CompleteIrp(Irp, STATUS_SUCCESS, 0);
} break;
case IRP_MJ_DEVICE_CONTROL: {
NTSTATUS status = ProcessDeviceControlIrp(DeviceObject, Irp);
return status;
} break;
}
return CompleteIrp(Irp, STATUS_INVALID_DEVICE_REQUEST, 0);
}
// 设备删除函数
void DeleteDeviceObject(PDEVICE_OBJECT DeviceObject)
{
UNICODE_STRING Win32NameString;
NTSTATUS ntStatus;
LOG("DeleteDeviceObject BEGIN.");
// 删除符号链接
RtlInitUnicodeString(&Win32NameString, (LPWSTR)DOS_ROOT_PREFIX);
ntStatus = IoDeleteSymbolicLink(&Win32NameString);
if (!NT_SUCCESS(ntStatus))
LOG("IoDeleteSymbolicLink failed ntStatus = 0x%08x.", ntStatus);
// 删除设备
RootDeviceObject = NULL;
IoDeleteDevice(DeviceObject);
LOG("DeleteDeviceObject END.");
}
// 设备创建函数
NTSTATUS CreateRootDeviceObject(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING Win32NameString, ntUnicodeString;
WCHAR dosname[32], ntname[32];
PDEVICE_OBJECT DeviceObject;
NTSTATUS ntStatus;
RtlStringCbCopyW(dosname, sizeof(dosname), (LPWSTR)DOS_ROOT_PREFIX);
RtlStringCbCopyW(ntname, sizeof(ntname), (LPWSTR)NT_ROOT_PREFIX);
RtlInitUnicodeString(&ntUnicodeString, ntname);
RtlInitUnicodeString(&Win32NameString, dosname);
LOG("Creating root device nt=%ls dos=%ls.", ntname, dosname);
// 创建设备对象
ntStatus = IoCreateDevice(
DriverObject, // 驱动对象
sizeof(int), // 状态信息大小
&ntUnicodeString, // 设备名称 - 必须是"\Device\[设备名]"
FILE_DEVICE_UNKNOWN, // 设备类型 - 常用设备之外类型
FILE_DEVICE_SECURE_OPEN, // 设备描述
FALSE, // 独占设备
&DeviceObject // 返回ptr到设备对象
);
if (!NT_SUCCESS(ntStatus)) {
LOG("TCCreateRootDeviceObject NTSTATUS = 0x%08x END.", ntStatus);
return ntStatus;
}
// 使用直接IO(禁用缓冲区)
DeviceObject->Flags |= DO_DIRECT_IO;
// 4字节对齐
DeviceObject->AlignmentRequirement = FILE_WORD_ALIGNMENT;
// 创建符号链接,允许用户模式程序通过 \\.\Devicename 访问设备
ntStatus = IoCreateSymbolicLink(&Win32NameString, &ntUnicodeString);
if (!NT_SUCCESS(ntStatus)) {
LOG("TCCreateRootDeviceObject NTSTATUS = 0x%08x END.", ntStatus);
IoDeleteDevice(DeviceObject);
return ntStatus;
}
// 注册关机通知,使设备能够在系统关机或重启时执行某些清理操作
IoRegisterShutdownNotification(DeviceObject);
// 获取设备对象指针
RootDeviceObject = DeviceObject;
return STATUS_SUCCESS;
}
// 驱动卸载函数
void DriverUnload(PDRIVER_OBJECT DriverObject)
{
LOG("DriverUnload BEGIN DriverObject=%p.", DriverObject);
// 资源释放
DeleteDeviceObject(RootDeviceObject);
LOG("DriverUnload END");
}
// 驱动入口函数
NTSTATUS
DriverEntry(
PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath
)
{
NTSTATUS status;
PSECURITY_DESCRIPTOR pSD = NULL;
OBJECT_ATTRIBUTES objAttri = { 0 };
UNICODE_STRING uniPortName = { 0 };
LOG("Version %s.", VERSION_STRING);
LOG("RegistryPath=%ws.", RegistryPath->Buffer);
// 注册卸载回调函数
DriverObject->DriverUnload = DriverUnload;
// 注册IRP处理函数
DriverObject->MajorFunction[IRP_MJ_CREATE] = IRP_CALL;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = IRP_CALL;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IRP_CALL;
// 向过滤管理器注册过滤器
status = FltRegisterFilter(DriverObject, &FilterRegistration, &gFilterHandle);
if (!NT_SUCCESS(status)) {
LOG("FltRegisterFilter failed with status: 0x%08x", status);
return status;
}
// 开启过滤
status = FltStartFiltering(gFilterHandle);
if (!NT_SUCCESS(status)) {
FltUnregisterFilter(gFilterHandle);
LOG("FltStartFiltering failed with status: 0x%08x", status);
return status;
}
// 创建通信端口
status = FltBuildDefaultSecurityDescriptor(&pSD, FLT_PORT_ALL_ACCESS);
if (!NT_SUCCESS(status)) {
FltUnregisterFilter(gFilterHandle);
LOG("FltBuildDefaultSecurityDescriptor failed with status: 0x%08x", status);
return status;
}
RtlInitUnicodeString(&uniPortName, MINIFILTER_PORT);
InitializeObjectAttributes(&objAttri, &uniPortName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, pSD);
status = FltCreateCommunicationPort(gFilterHandle, &gFilterServerPort,
&objAttri, NULL, ConnectionNotify, DisconnectionNotify, MessageNotify, 1);
FltFreeSecurityDescriptor(pSD);
if (!NT_SUCCESS(status)) {
FltUnregisterFilter(gFilterHandle);
LOG("FltCreateCommunicationPort failed with status: 0x%08x", status);
return status;
}
// 创建设备
return CreateRootDeviceObject(DriverObject);
}
二、编写应用程序
// driver.h
#pragma once
#include <iostream>
#include <windows.h>
// 驱动信息
#define DRIVER_NAME "KmdfTest"
#define DRIVER_PATH "C:\\Users\\\dxf\\Desktop\\KmdfTest\\Driver\\KmdfTest\\x64\\Debug\\KmdfTest.sys"
// 驱动路径
#define WIN32_ROOT_PREFIX L"\\\\.\\KmdfTest"
// 驱动功能码
#define TC_IOCTL_GET_DRIVER_VERSION CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
class Driver {
public:
Driver();
~Driver();
// 获取驱动版本号
std::string GetDriverVersion();
// 安装驱动
BOOL InstallDriver(const char* lpszDriverName,
const char* lpszDriverPath, const char* lpszAltitude, BOOL isAutoStart);
// 启动驱动
BOOL StartDriver(const char* lpszDriverName);
// 关闭驱动
BOOL StopDriver(const char* lpszDriverName);
// 删除驱动
BOOL DeleteDriver(const char* lpszDriverName);
private:
// 检查驱动是否安装
BOOL IsDriverInstalled(const char* lpszDriverName);
// 检查驱动是否运行
BOOL IsDriverRunning(const char* lpszDriverName);
// 打开驱动
BOOL OpenDriver(const std::wstring& devicePath);
// 驱动句柄
HANDLE hDevice;
};
// dirver.cpp
#include "driver.h"
#include <winsvc.h>
#include <winioctl.h>
Driver::Driver() : hDevice(INVALID_HANDLE_VALUE) {
// 检测驱动是否安装
if (!IsDriverInstalled(DRIVER_NAME)) {
std::cout << "The driver is not installed. install the driver..." << std::endl;
if (!Driver::InstallDriver(DRIVER_NAME, DRIVER_PATH, "225864", FALSE)) {
std::cerr << "Driver install failed!" << std::endl;
//std::exit(-1);
}
std::cout << "Driver install ok." << std::endl;
}
// 检测驱动是否运行
if (!IsDriverRunning(DRIVER_NAME)) {
std::cout << "The driver is not running, run the driver..." << std::endl;
if (!Driver::StartDriver(DRIVER_NAME)) {
std::cerr << "Driver running failed!" << std::endl;
//std::exit(-1);
}
std::cout << "Driver running ok." << std::endl;
}
// 打开驱动获取句柄
if (!OpenDriver(WIN32_ROOT_PREFIX)) {
std::cerr << "Failed to open device. Error: " << GetLastError() << std::endl;
//std::exit(-1);
}
// 获取驱动版本号
std::string version = GetDriverVersion();
std::cout << "Driver version: " << version << std::endl;
}
Driver::~Driver() {
if(hDevice != INVALID_HANDLE_VALUE)
CloseHandle(hDevice);
}
std::string Driver::GetDriverVersion()
{
char version[16];
DWORD bytesReturned;
if (DeviceIoControl(hDevice, TC_IOCTL_GET_DRIVER_VERSION, nullptr, 0, version, sizeof(version), &bytesReturned, nullptr)) {
return std::string(version, bytesReturned);
} else {
return std::string();
}
}
BOOL Driver::InstallDriver(const char* lpszDriverName,
const char* lpszDriverPath, const char* lpszAltitude, BOOL isAutoStart)
{
char szTempStr[MAX_PATH];
HKEY hKey;
DWORD dwData;
char szDriverImagePath[MAX_PATH];
if (NULL == lpszDriverName || NULL == lpszDriverPath) {
return FALSE;
}
// 得到完整的驱动路径
GetFullPathName(lpszDriverPath, MAX_PATH, szDriverImagePath, NULL);
SC_HANDLE hServiceMgr = NULL; // SCM管理器句柄
SC_HANDLE hService = NULL; // NT驱动程序的服务句柄
// 打开服务控制管理器
hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hServiceMgr == NULL) {
// OpenSCManager失败
CloseServiceHandle(hServiceMgr);
return FALSE;
}
// 创建驱动所对应的服务
int startType = SERVICE_DEMAND_START;
if (isAutoStart) startType = SERVICE_AUTO_START;
else startType = SERVICE_DEMAND_START;
hService = CreateService(hServiceMgr,
lpszDriverName, // 驱动程序的在注册表中的名称
lpszDriverName, // 注册表驱动程序的DisplayName值
SERVICE_ALL_ACCESS, // 加载驱动程序的访问权限
SERVICE_FILE_SYSTEM_DRIVER, // 表示加载的服务是文件系统驱动程序
startType, // 注册表驱动程序的Start值
SERVICE_ERROR_IGNORE, // 注册表驱动程序的ErrorControl值
szDriverImagePath, // 注册表驱动程序的ImagePath值
"FSFilter Activity Monitor", // 注册表驱动程序的Group值
NULL,
"FltMgr", // 注册表驱动程序的DependOnService值
NULL,
NULL);
if (hService == NULL) {
if (GetLastError() == ERROR_SERVICE_EXISTS) {
// 服务创建失败,是由于服务已经创立过
CloseServiceHandle(hService); // 服务句柄
CloseServiceHandle(hServiceMgr); // SCM句柄
return TRUE;
}
else {
CloseServiceHandle(hService); // 服务句柄
CloseServiceHandle(hServiceMgr); // SCM句柄
return FALSE;
}
}
CloseServiceHandle(hService); // 服务句柄
CloseServiceHandle(hServiceMgr); // SCM句柄
// --------------------------------------------------------------------------
// SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instances 子键下的键值项
// --------------------------------------------------------------------------
strcpy(szTempStr, "SYSTEM\\CurrentControlSet\\Services\\");
strcat(szTempStr, lpszDriverName);
strcat(szTempStr, "\\Instances");
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szTempStr, 0, "", TRUE, KEY_ALL_ACCESS, NULL, &hKey, (LPDWORD)&dwData) != ERROR_SUCCESS) {
return FALSE;
}
// 注册表驱动程序的DefaultInstance 值
strcpy(szTempStr, lpszDriverName);
strcat(szTempStr, " Instance");
if (RegSetValueEx(hKey, "DefaultInstance", 0, REG_SZ, (CONST BYTE*)szTempStr, (DWORD)strlen(szTempStr)) != ERROR_SUCCESS) {
return FALSE;
}
// 刷新注册表
RegFlushKey(hKey);
RegCloseKey(hKey);
// --------------------------------------------------------------------------
// SYSTEM\\CurrentControlSet\\Services\\DriverName\\Instances\\DriverName Instance 子键下的键值项
// --------------------------------------------------------------------------
strcpy(szTempStr, "SYSTEM\\CurrentControlSet\\Services\\");
strcat(szTempStr, lpszDriverName);
strcat(szTempStr, "\\Instances\\");
strcat(szTempStr, lpszDriverName);
strcat(szTempStr, " Instance");
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, szTempStr, 0, "", TRUE, KEY_ALL_ACCESS, NULL, &hKey, (LPDWORD)&dwData) != ERROR_SUCCESS) {
return FALSE;
}
// 注册表驱动程序的Altitude值
strcpy(szTempStr, lpszAltitude);
if (RegSetValueEx(hKey, "Altitude", 0, REG_SZ, (CONST BYTE*)szTempStr, (DWORD)strlen(szTempStr)) != ERROR_SUCCESS) {
return FALSE;
}
// 注册表驱动程序的Flags值
dwData = 0x0;
if (RegSetValueEx(hKey, "Flags", 0, REG_DWORD, (CONST BYTE*) & dwData, sizeof(DWORD)) != ERROR_SUCCESS) {
return FALSE;
}
// 刷新注册表
RegFlushKey(hKey);
RegCloseKey(hKey);
return TRUE;
}
BOOL Driver::StartDriver(const char* lpszDriverName)
{
SC_HANDLE schManager;
SC_HANDLE schService;
SERVICE_STATUS svcStatus;
if (NULL == lpszDriverName) {
return FALSE;
}
schManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (NULL == schManager) {
CloseServiceHandle(schManager);
return FALSE;
}
schService = OpenService(schManager, lpszDriverName, SERVICE_ALL_ACCESS);
if (NULL == schService) {
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return FALSE;
}
if (!StartService(schService, 0, NULL)) {
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) {
// 服务已经开启
return TRUE;
}
return FALSE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return TRUE;
}
BOOL Driver::StopDriver(const char* lpszDriverName)
{
SC_HANDLE schManager;
SC_HANDLE schService;
SERVICE_STATUS svcStatus;
bool bStopped = false;
schManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (NULL == schManager) {
return FALSE;
}
schService = OpenService(schManager, lpszDriverName, SERVICE_ALL_ACCESS);
if (NULL == schService) {
CloseServiceHandle(schManager);
return FALSE;
}
if (!ControlService(schService, SERVICE_CONTROL_STOP, &svcStatus) && (svcStatus.dwCurrentState != SERVICE_STOPPED)) {
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return FALSE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return TRUE;
}
BOOL Driver::DeleteDriver(const char* lpszDriverName)
{
SC_HANDLE schManager;
SC_HANDLE schService;
SERVICE_STATUS svcStatus;
schManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (NULL == schManager) {
return FALSE;
}
schService = OpenService(schManager, lpszDriverName, SERVICE_ALL_ACCESS);
if (NULL == schService) {
CloseServiceHandle(schManager);
return FALSE;
}
ControlService(schService, SERVICE_CONTROL_STOP, &svcStatus);
if (!DeleteService(schService)) {
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return FALSE;
}
CloseServiceHandle(schService);
CloseServiceHandle(schManager);
return TRUE;
}
BOOL Driver::IsDriverInstalled(const char* lpszDriverName)
{
SC_HANDLE hServiceMgr = NULL;
SC_HANDLE hService = NULL;
// 打开服务控制管理器
hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hServiceMgr == NULL) {
return FALSE;
}
// 打开驱动程序服务
hService = OpenService(hServiceMgr, lpszDriverName, SERVICE_QUERY_STATUS);
if (hService == NULL) {
// 如果没有找到服务,说明驱动没有安装
CloseServiceHandle(hServiceMgr);
return FALSE;
}
// 如果服务存在,说明驱动已经安装
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
return TRUE;
}
BOOL Driver::IsDriverRunning(const char* lpszDriverName)
{
SC_HANDLE hServiceMgr = NULL; // 服务控制管理器句柄
SC_HANDLE hService = NULL; // 服务句柄
SERVICE_STATUS serviceStatus; // 服务状态结构体
// 打开服务控制管理器
hServiceMgr = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (hServiceMgr == NULL) {
// 打开服务控制管理器失败
return FALSE;
}
// 打开服务,获取服务句柄
hService = OpenService(hServiceMgr, lpszDriverName, SERVICE_QUERY_STATUS);
if (hService == NULL) {
// 如果服务不存在,返回 FALSE
CloseServiceHandle(hServiceMgr);
return FALSE;
}
// 查询服务状态
if (!QueryServiceStatus(hService, &serviceStatus)) {
// 查询服务状态失败
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
return FALSE;
}
// 检查服务的当前状态
if (serviceStatus.dwCurrentState == SERVICE_RUNNING) {
// 如果服务正在运行,返回 TRUE
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
return TRUE;
}
// 如果服务没有在运行,返回 FALSE
CloseServiceHandle(hService);
CloseServiceHandle(hServiceMgr);
return FALSE;
}
BOOL Driver::OpenDriver(const std::wstring& devicePath)
{
// 打开设备
hDevice = CreateFileW(
devicePath.c_str(), // 设备路径,从参数传递
GENERIC_READ | GENERIC_WRITE, // 访问模式
FILE_SHARE_READ | FILE_SHARE_WRITE, // 文件共享模式
NULL, // 安全描述符
OPEN_EXISTING, // 仅打开已存在的设备
0, // 其他标志
NULL // 模板文件句柄
);
// 检查设备是否成功打开
if (hDevice == INVALID_HANDLE_VALUE) {
std::cerr << "Failed to open device. Error: " << GetLastError() << std::endl;
return FALSE;
}
return TRUE;
}
// filter.h
#pragma once
#include <iostream>
#include <Windows.h>
#pragma comment(lib, "FltLib.lib")
// 通信端口名称
#define MINIFILTER_PORT L"\\KmdfTestPort"
typedef enum {
PACKET_NONE,
PACKET_ADD_PATH, // 添加路径
PACKET_DEL_PATH, // 移除路径
PACKET_SET_PATH, // 设置路径
PACKET_CLE_PATH // 清空路径
} PACKET_TYPE;
typedef enum {
FLT_PATH_TYPE_READONLY, // 只读保护 - 防止创建/修改/删除
FLT_PATH_TYPE_DELPROTECT, // 删除保护 - 防止删除
} FLT_PATH_TYPE;
class DataPacket {
public:
DataPacket() : m_type(PACKET_TYPE::PACKET_NONE), m_pathType(FLT_PATH_TYPE::FLT_PATH_TYPE_READONLY) {
memset(m_path, 0, sizeof(m_path));
}
DataPacket(PACKET_TYPE Type, const wchar_t* Path, FLT_PATH_TYPE PathType)
: m_type(Type), m_pathType(PathType) {
if (Path != NULL) {
memset(m_path, 0, sizeof(m_path));
memcpy(m_path, Path, sizeof(m_path));
}
}
PACKET_TYPE getType() {
return m_type;
}
void setType(PACKET_TYPE Type) {
m_type = Type;
}
std::wstring getPath() {
return m_path;
}
void setPath(const std::wstring& Path) {
memset(m_path, 0, sizeof(m_path));
memcpy(m_path, Path.c_str(), Path.size() << 1);
}
FLT_PATH_TYPE getPathType() {
return m_pathType;
}
void setPathType(FLT_PATH_TYPE PathType) {
m_pathType = PathType;
}
private:
PACKET_TYPE m_type;
wchar_t m_path[260];
FLT_PATH_TYPE m_pathType;
};
class MiniFilterCommunication {
public:
MiniFilterCommunication();
~MiniFilterCommunication();
// 设置目录只读保护
BOOL SetDirReadonly(std::string& dirpath, BOOL isReadOnly);
// 清空目录只读保护
BOOL CleDirReadonly();
// 设置目录删除保护
BOOL SetDirDelprotect(std::string& dirpath, BOOL isDelprotect);
// 清空目录删除保护
BOOL CleDirDelprotect();
private:
// 连接Minifilter服务
BOOL Connect(const std::wstring& PortName);
// 发送消息到Minifilter服务
BOOL SendMessageToFlt(PACKET_TYPE Type, const wchar_t* FilePath, FLT_PATH_TYPE PathType);
// 盘符路径转卷路径
std::string DriveLetterToVolumePath(std::string& path);
HANDLE m_hPort = INVALID_HANDLE_VALUE;
};
// filter.cpp
#include "Filter.h"
#include <Windows.h>
#include <fltUser.h>
MiniFilterCommunication::MiniFilterCommunication() {
// 连接驱动通信端口
if (!Connect(MINIFILTER_PORT)) {
std::cerr << "Minifilter connect failed!" << std::endl;
//std::exit(-1);
}
}
MiniFilterCommunication::~MiniFilterCommunication()
{
if (m_hPort != INVALID_HANDLE_VALUE) {
CloseHandle(m_hPort);
}
}
BOOL MiniFilterCommunication::SetDirReadonly(std::string& dirpath, BOOL isReadOnly)
{
std::string driveLetter;
char devicePath[1024];
// 路径以\Device\HarddiskVolumex为起始而不是盘符
std::string path = DriveLetterToVolumePath(dirpath);
if (!path.empty()) {
dirpath = path;
}
std::cout << "SetDirReadonly " << dirpath << " " << isReadOnly << std::endl;
std::wstring wpath(dirpath.begin(), dirpath.end());
PACKET_TYPE type = isReadOnly ? PACKET_SET_PATH : PACKET_DEL_PATH;
return SendMessageToFlt(type, wpath.c_str(), FLT_PATH_TYPE_READONLY);
}
BOOL MiniFilterCommunication::CleDirReadonly()
{
return SendMessageToFlt(PACKET_CLE_PATH, NULL, FLT_PATH_TYPE_READONLY);
}
BOOL MiniFilterCommunication::SetDirDelprotect(std::string& dirpath, BOOL isDelprotect)
{
std::string driveLetter;
char devicePath[1024];
// 路径以\Device\HarddiskVolumex为起始而不是盘符
std::string path = DriveLetterToVolumePath(dirpath);
if (!path.empty()) {
dirpath = path;
}
std::cout << "SetDirDelprotect " << dirpath << " " << isDelprotect << std::endl;
std::wstring wpath(dirpath.begin(), dirpath.end());
PACKET_TYPE type = isDelprotect ? PACKET_SET_PATH : PACKET_DEL_PATH;
return SendMessageToFlt(type, wpath.c_str(), FLT_PATH_TYPE_DELPROTECT);
}
BOOL MiniFilterCommunication::CleDirDelprotect()
{
return SendMessageToFlt(PACKET_CLE_PATH, NULL, FLT_PATH_TYPE_DELPROTECT);
}
BOOL MiniFilterCommunication::Connect(const std::wstring& PortName)
{
HRESULT hResult = FilterConnectCommunicationPort(PortName.c_str(), 0, NULL, 0, NULL, &m_hPort);
if (hResult != S_OK) {
return FALSE;
}
return TRUE;
}
BOOL MiniFilterCommunication::SendMessageToFlt(PACKET_TYPE Type, const wchar_t* FilePath, FLT_PATH_TYPE PathType)
{
DataPacket packet {Type, FilePath, PathType};
DWORD outputSize = 0;
HRESULT hResult = FilterSendMessage(m_hPort, &packet, sizeof(packet), &packet, sizeof(packet), &outputSize);
if (hResult != S_OK) {
return FALSE;
}
return TRUE;
}
std::string MiniFilterCommunication::DriveLetterToVolumePath(std::string& path)
{
std::string driveLetter;
char devicePath[1024];
if (path.length() >= 3 && path[1] == ':' && path[2] == '\\') {
driveLetter = path.substr(0, 2);
std::cout << "driveLetter: " << driveLetter << std::endl;
DWORD result = QueryDosDeviceA(driveLetter.c_str(), devicePath, sizeof(devicePath));
if (result == 0) {
DWORD errorCode = GetLastError();
std::cerr << "SetDirReadonly QueryDosDeviceA failed: " << errorCode << std::endl;
return std::string();
}
path.replace(0, 2, std::string(devicePath));
return path;
} else {
return std::string();
}
}
// main.cpp
#include <iostream>
#include <sstream>
#include "driver.h"
#include "filter.h"
int main(int argc, char* argv[])
{
Driver driver;
MiniFilterCommunication miniFilterCommunication;
std::string str;
while (1) {
std::cout << "> ";
if (std::getline(std::cin, str)) {
std::istringstream iss(str);
std::string command;
iss >> command;
if (command.empty()) {
continue;
} else if (command == "stop") {
if (driver.StopDriver(DRIVER_NAME)) std::cout << "stop ok." << std::endl;
else std::cerr << "stop failed!" << std::endl;
} else if (command == "delete") {
if (driver.DeleteDriver(DRIVER_NAME)) std::cout << "delete ok." << std::endl;
else std::cerr << "delete failed!" << std::endl;
} else if (command == "readonly") {
// readonly C:\Users\dxf\Desktop\FilterTest 1
std::string path;
BOOL readonly;
if (iss >> path >> readonly) {
if (miniFilterCommunication.SetDirReadonly(path, readonly))
std::cout << "SetDirReadonly ok." << std::endl;
else
std::cerr << "SetDirReadonly failed!" << std::endl;
}
} else if (command == "clereadonly") {
if (miniFilterCommunication.CleDirReadonly())
std::cout << "CleDirReadonly ok." << std::endl;
else
std::cerr << "CleDirReadonly failed!" << std::endl;
} else if (command == "delprotect") {
// delprotect C:\Users\dxf\Desktop\FilterTest 1
std::string path;
BOOL delprotect;
if (iss >> path >> delprotect) {
if (miniFilterCommunication.SetDirDelprotect(path, delprotect))
std::cout << "SetDirDelprotect ok." << std::endl;
else
std::cerr << "SetDirDelprotect failed!" << std::endl;
}
} else if (command == "cledelprotect") {
if (miniFilterCommunication.CleDirDelprotect())
std::cout << "CleDirDelprotect ok." << std::endl;
else
std::cerr << "CleDirDelprotect failed!" << std::endl;
} else if (command == "quit") {
std::cerr << "Exit." << std::endl;
break;
} else {
std::cerr << "Unknown command!" << std::endl;
}
}
}
return 0;
}
三、过滤驱动安装
|
对于微过滤驱动,它和一般的驱动不同,在加载前必须有一份安装文件向注册表中写出子键,直接使用sc启动FltRegisterFilter会注册失败,参考通用驱动程序代码加载方式,注意自动重启方式无效。 |


894

被折叠的 条评论
为什么被折叠?



