参考资料为《windows驱动开发详解》
.h
#include "ntddk.h" #include "ntddkbd.h" #include "string.h" #include "interface.h" #include "scsi.h" #if !defined(_FILTER_H_) //注意这个位置不能乱放,我的认识是要放在加载的头文件的下面 #define _FILTER_H_ #define DISK_TAG_SRB 'SDcS' // "ScDS" - srb allocation #define MAXLEN 256 #define NTDEVICE_NAME_STRING L"\\Device\\Usbstorfilter" #define SYMBOLIC_NAME_STRING L"\\DosDevices\\Usbstorfilter" #ifndef STATUS_CONTINUE_COMPLETION #define STATUS_CONTINUE_COMPLETION STATUS_SUCCESS #endif #define POOL_TAG 'liFT' typedef struct _DEVICE_EXTENSION { PDEVICE_OBJECT Self; PDEVICE_OBJECT NextLowerDriver; IO_REMOVE_LOCK RemoveLock; } DEVICE_EXTENSION,*PDEVICE_EXTENSION; typedef struct _CONTROL_DEVICE_EXTENSION { ULONG Deleted; // False if the deviceobject is valid, TRUE if it's deleted PVOID ControlData; // Store your control data here } CONTROL_DEVICE_EXTENSION, *PCONTROL_DEVICE_EXTENSION; EXTERN_C NTSTATUS FilterAddDevice( IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ); EXTERN_C NTSTATUS FilterDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); EXTERN_C VOID FilterUnload( IN PDRIVER_OBJECT DriverObject ); EXTERN_C NTSTATUS FilterPass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); EXTERN_C NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ); EXTERN_C NTSTATUS FilterStartCompletionRoutine( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); EXTERN_C NTSTATUS USBSCSIPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ); EXTERN_C NTSTATUS USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ); #endif
.c
#include "Driver.h" ULONG InstanceCount = 0; int flag=1; #ifdef ALLOC_PRAGMA #pragma alloc_text (INIT, DriverEntry) #pragma alloc_text (PAGE, FilterAddDevice) #pragma alloc_text (PAGE, FilterDispatchPnp) #pragma alloc_text (PAGE, FilterUnload) #endif PDEVICE_OBJECT ControlDeviceObject; NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; DbgPrint("Enter DriverEntry\n"); UNREFERENCED_PARAMETER (RegistryPath); for (ULONG ulIndex=0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++ ) { DriverObject->MajorFunction[ulIndex] = FilterPass; } DriverObject->DriverUnload = FilterUnload; DriverObject->DriverExtension->AddDevice = FilterAddDevice; DriverObject->MajorFunction[IRP_MJ_SCSI]=USBSCSIPassThrough; DriverObject->MajorFunction[IRP_MJ_PNP] = FilterDispatchPnp; return status; } VOID FilterUnload(IN PDRIVER_OBJECT DriverObject) { PAGED_CODE(); ASSERT(DriverObject->DeviceObject == NULL); DbgPrint("Entry FilterUnload\n"); return; } NTSTATUS FilterAddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject=NULL; PDEVICE_EXTENSION deviceExtension; UNICODE_STRING ntName; RtlInitUnicodeString(&ntName, L"\\Device\\dnmm"); DbgPrint("Entry FilterAddDevice\n"); PAGED_CODE(); status=IoCreateDevice( DriverObject, sizeof (DEVICE_EXTENSION), &ntName, FILE_DEVICE_DISK, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObject ); if (!NT_SUCCESS(status)) { return status; } deviceExtension=(PDEVICE_EXTENSION)deviceObject->DeviceExtension; deviceExtension->NextLowerDriver=IoAttachDeviceToDeviceStack( deviceObject, PhysicalDeviceObject); if (NULL==deviceExtension->NextLowerDriver) { DbgPrint("IoAttachDeviceToDeviceStack fail\n"); IoDeleteDevice(deviceObject); return STATUS_UNSUCCESSFUL; } deviceObject->Flags |= deviceExtension->NextLowerDriver->Flags&(DO_BUFFERED_IO|DO_DIRECT_IO|DO_POWER_PAGABLE); deviceExtension->Self=deviceObject; IoInitializeRemoveLock(&deviceExtension->RemoveLock,POOL_TAG,1,100); deviceObject->Flags&=~DO_DEVICE_INITIALIZING; return STATUS_SUCCESS; } NTSTATUS FilterPass( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; NTSTATUS status; deviceExtension=(PDEVICE_EXTENSION) DeviceObject->DeviceExtension; status=IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp); if (!NT_SUCCESS(status)) { Irp->IoStatus.Status=status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } IoSkipCurrentIrpStackLocation(Irp); status=IoCallDriver(deviceExtension->NextLowerDriver,Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); DbgPrint(("I am FilterPass\n")); return status; } NTSTATUS FilterDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION deviceExtension; PIO_STACK_LOCATION irpStack; NTSTATUS status; KEVENT event; DbgPrint("----------------- FilterDispatchPnp.\n"); PAGED_CODE(); deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension; irpStack = IoGetCurrentIrpStackLocation(Irp); status = IoAcquireRemoveLock(&deviceExtension->RemoveLock,Irp); if (!NT_SUCCESS(status)) { Irp->IoStatus.Status = status; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } switch(irpStack->MinorFunction) { case IRP_MN_START_DEVICE: DbgPrint(":-----------------------IRP_MN_START_DEVICE:\n"); KeInitializeEvent(&event,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE) FilterStartCompletionRoutine, &event, TRUE, TRUE, TRUE); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); if (status == STATUS_PENDING) { KeWaitForSingleObject(&event,Executive,KernelMode,FALSE,NULL); status = Irp->IoStatus.Status; } if (NT_SUCCESS(status)) { if (deviceExtension->NextLowerDriver->Characteristics & FILE_REMOVABLE_MEDIA) { DeviceObject->Characteristics|=FILE_REMOVABLE_MEDIA; } } Irp->IoStatus.Status = status; IoCompleteRequest(Irp,IO_NO_INCREMENT); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); return status; case IRP_MN_REMOVE_DEVICE: DbgPrint(":---------------------IRP_MN_REMOV_DEVICE:\n"); IoReleaseRemoveLockAndWait(&deviceExtension->RemoveLock,Irp); IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); IoDetachDevice(deviceExtension->NextLowerDriver); IoDeleteDevice(DeviceObject); return status; default: DbgPrint(":---------------------default:\n"); status = Irp->IoStatus.Status; break; } Irp->IoStatus.Status = status; IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(deviceExtension->NextLowerDriver,Irp); IoReleaseRemoveLock(&deviceExtension->RemoveLock,Irp); return status; } NTSTATUS FilterStartCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PKEVENT event = (PKEVENT)Context; DbgPrint("Entry FilterStartCompletionRoutine!\n"); if (Irp->PendingReturned == TRUE) { KeSetEvent(event,IO_NO_INCREMENT,FALSE); } return STATUS_MORE_PROCESSING_REQUIRED; } NTSTATUS USBSCSIPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PDEVICE_EXTENSION StorExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; DbgPrint("SCSI-Pass-Through-begin --\n"); IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, USBSCSICompletion, DeviceObject, TRUE, TRUE, TRUE ); IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp); IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); DbgPrint("SCSI-Pass-Through-end -Write-\n"); return IoCallDriver( StorExtension->NextLowerDriver, Irp ); } NTSTATUS USBSCSICompletion( IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context ) { PMODE_PARAMETER_HEADER modeData; PCDB cdb ; UCHAR opCode; PDEVICE_EXTENSION StorExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; IoAcquireRemoveLock(&StorExtension->RemoveLock,Irp); DbgPrint("+++USBSCSICompletionWrite\n"); PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation( Irp ); PSCSI_REQUEST_BLOCK CurSrb = (PSCSI_REQUEST_BLOCK)ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK), DISK_TAG_SRB); if (CurSrb == NULL) { DbgPrint("ERROR"); ASSERT(0); } RtlZeroMemory(CurSrb, SCSI_REQUEST_BLOCK_SIZE); if ( irpStack->MajorFunction == IRP_MJ_SCSI ) { CurSrb=irpStack->Parameters.Scsi.Srb; cdb = (PCDB)CurSrb->Cdb; opCode=cdb->CDB6GENERIC.OperationCode; DbgPrint("++=====================+:Write Private 2\n"); if (opCode==SCSIOP_MODE_SENSE) { DbgPrint("++3+:Write Private 2\n"); modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer; modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT; } } if ( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } IoReleaseRemoveLock(&StorExtension->RemoveLock,Irp); return Irp->IoStatus.Status ; }
安装方法:
1. 直接修改注册表
这个驱动生成之后为 FSSSS.sys
要对某一个型号的U盘过滤(以kingston为例)。
step1:将FSSSS.sys拷贝到system32\Drivers下
step2:在注册表中找到 过滤U盘的位置。例如
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\DISK&Ven_Kingston&Prod_DataTraveler_2.0&Rev_PMAP\5B821D00025A&0
在这个条目中添加一个REG_SZ类型 KeyValue对为( LowerFilters FSSSS)。注意,如果无法修改需要先修改权限
step3:在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\中新建一个Key为FSSSS,得到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FSSSS
在这个里面添加3个键值对 REG_DWORD(ErrorControl 1) REG_DWORD(Start 3) REG_DWORD(Type 1)
step4:Disable Enable设备就OK了