USB过滤驱动,实现U盘只读控制

来源:互联网 发布:惠州网络推广公司 编辑:程序博客网 时间:2024/05/27 03:27
功能: 
这是一个简单的USB过滤驱动,采用标准的WDM过滤,以DDK中的filter为原形。实现了U盘的只读控制。 

说明: 
1 在整个编写过程中,受到tiamo等众多高手的帮助,感激不尽。还要向他们多多学习。 
2 这是我写的具有具体功能的第一个驱动,高兴。 
3 本人是一位就读于排名在300名以外的大学的大四学生,水平有限,有错误的地方请各位指出。见笑了。 

开发中使用的工具和环境: 
vc 6.0+2000ddk 用DbgViewer查看信息。 用DeviceTree查看驱动加载情况 

正文: 

我从开始看驱动就认为,一个完整的驱动是改出来的。 
因此我修改了ddk中toaster/filter程序。这个程序写的思路很清晰,把一个标准的过滤驱动程序应该有的各个模块都写了出来。特 
别是很完整的做了PNP的相关操作。 
作为一个标准过滤驱动,应该在AddDevice中将创建的设备IoAttachDeviceToDeviceStack到欲过滤的设备上。而这个设备就是 
AddDevice的第二个参数。这里要说明的是,我过滤的设备对象是usbstor.sys,是一个FlowerFilters。 在注册表中加入相应的项(这个 
过程应该是INF做的,我不会做,因此直接加的),系统在加载usbstor.sys这个驱动的时候,根据注册表中FlowerFilters对应的值就会 
自动去加载你的驱动,非常的方便。 
系统加载你的设备以后就进入了AddDevice,此时你可以IoAttachDeviceToDeviceStack,填写你的PDEVICE_EXTENSION等等。 
这样完成以后,你的设备就可以在DeviceTree中看到,位置在USBSTOR打开以后,展开可以看到。 
剩下的不用我说,大家也知道。就是拦截相应的IRP了。对应不同的过滤功能,需要拦截的IRP也不同,以我这为例子,我想拦截 
所有的写操作,就是使U盘成为只读的。开始我去拦截IRP_MJ_WRITE,跟踪发现,写U盘的时候根本不走这个地方。询问后知道要 
拦截相应的scsi命令,关于SCSI命令有相关的规范去看。对SCSI命令的取得和操作大致如下: 
1 得到当前的SCSI命令: 
DbgPrint(/"IRP_MJ_SCSI/"); 
irpStack = IoGetCurrentIrpStackLocation(irp); 
CurSrb=irpStack->Parameters.Scsi.Srb; 
cdb=CurSrb->Cdb; 
opCode=cdb->CDB6GENERIC.OperationCode; 
现在opCode中就是当前的SCSI命令。 

2 分析SCSI命令(由于SCSI命令很多,找到真正要拦截的SCSI命令,还需要参看实例) 
if(opCode==SCSIOP_MODE_SENSE)//一个mode sense结构 
{ } 
if(opCode==SCSIOP_WRITE||opCode==SCSIOP_WRITE6)//写操作 
{ } 
其他的参看SCSI规范 

当我拦截到SCSI命令以后,认为一切边的顺利起来。但是实际上,我在只拦截SCSIOP_WRITE的时候,虽然系统不会真正的写东西到 
U盘上,但却要过很久才会提示延时写错误。这样的程序显然是不能给用户的。这个时候tiamo告诉我一个方法,这个方法来源于市场 
上的一种“带写保护功能”的U盘,他可以象软盘一样的写保护。当然他是硬件上实现的。软件实现更加的简单,如下: 
irpStack = IoGetCurrentIrpStackLocation(Irp); 
CurSrb=irpStack->Parameters.Scsi.Srb;//Get Current Scsi SRB, Analysis SCSI Command here! 
cdb=CurSrb->Cdb; 
opCode=cdb->CDB6GENERIC.OperationCode; 
if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer && CurSrb->DataTransferLength >= sizeof(MODE_PARAMETER_HEADER) 

modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer; 
modeData->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT; 

具体就是modeData->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT;这句话了。 

写到这里,U盘的只读功能就完成了。效果很好。 
原创粉丝点击