能力值:
( LV2,RANK:10 )
2 楼
现在已经实现了功能,禁用是没问题的, 只读有点问题, 新建空txt文件可以成功, 写入信息保存时会提示拒绝访问然后弹出另存为, 我想在只读时任何覆盖操作都提示一下就完了该这么做呢? 下面是源码 #include <fltKernel.h> #include <dontuse.h> #include <suppress.h> #pragma prefast(disable:__WARNING_ENCODE_MEMBER_FUNCTION_POINTER, "Not valid for kernel mode drivers") #define SETTINGS_AUTORUNINF 0x01 #define SETTINGS_EXECUTABLES SETTINGS_AUTORUNINF << 1 #define SETTINGS_BLOCK SETTINGS_AUTORUNINF << 2 #define SETTINGS_READONLY SETTINGS_AUTORUNINF << 3 #define SETTINGS_NOFILEEXECUTE SETTINGS_AUTORUNINF << 4 #define DENY_CREATE 1 #define DENY_WRITE 1 << 1 #define DENY_INFORMATHION 1 << 2 PFLT_FILTER Filter; #define pasthrough_INSTANCE_CONTEXT_TAG 'cIxC' typedef struct _pasthrough_INSTANCE_CONTEXT { BOOLEAN ucFlags; } pasthrough_INSTANCE_CONTEXT, *Ppasthrough_INSTANCE_CONTEXT; #define pasthrough_INSTANCE_CONTEXT_SIZE sizeof(pasthrough_INSTANCE_CONTEXT) NTSTATUS DriverEntry(__in PDRIVER_OBJECT DriverObject, __in PUNICODE_STRING RegistryPath); NTSTATUS pasthroughUnload(__in FLT_FILTER_UNLOAD_FLAGS Flags); NTSTATUS pasthroughQueryTeardown(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_QUERY_TEARDOWN_FLAGS Flags); FLT_PREOP_CALLBACK_STATUS pasthroughPreCreate(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext); FLT_PREOP_CALLBACK_STATUS pasthroughPreWrite(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext); FLT_PREOP_CALLBACK_STATUS pasthroughPreSetInformation(__inout PFLT_CALLBACK_DATA Data, __in PCFLT_RELATED_OBJECTS FltObjects, __deref_out_opt PVOID *CompletionContext); NTSTATUS pasthroughInstanceSetup(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_SETUP_FLAGS Flags, __in DEVICE_TYPE VolumeDeviceType, __in FLT_FILESYSTEM_TYPE VolumeFilesystemType); VOID ReadRegistrySettings(__in PUNICODE_STRING RegistryPath); VOID pasthroughContextCleanup(__in PFLT_CONTEXT Context, __in FLT_CONTEXT_TYPE ContextType); VOID pasthroughInstanceTeardownComplete(__in PCFLT_RELATED_OBJECTS FltObjects, __in FLT_INSTANCE_TEARDOWN_FLAGS Flags); // Assign text sections for each routine. #ifdef ALLOC_PRAGMA #pragma alloc_text(INIT, DriverEntry) #pragma alloc_text(PAGE, pasthroughUnload) #pragma alloc_text(PAGE, pasthroughInstanceSetup) #pragma alloc_text(PAGE, pasthroughPreCreate) #pragma alloc_text(PAGE, pasthroughPreWrite) #pragma alloc_text(PAGE, pasthroughPreSetInformation) #pragma alloc_text(PAGE, pasthroughContextCleanup) #pragma alloc_text(PAGE, pasthroughInstanceTeardownComplete) #endif NTSTATUS DriverEntry(__in PDRIVER_OBJECT pDO, __in PUNICODE_STRING pusRegistryPath) { NTSTATUS iNTStatus; const FLT_OPERATION_REGISTRATION Callbacks[] = { {IRP_MJ_CREATE, 0, pasthroughPreCreate, NULL}, {IRP_MJ_SET_INFORMATION, 0, pasthroughPreSetInformation, NULL}, {IRP_MJ_WRITE, 0, pasthroughPreWrite, NULL}, {IRP_MJ_OPERATION_END} }; const FLT_CONTEXT_REGISTRATION contextRegistration[] = { {FLT_INSTANCE_CONTEXT, 0, pasthroughContextCleanup, pasthrough_INSTANCE_CONTEXT_SIZE, pasthrough_INSTANCE_CONTEXT_TAG}, {FLT_CONTEXT_END} }; const FLT_REGISTRATION FilterRegistration = { sizeof(FLT_REGISTRATION), // Size FLT_REGISTRATION_VERSION, // Version 0, // Flags contextRegistration, // Context Registration. Callbacks, // Operation callbacks pasthroughUnload, // FilterUnload pasthroughInstanceSetup, // InstanceSetup NULL, // InstanceQueryTeardown NULL, // InstanceTeardownStart pasthroughInstanceTeardownComplete, // InstanceTeardownComplete NULL, // GenerateFileName NULL, // GenerateDestinationFileName NULL // NormalizeNameComponent }; iNTStatus = FltRegisterFilter(pDO, &FilterRegistration, &Filter); if (!NT_SUCCESS(iNTStatus)) return iNTStatus; iNTStatus = FltStartFiltering(Filter); if (NT_SUCCESS(iNTStatus)) return STATUS_SUCCESS; FltUnregisterFilter(Filter); return iNTStatus; } NTSTATUS pasthroughUnload(__in FLT_FILTER_UNLOAD_FLAGS iFFUF) { UNREFERENCED_PARAMETER(iFFUF); PAGED_CODE(); FltUnregisterFilter(Filter); return STATUS_SUCCESS; } int VolumeToDosName(__in PFLT_VOLUME pFV) { PDEVICE_OBJECT pDO = NULL; UNICODE_STRING usDosName; NTSTATUS iNTStatus; int iReturn = 0; iNTStatus = FltGetDiskDeviceObject(pFV, &pDO); if (NT_SUCCESS(iNTStatus)) { iNTStatus = IoVolumeDeviceToDosName(pDO, &usDosName); if (NT_SUCCESS(iNTStatus)) { iReturn = RtlUpcaseUnicodeChar(usDosName.Buffer[0]); ExFreePool(usDosName.Buffer); } } return iReturn; } NTSTATUS pasthroughInstanceSetup(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_SETUP_FLAGS iFISF, __in DEVICE_TYPE iDT, __in FLT_FILESYSTEM_TYPE iFFT) { UCHAR ucBuffer[sizeof(FLT_VOLUME_PROPERTIES)+512]; PFLT_VOLUME_PROPERTIES pFVP = (PFLT_VOLUME_PROPERTIES)ucBuffer; ULONG ulLengthReceived; NTSTATUS iNTStatus; NTSTATUS iNTStatusReturn; Ppasthrough_INSTANCE_CONTEXT pAIC = NULL; int iDrive; UNREFERENCED_PARAMETER(iFISF); UNREFERENCED_PARAMETER(iFFT); ulLengthReceived = 0; //ReadRegistrySettings(NULL); PAGED_CODE(); iDrive = VolumeToDosName(pFRO->Volume); iNTStatus = FltAllocateContext(pFRO->Filter, FLT_INSTANCE_CONTEXT, pasthrough_INSTANCE_CONTEXT_SIZE, NonPagedPool, &pAIC); if (!NT_SUCCESS(iNTStatus)) { if (pAIC != NULL) FltReleaseContext(pAIC); return STATUS_FLT_DO_NOT_ATTACH; } DbgPrint("pasthrough: pasthroughInstanceSetup iDT: %d", iDT); switch(iDT) { case FILE_DEVICE_DISK_FILE_SYSTEM: if (NT_SUCCESS(FltGetVolumeProperties(pFRO->Volume, pFVP, sizeof(ucBuffer), &ulLengthReceived))) { DbgPrint("pasthrough: pasthroughInstanceSetup FILE_DEVICE_DISK_FILE_SYSTEM: RealDeviceName: %wZ DeviceCharacteristics: %08x", &pFVP->RealDeviceName, pFVP->DeviceCharacteristics); if (pFVP->DeviceCharacteristics & FILE_REMOVABLE_MEDIA) { pAIC->ucFlags = TRUE; iNTStatusReturn = STATUS_SUCCESS; } } break; default: iNTStatusReturn = STATUS_FLT_DO_NOT_ATTACH; } DbgPrint("pasthrough: pasthroughInstanceSetup iNTStatusReturn: %d", iNTStatusReturn); iNTStatus = FltSetInstanceContext(pFRO->Instance, FLT_SET_CONTEXT_KEEP_IF_EXISTS, pAIC, NULL); if (!NT_SUCCESS(iNTStatus)) { if (pAIC != NULL) FltReleaseContext(pAIC); return STATUS_FLT_DO_NOT_ATTACH; } if (pAIC != NULL) FltReleaseContext(pAIC); if (NT_SUCCESS(iNTStatusReturn)) { if (ulLengthReceived <= 0) FltGetVolumeProperties(pFRO->Volume, pFVP, sizeof(ucBuffer), &ulLengthReceived); DbgPrint("pasthrough: Instance setup iDT: %d RealDeviceName: %wZ DeviceCharacteristics: %08x Dosname: %c", iDT, &pFVP->RealDeviceName, pFVP->DeviceCharacteristics, iDrive); } return iNTStatusReturn; } PKEY_VALUE_PARTIAL_INFORMATION QueryRegistryValue(const wchar_t* regPath, const wchar_t* regKey) { HANDLE KeyHandle = NULL; NTSTATUS Status = STATUS_SUCCESS; UNICODE_STRING KeyPath; OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING SourceKeyName; PKEY_VALUE_PARTIAL_INFORMATION AcKeyInfo = NULL; KEY_VALUE_PARTIAL_INFORMATION KeyInfo; ULONG Length = 0; RtlInitUnicodeString(&KeyPath, regPath); RtlInitUnicodeString(&SourceKeyName, regKey); DbgPrint("pasthrough: KeyPath = %wZ, SourceKeyName = %wZ\n", &KeyPath, &SourceKeyName); //初始化OBJECT_ATTRIBUTES结构体 InitializeObjectAttributes( &ObjectAttributes, &KeyPath, OBJ_CASE_INSENSITIVE, NULL, NULL); //打开注册表键 Status = ZwOpenKey(&KeyHandle, KEY_READ, &ObjectAttributes); if (!NT_SUCCESS(Status)) { DbgPrint("pasthrough: Open the Key Handle Faild!! -- %#X\n", Status); return AcKeyInfo; } //第一次读取注册表键值探测数据大小 Status = ZwQueryValueKey( KeyHandle, &SourceKeyName, KeyValuePartialInformation, &KeyInfo, sizeof(KEY_VALUE_PARTIAL_INFORMATION), &Length); if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) { DbgPrint("pasthrough: 读取SystemRoot键值失败!! - %#X\n", Status); ZwClose(KeyHandle); return AcKeyInfo; } //根据上面探测的注册表键值大小动态分配内存 AcKeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePoolWithTag(NonPagedPool, Length, "tag2"); if (NULL == AcKeyInfo) { DbgPrint("pasthrough: 在分配保存Key键值的内存空间时失败!!"); ZwClose(KeyHandle); Status = STATUS_INSUFFICIENT_RESOURCES; return AcKeyInfo; } //再次读取注册表键值 Status = ZwQueryValueKey( KeyHandle, &SourceKeyName, KeyValuePartialInformation, AcKeyInfo, Length, &Length); if (!NT_SUCCESS(Status)) { DbgPrint("pasthrough: 读取SystemRoot键值失败!! - %#X\n", Status); ZwClose(KeyHandle); ExFreePool(AcKeyInfo); return AcKeyInfo; } ZwClose(KeyHandle); return AcKeyInfo; } VOID UnicodeToChar(PUNICODE_STRING dst, char *src) { ANSI_STRING string; RtlUnicodeStringToAnsiString(&string,dst, TRUE); strcpy(src,string.Buffer); RtlFreeAnsiString(&string); } int QueryUSBRegInfo(PCFLT_RELATED_OBJECTS pFRO) { int option = 0; char VolumeName[2] = {0}; UNICODE_STRING u; char RegVolimeValue[100] = {0}; PKEY_VALUE_PARTIAL_INFORMATION AcOptionInfo = NULL; PULONG pulValue = NULL; PKEY_VALUE_PARTIAL_INFORMATION AcKeyInfo = QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo", L"Volume"); if (NULL == AcKeyInfo) { DbgPrint("pasthrough QueryUSBRegInfo AcKeyInfo == NULL"); return option; } if (AcKeyInfo->Type != REG_SZ) { DbgPrint("pasthrough QueryUSBRegInfo AcKeyInfo->Type != REG_SZ"); ExFreePool(AcKeyInfo); return option; } VolumeName[0] = (char)VolumeToDosName(pFRO->Volume); DbgPrint("pasthrough QueryUSBRegInfo VolimeName = %s\n", VolumeName); RtlInitUnicodeString(&u, AcKeyInfo->Data); DbgPrint("pasthrough QueryUSBRegInfo u = %wZ\n", &u); ExFreePool(AcKeyInfo); UnicodeToChar(&u, RegVolimeValue); DbgPrint("pasthrough QueryUSBRegInfo RegVolimeValue = %s\n", RegVolimeValue); if (strstr(RegVolimeValue, VolumeName) == NULL) { return option; } AcOptionInfo = QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo", L"Option"); if (NULL == AcOptionInfo) { DbgPrint("pasthrough QueryUSBRegInfo NULL == AcOptionInfo\n"); return option; } if (AcOptionInfo->Type != REG_DWORD || AcOptionInfo->DataLength != sizeof(ULONG)) { DbgPrint("pasthrough QueryUSBRegInfo AcOptionInfo type or length error\n"); ExFreePool(AcOptionInfo); return option; } pulValue = (PULONG) AcOptionInfo->Data; option = (int)*pulValue; DbgPrint("pasthrough QueryUSBRegInfo option %d\n", option); ExFreePool(AcOptionInfo); return option; } FLT_PREOP_CALLBACK_STATUS pasthroughPreCreate(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext) { Ppasthrough_INSTANCE_CONTEXT pAIC = NULL; int option; int CreateDisposition; int IsNewCreate = 0; UNREFERENCED_PARAMETER(pFRO); UNREFERENCED_PARAMETER(ppvCompletionContext); PAGED_CODE(); option = QueryUSBRegInfo(pFRO); CreateDisposition = (pFCD->Iopb->Parameters.Create.Options >> 24) & 0x000000ff; IsNewCreate = (CreateDisposition == FILE_CREATE || CreateDisposition == FILE_OPEN_IF || CreateDisposition == FILE_OVERWRITE_IF); if ((option & DENY_CREATE) != DENY_CREATE) return FLT_PREOP_SUCCESS_NO_CALLBACK; else if ((option & DENY_WRITE) == DENY_WRITE) { pFCD->IoStatus.Status = IsNewCreate ? STATUS_ACCESS_DENIED : STATUS_MEDIA_WRITE_PROTECTED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } else { DbgPrint("pasthrough pre Create: access denied"); pFCD->IoStatus.Status = STATUS_ACCESS_DENIED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } } FLT_PREOP_CALLBACK_STATUS pasthroughPreWrite(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext) { Ppasthrough_INSTANCE_CONTEXT pAIC = NULL; int option; UNREFERENCED_PARAMETER(pFRO); UNREFERENCED_PARAMETER(ppvCompletionContext); PAGED_CODE(); option = QueryUSBRegInfo(pFRO); if ((option & DENY_WRITE) != DENY_WRITE) return FLT_PREOP_SUCCESS_NO_CALLBACK; else { DbgPrint("pasthrough pre Write: access denied"); pFCD->IoStatus.Status = STATUS_ACCESS_DENIED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } } FLT_PREOP_CALLBACK_STATUS pasthroughPreSetInformation(__inout PFLT_CALLBACK_DATA pFCD, __in PCFLT_RELATED_OBJECTS pFRO, __deref_out_opt PVOID *ppvCompletionContext) { int option; UNREFERENCED_PARAMETER(ppvCompletionContext); PAGED_CODE(); option = QueryUSBRegInfo(pFRO); if ((option & DENY_INFORMATHION) != DENY_INFORMATHION) return FLT_PREOP_SUCCESS_NO_CALLBACK; else { DbgPrint("pasthrough pre SetInformation: access denied"); pFCD->IoStatus.Status = STATUS_ACCESS_DENIED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } } VOID pasthroughContextCleanup(__in PFLT_CONTEXT pFC, __in FLT_CONTEXT_TYPE pFCT) { Ppasthrough_INSTANCE_CONTEXT pAIC; PAGED_CODE(); if (FLT_INSTANCE_CONTEXT == pFCT) { pAIC = (Ppasthrough_INSTANCE_CONTEXT) pFC; // no memory to release } } VOID pasthroughInstanceTeardownComplete(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_TEARDOWN_FLAGS iFITF) { Ppasthrough_INSTANCE_CONTEXT pAIC; NTSTATUS iNTStatus; UNREFERENCED_PARAMETER(iFITF); PAGED_CODE(); iNTStatus = FltGetInstanceContext(pFRO->Instance, (PFLT_CONTEXT *)&pAIC); if (NT_SUCCESS(iNTStatus)) FltReleaseContext(pAIC); }
能力值:
( LV2,RANK:10 )
11 楼
KanXuerr
我也在做类似的功能,请教楼主大大是怎么判断盘符是否是U盘呢?还有QueryRegistryValue(L"\\Registry\\Machine\\Software\\USBInfo&quo ...
这个注册表是我自己写的, 我这样写是为了方便测试, 因为公司电脑USB口封掉了。
判断是U盘可以在instancesetup里面通过卷取到设备对象, 然后取设备的这个属性IOCTL_STORAGE_QUERY_PROPERTY。
现在卡在便携设备这里了, 昨天发现这东西没有加载到文件系统, 使用的用WPD驱动, 有熟悉的人愿意讲讲吗?
NTSTATUS InstanceSetup(__in PCFLT_RELATED_OBJECTS pFRO, __in FLT_INSTANCE_SETUP_FLAGS iFISF, __in DEVICE_TYPE iDT, __in FLT_FILESYSTEM_TYPE iFFT)
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS status;
BYTE busType;
UNREFERENCED_PARAMETER(iFISF);
UNREFERENCED_PARAMETER(iFFT);
//ReadRegistrySettings(NULL);
PAGED_CODE();
status = FltGetDiskDeviceObject(pFRO->Volume, &DeviceObject);
if (!NT_SUCCESS(status))
{
return STATUS_UNSUCCESSFUL;
}
GetDeviceBusType(DeviceObject, &busType);
if (busType == 7) {
// 是U盘或者移动硬盘
}
NTSTATUS
GetDeviceBusType(
__in PDEVICE_OBJECT Device,
__in __out BYTE* pBusType
)
{
PIRP Irp;
KEVENT Event;
NTSTATUS status;
IO_STATUS_BLOCK Iosb;
STORAGE_PROPERTY_QUERY PropQuery;
PSTORAGE_DEVICE_DESCRIPTOR pDesc;
PVOID QueryBuffer = NULL;
ULONG QuerySize = 0x2000;
char * pDeviceInfo;
__try
{
QueryBuffer = ExAllocatePoolWithTag(NonPagedPool, QuerySize, UIM_USB_POOL_TAG);
if (!QueryBuffer)
{
status = STATUS_INSUFFICIENT_RESOURCES;
__leave;
}
memset(&PropQuery, 0, sizeof(PropQuery));
memset(QueryBuffer, 0, QuerySize);
PropQuery.PropertyId = StorageDeviceProperty;
PropQuery.QueryType = PropertyStandardQuery;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
//
//A driver that calls IoBuildDeviceIoControlRequest must not call IoFreeIrp,
//because the I/O manager frees these synchronous IRPs after IoCompleteRequest has been called.
//
Irp = IoBuildDeviceIoControlRequest(
IOCTL_STORAGE_QUERY_PROPERTY,
Device,
&PropQuery,
sizeof(PropQuery),
QueryBuffer,
QuerySize,
FALSE,
&Event,
&Iosb
);
if (!Irp)
{
status = STATUS_UNSUCCESSFUL;
__leave;
}
status = IoCallDriver(Device, Irp);
if (STATUS_PENDING == status)
{
KeWaitForSingleObject(
&Event,
Executive,
KernelMode,
FALSE,
(PLARGE_INTEGER)NULL
);
status = Iosb.Status;
}
if (!NT_SUCCESS(status))
{
__leave;
}
if (!Iosb.Information)
{
status = STATUS_UNSUCCESSFUL;
__leave;
}
pDesc = (PSTORAGE_DEVICE_DESCRIPTOR)QueryBuffer;
if (pBusType)
*pBusType = (BYTE)pDesc->BusType;
// 将pid, vid, seq打印出来
pDeviceInfo = (char*)pDesc;
DbgPrint("GetDeviceBusType pid: %s, vid: %s, version: %s, seq: %s\n", &pDeviceInfo[pDesc->ProductIdOffset], &pDeviceInfo[pDesc->VendorIdOffset], &pDeviceInfo[pDesc->ProductRevisionOffset], &pDeviceInfo[pDesc->SerialNumberOffset]);
}
__finally
{
if (QueryBuffer)
if (QueryBuffer != NULL)
{
ExFreePoolWithTag(QueryBuffer, UIM_USB_POOL_TAG);
QueryBuffer = NULL;
}
}
return status;
}