|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
pccq 之前研究wpd过滤的时候,研究过这个帖子,没有成功,最后用的umdf filter我用这个帖子做的kmdf upperfilers只能处理DeviceControlCode, 不能细化到操控wpd的内部存储器的文件读写。你用umdf filter可以做到吗? |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
wx_幼儿园的王 楼主。你的UIM_USB_POOL_TAG参数是什么啊#define UIM_USB_POOL_TAG 'umiD' |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
WPD过滤驱动有方向了, 参照这个上面来做http://www.osronline.com/article.cfm%5earticle=446.htm |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
sylingyy 你需要的是usbstore filter,而不是minifilter。便携设备使用的是WPD驱动, 就好比USB鼠标键盘, 不走文件系统, 限制usbstore对他无效, usbstore还是属于文件系统的 |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
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; } |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
wumnkx 实际测试中发现, 移动硬盘识别出来是硬盘, 还有些手机比如我的小米手机识别的是便携设备,有些识别的是你U盘, 我想对这些设备都做处理, 设备怎么在驱动里面区分呢?自己试验了一下, 便携设备在资源管理器里面显示的不是盘符,而是一个设备名称, 在设备管理器里面有个专门的便携设备项, 设备插上电脑时不会触发minifilter的InstanceSetup; 后来查了一下资料, 发现这个设备用的是叫WPD的驱动, 这玩意有人熟悉吗? |
|
|
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
Thead IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION实际测试中发现, 移动硬盘识别出来是硬盘, 还有些手机比如我的小米手机识别的是便携设备,有些识别的是你U盘, 我想对这些设备都做处理, 设备怎么在驱动里面区分呢? |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
Thead IRP_MJ_ACQUIRE_FOR_SECTION_SYNCHRONIZATION感谢大佬, 试了下在这里做可以禁止执行exe!!! option = QueryUSBRegInfo(pFRO); IsExcute = (pFCD->Iopb->Parameters.AcquireForSectionSynchronization.PageProtection == PAGE_EXECUTE); if ((option & DENY_EXCUTE) != DENY_EXCUTE || !IsExcute) return FLT_PREOP_SUCCESS_NO_CALLBACK; else { DbgPrint("pasthrough pre CreateProcess: access denied"); pFCD->IoStatus.Status = STATUS_ACCESS_DENIED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
好了, 只读也搞定了, 通过看日志, 发现在precreate里面CreateDisposition不等于FILE_OPEN就是写入, 于是在这里拦截, 效果很好。 IsWrite = (CreateDisposition != FILE_OPEN) if ((option & DENY_WRITE) == DENY_WRITE && IsWrite) { DbgPrint("pasthrough pre Create: access denied IsWrite = %d, IsExcute = %d\n", IsWrite, IsExcute); pFCD->IoStatus.Status = STATUS_MEDIA_WRITE_PROTECTED; pFCD->IoStatus.Information = 0; return FLT_PREOP_COMPLETE; } 我还想禁止执行exe, 但没找到好的办法, 如果有人想到了希望不吝指教, 谢谢!! |
|
[求助]想用minifilter实现u盘的禁用或只读,该怎么着手?
现在已经实现了功能,禁用是没问题的, 只读有点问题, 新建空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); } |
|
|
|
[注意]测试你的肺活量,按住键盘0,憋气,看你能有多少行,男人不做假!
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 |
操作理由
RANk
{{ user_info.golds == '' ? 0 : user_info.golds }}
雪币
{{ experience }}
课程经验
{{ score }}
学习收益
{{study_duration_fmt}}
学习时长
基本信息
荣誉称号:
{{ honorary_title }}
能力排名:
No.{{ rank_num }}
等 级:
LV{{ rank_lv-100 }}
活跃值:
在线值:
浏览人数:{{ visits }}
最近活跃:{{ last_active_time }}
注册时间:{{ user_info.create_date_jsonfmt }}
勋章
兑换勋章
证书
证书查询 >
能力值