阅读:33380回复:78
共享我写的一个USB过滤驱动,实现U盘只读控制
看到很多人都把自己的东西拿出来共享,我也来写一点。
功能: 这是一个简单的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盘的只读功能就完成了。效果很好。 写这个文章的时候我正在完善这个程序,希望用一个应用层的程序和他配合。可以控制U盘只读、读写、全锁定等等。遇到一些大问题。 当我完成那个功能的时候,再把这些详细的东西加上。 献丑了。。 |
|
沙发#
发布于:2005-04-05 17:36
谢谢.
大学排名不能说明什么. 人的差异在于专注和努力程度,不在于就读于什么学校. 清华北大的垃圾我也遇到过,没上过大学的牛人我也见过. 共享的世界才是完美的:) [编辑 - 4/5/05 by znsoft] |
|
|
板凳#
发布于:2005-04-05 19:04
大学排名不能说明什么. 很同意znsoft的观点,我也见过很多清华北大的眼高手低的人。“人的差异在于专注和努力程度,不在于就读于什么学校”这句话太经典了。收藏了。 |
|
|
地板#
发布于:2005-04-05 19:16
支持zhjie374!
“人的差异在于专注和努力程度,不在于就读于什么学校”经典。 |
|
|
地下室#
发布于:2005-04-06 12:19
我是菜鸟,想问一下你是如何加载这个驱动程序的??
如何测试?? 呵呵 也就是说如何修改注册表然后加载这个驱动? [编辑 - 4/6/05 by wangshust] |
|
|
5楼#
发布于:2005-04-06 13:27
首先要保证你的过滤驱动已经是在SERVICES中有这个项.
然后在相应的ENUM下加上FLOWERFILTERS 是一个MUTI_SZ,值就是你对应的那个服务名字. |
|
6楼#
发布于:2005-04-06 13:27
谢谢. 但是对于刚刚毕业的而言,名牌就是机会多! 你说公平吗 |
|
|
7楼#
发布于:2005-04-06 15:59
名牌确实机会多.
没有办法. 深有体会 |
|
8楼#
发布于:2005-04-06 17:14
是个好人!
|
|
|
9楼#
发布于:2005-04-07 09:00
名牌确实机会多. 名牌不如有个好身体,郁闷... |
|
|
10楼#
发布于:2005-04-08 15:30
引用: 深有同感,工作累,锻炼时间少啊!每天在路上就把时间耗光了。 |
|
|
11楼#
发布于:2005-04-08 15:34
还有,赚的钱交个人所得税了,所剩无几。
入不敷出。好可怜啊! |
|
|
12楼#
发布于:2005-05-31 17:14
各位,大家好
我按照zhjie374兄的做法,做了如下: 给 HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Enum\\USB\\Vid_0ea0&Pid_6803\\2885639B3DFD3D12 加了UpperFilters,加载filter,用Dbgview.exe查看我在IRP_MJ_SCSI加的DBGOUT,看看是否有irp经过,可是没有看到 我在HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Control\\Class\\{36FC9E60-C465-11CF-8056-444553540000} 加了UpperFilters确可以看到Dbgview.exe出来的DBGOUT测试信息 请问我的哪有问题,请指点? |
|
13楼#
发布于:2005-06-01 00:06
// CurSrb如何申明
CurSrb=irpStack->Parameters.Scsi.Srb;//Get Current Scsi SRB, Analysis SCSI Command here! // cdb如何申明 cdb=CurSrb->Cdb; // opCode 如何申明 opCode=cdb->CDB6GENERIC.OperationCode; if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer && CurSrb->DataTransferLength >= sizeof(MODE_PARAMETER_HEADER) { // modeData 如何申明 modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer; modeData->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT; } |
|
14楼#
发布于:2005-06-01 10:01
cdb=CurSrb->Cdb;
// cdb 是一个 UCHAR Cdb[16];结构 下面怎么还有啊 opCode=cdb->CDB6GENERIC.OperationCode; 如何解释啊 |
|
15楼#
发布于:2005-06-01 21:32
case IRP_MJ_INTERNAL_DEVICE_CONTROL:
//case IRP_MJ_SCSI: // peter add CurSrb = ExAllocatePoolWithTag(NonPagedPool, sizeof(SCSI_REQUEST_BLOCK), DISK_TAG_SRB); if (CurSrb == NULL) { DBGOUT((\"no\")); }else{ DBGOUT((\"ok\")); } RtlZeroMemory(CurSrb, SCSI_REQUEST_BLOCK_SIZE); CurSrb=irpSp->Parameters.Scsi.Srb; cdb = (PCDB)CurSrb->Cdb; opCode=cdb->CDB6GENERIC.OperationCode; if(opCode==SCSIOP_MODE_SENSE && CurSrb->DataBuffer && CurSrb->DataTransferLength >= sizeof(MODE_PARAMETER_HEADER) ) { DBGOUT((\"test\")); modeData = (PMODE_PARAMETER_HEADER)CurSrb->DataBuffer; modeData->DeviceSpecificParameter|=MODE_DSP_WRITE_PROTECT; } DBGOUT((\"OperationCode1 (%x)\", cdb->CDB6GENERIC.OperationCode )); // peter add end 问题出现了, cdb->CDB6GENERIC.OperationCode 的植是 0 怎么回事? |
|
16楼#
发布于:2005-06-02 13:41
出现的 opCode 值 (56) ,(30),(6C) ,每次出现的不确定,奇怪
|
|
17楼#
发布于:2005-06-29 16:25
scsci 命令表
#define PSI_EIDE_SCSIOP 1 #define CHAR char #define UCHAR unsigned char #define SHORT short #define USHORT unsigned short #define BOOL long #define LONG long #define ULONG unsigned long #define VOID void #define ANY2SCSI(up, p) #define SCSI2LONG(up) #define XANY2SCSI(up, p) #define XSCSI2LONG(up) #define SCSIOP_TEST_UNIT_READY 0x00 #define SCSIOP_REZERO_UNIT 0x01 #define SCSIOP_REWIND 0x01 #define SCSIOP_REQUEST_BLOCK_ADDR 0x02 #define SCSIOP_REQUEST_SENSE 0x03 #define SCSIOP_FORMAT_UNIT 0x04 #define SCSIOP_READ_BLOCK_LIMITS 0x05 #define SCSIOP_REASSIGN_BLOCKS 0x07 #define SCSIOP_READ6 0x08 #define SCSIOP_RECEIVE 0x08 #define SCSIOP_WRITE6 0x0A #define SCSIOP_PRINT 0x0A #define SCSIOP_SEND 0x0A #define SCSIOP_SEEK6 0x0B #define SCSIOP_TRACK_SELECT 0x0B #define SCSIOP_SLEW_PRINT 0x0B #define SCSIOP_SEEK_BLOCK 0x0C #define SCSIOP_PARTITION 0x0D #define SCSIOP_READ_REVERSE 0x0F #define SCSIOP_WRITE_FILEMARKS 0x10 #define SCSIOP_FLUSH_BUFFER 0x10 #define SCSIOP_SPACE 0x11 #define SCSIOP_INQUIRY 0x12 #define SCSIOP_VERIFY6 0x13 #define SCSIOP_RECOVER_BUF_DATA 0x14 #define SCSIOP_MODE_SELECT 0x15 #define SCSIOP_RESERVE_UNIT 0x16 #define SCSIOP_RELEASE_UNIT 0x17 #define SCSIOP_COPY 0x18 #define SCSIOP_ERASE 0x19 #define SCSIOP_MODE_SENSE 0x1A #define SCSIOP_START_STOP_UNIT 0x1B #define SCSIOP_STOP_PRINT 0x1B #define SCSIOP_LOAD_UNLOAD 0x1B #define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C #define SCSIOP_SEND_DIAGNOSTIC 0x1D #define SCSIOP_MEDIUM_REMOVAL 0x1E #define SCSIOP_READ_CAPACITY 0x25 #define SCSIOP_READ 0x28 #define SCSIOP_WRITE 0x2A #define SCSIOP_SEEK 0x2B #define SCSIOP_LOCATE 0x2B #define SCSIOP_WRITE_VERIFY 0x2E #define SCSIOP_VERIFY 0x2F #define SCSIOP_SEARCH_DATA_HIGH 0x30 #define SCSIOP_SEARCH_DATA_EQUAL 0x31 #define SCSIOP_SEARCH_DATA_LOW 0x32 #define SCSIOP_SET_LIMITS 0x33 #define SCSIOP_READ_POSITION 0x34 #define SCSIOP_SYNCHRONIZE_CACHE 0x35 #define SCSIOP_COMPARE 0x39 #define SCSIOP_COPY_COMPARE 0x3A #define SCSIOP_WRITE_DATA_BUFF 0x3B #define SCSIOP_READ_DATA_BUFF 0x3C #define SCSIOP_CHANGE_DEFINITION 0x40 #define SCSIOP_READ_SUB_CHANNEL 0x42 #define SCSIOP_READ_TOC 0x43 #define SCSIOP_READ_HEADER 0x44 #define SCSIOP_PLAY_AUDIO 0x45 #define SCSIOP_PLAY_AUDIO_MSF 0x47 #define SCSIOP_PLAY_TRACK_INDEX 0x48 #define SCSIOP_PLAY_TRACK_RELATIVE 0x49 #define SCSIOP_PAUSE_RESUME 0x4B #define SCSIOP_LOG_SELECT 0x4C #define SCSIOP_LOG_SENSE 0x4D #define SCSIOP_MODE_SELECT10 0x55 #define SCSIOP_MODE_SENSE10 0x5A #define SCSIOP_LOAD_UNLOAD_SLOT 0xA6 #define SCSIOP_MECHANISM_STATUS 0xBD #define SCSIOP_READ_CD 0xBE #define NULL 0 #define PCI2000 |
|
|
18楼#
发布于:2005-06-29 16:38
ms 的定义
//// SCSI CDB operation codes // #define SCSIOP_TEST_UNIT_READY 0x00 #define SCSIOP_REZERO_UNIT 0x01 #define SCSIOP_REWIND 0x01 #define SCSIOP_REQUEST_BLOCK_ADDR 0x02 #define SCSIOP_REQUEST_SENSE 0x03 #define SCSIOP_FORMAT_UNIT 0x04 #define SCSIOP_READ_BLOCK_LIMITS 0x05 #define SCSIOP_REASSIGN_BLOCKS 0x07 #define SCSIOP_INIT_ELEMENT_STATUS 0x07 #define SCSIOP_READ6 0x08 #define SCSIOP_RECEIVE 0x08 #define SCSIOP_WRITE6 0x0A #define SCSIOP_PRINT 0x0A #define SCSIOP_SEND 0x0A #define SCSIOP_SEEK6 0x0B #define SCSIOP_TRACK_SELECT 0x0B #define SCSIOP_SLEW_PRINT 0x0B #define SCSIOP_SEEK_BLOCK 0x0C #define SCSIOP_PARTITION 0x0D #define SCSIOP_READ_REVERSE 0x0F #define SCSIOP_WRITE_FILEMARKS 0x10 #define SCSIOP_FLUSH_BUFFER 0x10 #define SCSIOP_SPACE 0x11 #define SCSIOP_INQUIRY 0x12 #define SCSIOP_VERIFY6 0x13 #define SCSIOP_RECOVER_BUF_DATA 0x14 #define SCSIOP_MODE_SELECT 0x15 #define SCSIOP_RESERVE_UNIT 0x16 #define SCSIOP_RELEASE_UNIT 0x17 #define SCSIOP_COPY 0x18 #define SCSIOP_ERASE 0x19 #define SCSIOP_MODE_SENSE 0x1A #define SCSIOP_START_STOP_UNIT 0x1B #define SCSIOP_STOP_PRINT 0x1B #define SCSIOP_LOAD_UNLOAD 0x1B #define SCSIOP_RECEIVE_DIAGNOSTIC 0x1C #define SCSIOP_SEND_DIAGNOSTIC 0x1D #define SCSIOP_MEDIUM_REMOVAL 0x1E #define SCSIOP_READ_FORMATTED_CAPACITY 0x23 #define SCSIOP_READ_CAPACITY 0x25 #define SCSIOP_READ 0x28 #define SCSIOP_WRITE 0x2A #define SCSIOP_SEEK 0x2B #define SCSIOP_LOCATE 0x2B #define SCSIOP_POSITION_TO_ELEMENT 0x2B #define SCSIOP_WRITE_VERIFY 0x2E #define SCSIOP_VERIFY 0x2F #define SCSIOP_SEARCH_DATA_HIGH 0x30 #define SCSIOP_SEARCH_DATA_EQUAL 0x31 #define SCSIOP_SEARCH_DATA_LOW 0x32 #define SCSIOP_SET_LIMITS 0x33 #define SCSIOP_READ_POSITION 0x34 #define SCSIOP_SYNCHRONIZE_CACHE 0x35 #define SCSIOP_COMPARE 0x39 #define SCSIOP_COPY_COMPARE 0x3A #define SCSIOP_WRITE_DATA_BUFF 0x3B #define SCSIOP_READ_DATA_BUFF 0x3C #define SCSIOP_CHANGE_DEFINITION 0x40 #define SCSIOP_READ_SUB_CHANNEL 0x42 #define SCSIOP_READ_TOC 0x43 #define SCSIOP_READ_HEADER 0x44 #define SCSIOP_PLAY_AUDIO 0x45 #define SCSIOP_PLAY_AUDIO_MSF 0x47 #define SCSIOP_PLAY_TRACK_INDEX 0x48 #define SCSIOP_PLAY_TRACK_RELATIVE 0x49 #define SCSIOP_PAUSE_RESUME 0x4B #define SCSIOP_LOG_SELECT 0x4C #define SCSIOP_LOG_SENSE 0x4D #define SCSIOP_STOP_PLAY_SCAN 0x4E #define SCSIOP_READ_DISK_INFORMATION 0x51 #define SCSIOP_READ_TRACK_INFORMATION 0x52 #define SCSIOP_MODE_SELECT10 0x55 #define SCSIOP_MODE_SENSE10 0x5A #define SCSIOP_REPORT_LUNS 0xA0 #define SCSIOP_SEND_KEY 0xA3 #define SCSIOP_REPORT_KEY 0xA4 #define SCSIOP_MOVE_MEDIUM 0xA5 #define SCSIOP_LOAD_UNLOAD_SLOT 0xA6 #define SCSIOP_EXCHANGE_MEDIUM 0xA6 #define SCSIOP_SET_READ_AHEAD 0xA7 #define SCSIOP_READ_DVD_STRUCTURE 0xAD #define SCSIOP_REQUEST_VOL_ELEMENT 0xB5 #define SCSIOP_SEND_VOLUME_TAG 0xB6 #define SCSIOP_READ_ELEMENT_STATUS 0xB8 #define SCSIOP_READ_CD_MSF 0xB9 #define SCSIOP_SCAN_CD 0xBA #define SCSIOP_PLAY_CD 0xBC #define SCSIOP_MECHANISM_STATUS 0xBD #define SCSIOP_READ_CD 0xBE #define SCSIOP_INIT_ELEMENT_RANGE 0xE7 |
|
|
19楼#
发布于:2005-08-08 16:30
cbd的类型是什么喃?
|
|
上一页
下一页