irp完成例程为什么星月挂瓷后还要盘吗判断是否挂起

 下载
 收藏
该文档贡献者很忙,什么也没留下。
 下载此文档
正在努力加载中...
Windows I/O处理流程浅析
下载积分:200
内容提示:讨论Windows 系统的I/O操作的流程之前,不得不提及Windows的I/O系统结构。简单说来, 从虚拟机的角度来说,Windows的I/O系统是一个层层封装的虚拟机。Windows在系统核心
文档格式:PDF|
浏览次数:1|
上传日期: 01:00:05|
文档星级:
该用户还上传了这些文档
下载文档:Windows I/O处理流程浅析.PDF
官方公共微信后使用快捷导航没有帐号?
查看: 4437|回复: 22
过滤驱动程序中IRP_MJ_SCSI的下一层是什么?
在线时间0 小时
TA的帖子TA的资源
一粒金砂, 积分 0, 距离下一级还需 5 积分
最近研究U盘过滤驱动,想先读取U盘的扇区,但是一直读不到。从网上找到几个读扇区的代码,也不管用,后来发现是因为重路了。因为我将过滤驱动挂在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-40000}下, 要在SCSI的派遣函数里禁用,我想在禁用之前读取U盘扇区,所以在禁用的代码前加入读取U盘扇区的代码,在代码里有这么一段
& & & & isl=IoGetNextIrpStackLocation(irp);
& & & & & & & & isl-&DeviceObject=dev_
& & & & & & & & isl-&MajorFunction=IRP_MJ_SCSI;
& & & & & & & & isl-&Parameters.Scsi.Srb=
& & & & & & & & isl-&CompletionRoutine=IrpCompletionRoutine_0;
& & & & & & & & isl-&Context=
& & & & & & & & isl-&Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
& & & & & & & & status=MyIoCallDriver(dev_object,irp);
所以重路了。
我想应该是在SCSI的派遣函数里写SCSI的下一层的读取扇区的代码,因为IRP_MJ_READ的下一层是IRP_MJ_SCSI,所以在SCSI里读扇区时应该写SCSI的下一层的代码,但是我不知道SCSI的下一层是什么?以及该怎么写?
谁有相关的资料?或是哪里可以看到?
或是推荐一本书也行
大家帮帮忙
在线时间0 小时
TA的帖子TA的资源
你根本不需要写SCSI下一层的代码,只需要组织好你的SRB,发送到设备堆栈的下一个就好了
在线时间0 小时
TA的帖子TA的资源
如何组织?
请指出具体怎么做?
在线时间0 小时
TA的帖子TA的资源
& &其实就是填充_SCSI_REQUEST_BLOCK结构(_IO_STACK_LOCATION.scsi._SCSI_REQUEST_BLOCK):
根据DDK文档很容易填写,里面有一个关键的字结构——在_SCSI_REQUEST_BLOCK结构最后是UCHAR Cdb[16];但是Cdb不一定是16个字节,长度由_SCSI_REQUEST_BLOCK.CdbLength决定。
& & CDB[0]为OperationCode,28h表示SCSIOP_READ,2Ah表示SCSIOP_WRITE。_CDB[1]按位描 述了一些属性,可以参考scsi.h,这里将这个字节设为80h。_CDB[2]到_CDB[5]描述的是扇区位置,依次为dwSectorLowPos 从高字节到低字节的值。CDB[7]和CDB[8]描述了要写书的扇区数。如果小于0,则设为1。
在线时间0 小时
TA的帖子TA的资源
在线时间0 小时
TA的帖子TA的资源
我是才用下面的方法禁用U盘的,见下面的代码:
插入U盘时任务栏会提示U插入,但是我的电脑里没有U盘的盘符
我想知道当刚刚插入U盘但没有显示盘符时时能不能读取到磁盘的扇区?
if (_wcsnicmp(DeviceObject-&AttachedDevice-&DriverObject-&DriverName.Buffer,L&\\Driver\\USBSTOR&,15)==0)
& & & & & & & &
& & & & & & & & PVOID
& & & & & & & & buffer=ExAllocatePool(0,512);
& & & & & & & & RtlZeroMemory(buffer,512);
& && && && && & //读扇区
& & & & & & & & status = AtapiReadWriteDisk(fido,IRP_MJ_READ,buffer,1,1,Irp);
& & & & & & & & if (NT_SUCCESS(status))
& & & & & & & & {& & & &
& & & & & & & & & & & & Irp-&IoStatus.Status = STATUS_ACCESS_DENIED;
& & & & & & & &&&& & & & Irp-&rmation = 0;
& & & & & & & & & & & & IoCompleteRequest( Irp, IO_NO_INCREMENT );
& & & & & & & & & & & & ExFreePool(buffer);
& & & & & & & && && && &return STATUS_ACCESS_DENIED;
& & & & & & & & }
在线时间0 小时
TA的帖子TA的资源
我是这么写的,不知道对不对,今天电脑系统崩溃了,两个系统都不能用了,一直在装系统,大侠给看看& & & &
srb = (PSCSI_REQUEST_BLOCK)ExAllocatePool(NonPagedPool,sizeof(SCSI_REQUEST_BLOCK));
& & & & & & & & if(!srb)
& & & & & & & & & & & &
& & & & & & & & sense = (PSENSE_DATA)ExAllocatePool(NonPagedPool,sizeof(SENSE_DATA));
& & & & & & & & psense=
& & & & & & & & if(!sense)
& & & & & & & & & & & &
& & & & & & & & memset(srb,0,sizeof(SCSI_REQUEST_BLOCK));
& & & & & & & & memset(sense,0,sizeof(SENSE_DATA));
& && &&&//更多关于srb,请看《SCSI 总线和IDE接口:协议、应用和编程》和《SCSI程序员指南》
& & & & & & & & srb-&Length=sizeof(SCSI_REQUEST_BLOCK);
& & & & & & & & srb-&Function=0;
& & & & & & & & srb-&DataBuffer=
& & & & & & & & srb-&DataTransferLength=BlockCount&&9;& & //sector size*number of sector
& & & & & & & & srb-&QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE;
& & & & & & & & srb-&SrbStatus=0;
& & & & & & & & srb-&ScsiStatus=0;
& & & & & & & & srb-&NextSrb=0;
& & & & & & & & srb-&SenseInfoBuffer=
& & & & & & & & srb-&SenseInfoBufferLength=sizeof(SENSE_DATA);
// & & & & & & & & if(MajorFunction==IRP_MJ_READ)
& & & & & & & & & & & & srb-&SrbFlags=SRB_FLAGS_DATA_IN;
& & & & & & & & & & & &
// & & & & & & & & if(MajorFunction==IRP_MJ_READ)
& & & & & & & & & & & & srb-&SrbFlags|=SRB_FLAGS_ADAPTER_CACHE_ENABLE;
& & & & & & & &
& & & & & & & & srb-&SrbFlags|=SRB_FLAGS_DISABLE_AUTOSENSE;
& & & & & & & & srb-&TimeOutValue=(srb-&DataTransferLength&&10)+1;
& & & & & & & & srb-&QueueSortKey=DiskP
& & & & & & & & srb-&CdbLength=10;
& & & & & & & & //srb-&Cdb[0] = 2*((UCHAR)MajorFunction+ 17);
& && &&&srb-&Cdb[0] = SCSIOP_READ;
& & & & & & & & srb-&Cdb[1] = srb-&Cdb[1] & 0x1F | 0x80;
& & & & & & & & srb-&Cdb[2] = (unsigned char)(DiskPos&&0x18)&0xFF;& & //
& & & & & & & & srb-&Cdb[3] = (unsigned char)(DiskPos&&0x10)&0xFF;& & //
& & & & & & & & srb-&Cdb[4] = (unsigned char)(DiskPos&&0x08)&0xFF;& & //
& & & & & & & & srb-&Cdb[5] = (UCHAR)DiskP& && && & //填写sector位置
& & & & & & & & srb-&Cdb[7] = (UCHAR)BlockCount&&0x08;
& & & & & & & & srb-&Cdb[8] = (UCHAR)BlockC
在线时间0 小时
TA的帖子TA的资源
& & & & & & & & KeInitializeEvent(&Event, NotificationEvent, FALSE);
& & & & & & & & irp=IoAllocateIrp(dev_object-&StackSize,0);
& & & & & & & & mdl=IoAllocateMdl(buffer, BlockCount&&9, 0, 0, irp);
& & & & & & & & Irp-&MdlAddress=
& & & & & & & & if(!mdl)
& & & & & & & & {
& & & & & & & & & & & & ExFreePool(srb);
& & & & & & & & & & & & ExFreePool(psense);
& & & & & & & & & & & & IoFreeIrp(irp);
& & & & & & & & & & & & return STATUS_INSUFFICIENT_RESOURCES;
& & & & & & & & }
& & & & & & & & //MmProbeAndLockPages(mdl,0,(MajorFunction==IRP_MJ_READ?0:1));
& & & & & & & & MmProbeAndLockPages(mdl,0,IoReadAccess);
& & & & & & & & srb-&OriginalRequest=
& & & & & & & & irp-&UserIosb=&
& & & & & & & & irp-&UserEvent=&E
& & & & & & & & irp-&IoStatus.Status=0;
& & & & & & & & irp-&rmation=0;
& & & & & & & & irp-&Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE;
& & & & & & & & irp-&AssociatedIrp.SystemBuffer=0;
& & & & & & & & irp-&Cancel=0;
& & & & & & & & irp-&RequestorMode=0;
& & & & & & & & irp-&CancelRoutine=0;
& & & & & & & & irp-&Tail.Overlay.Thread=PsGetCurrentThread();
& & & & & & & & isl=IoGetNextIrpStackLocation(Irp);
& & & & & & & & isl-&DeviceObject=dev_
& & & & & & & & //isl-&MajorFunction=IRP_MJ_SCSI;
& & & & & & & & isl-&Parameters.Scsi.Srb=
& & & & & & & & isl-&CompletionRoutine=IrpCompletionRoutine_0;
& & & & & & & & isl-&Context=
& & & & & & & & isl-&Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR;
& & & & & & & & status=IoCallDriver(pdx-&LowerDeviceObject,irp);
& & & & & & & & KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0);
在线时间0 小时
TA的帖子TA的资源
你之所以没有被检测出盘符,是因为你的过滤驱动是挂在{36FC9E60-C465-11CF-40000}下,而不是{4D36E967-E325-11CE-BFC1-0}。前者是USB Controller的GUID,后者是U盘这类Disk Device的Class GUID。
你的读写扇区的代码应该没有什么问题。有问题稍微调试一下应该没有什么大碍。
//MmProbeAndLockPages(mdl,0,(MajorFunction==IRP_MJ_READ?0:1));
//isl-&MajorFunction=IRP_MJ_SCSI;
这两条语句不应该注掉
在线时间0 小时
TA的帖子TA的资源
isl-&MajorFunction=IRP_MJ_SCSI;
这条语句如果不注释掉,会反复进入SCSI的派遣函数,不能读取U盘扇区
在线时间3 小时
TA的帖子TA的资源
我想知道当刚刚插入U盘但没有显示盘符时时能不能读取到磁盘的扇区?
也就是说,当程序执行到SCSI的派遣函数里的这行语句时,if (_wcsnicmp(DeviceObject-&AttachedDevice-&DriverObject-&DriverName.Buffer,L&\\Driver\\USBSTOR&,15)==0)
在这里构造srb能否读取到U盘扇区?
#pragma LOCKEDCODE
NTSTATUS DispatchForSCSI(IN PDEVICE_OBJECT fido, IN PIRP Irp)
& & KdPrint((DRIVERNAME & - Enter DispatchForSCSI \n&));
& & //获得设备扩展
& & & & PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido-&DeviceE
& & & & //获得I/O堆栈
& & & & PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
& & & & PDEVICE_OBJECT DeviceObject = pdx-&DeviceO
& & & & NTSTATUS
& & & & if (_wcsnicmp(DeviceObject-&AttachedDevice-&DriverObject-&DriverName.Buffer,L&\\Driver\\USBSTOR&,15)==0) //程序执行到这里,能读取到U盘扇区吗?
在线时间0 小时
TA的帖子TA的资源
读不读得到扇区,只取决于你是否向磁盘(这里是U盘)设备发送了IRP_MJ_SCSI,你的IRP没有该功能码肯定是有问题的,而且我在前面已经说了,你要把你的过滤驱动挂在Disk类驱动上面,这样你在CallDriver时比较容易直接发送该IRP给磁盘(U盘)设备。而且不存在什么IRP_MJ_SCSI重入问题。
在上述解决方案中,唯一需要考虑的是如何区别出普通磁盘还是U盘。这其实也很容易,发送IOCTL_STORAGE_QUERY_PROPERTY,就可以知道类型。
在线时间0 小时
TA的帖子TA的资源
在线时间0 小时
TA的帖子TA的资源
不好意思,前面的说法有一点问题。IRP_MJ_SCSI重入问题还是存在,不过这个问题可以用影设备之类的方式来解决。
在线时间0 小时
TA的帖子TA的资源
如何发送IOCTL_STORAGE_QUERY_PROPERTY?
要创建一个IRP传递下去吗?
小弟刚做这个不久,还请不吝赐教。
原来我的过滤驱动挂在Disk类驱动下面,但是重启容易蓝屏。
如果将过滤驱动挂在Disk类驱动上面,在那个派遣函数里禁用U盘?
在IRP_MJ_CREATE的派遣函数里吗?
在线时间12 小时
TA的帖子TA的资源
如果将过滤驱动挂在Disk类驱动上面,是不是要在{4D36E967-E325-11CE-BFC1-0}里加一个UpperFilters,是不是要和PartMgr放在一起?在PartMgr后面加一个空格然后将我的过滤驱动的名字填上?
在线时间0 小时
TA的帖子TA的资源
发送IOCTL_STORAGE_QUERY_PROPERTY和发送普通的IRP的方法是一样的,自己根据DDK文档的描述填写。
你挂在Disk下面也可以,只要按照我之前说的方法处理好U盘和普通磁盘的区别,以及IRP_MJ_SCSI的重入就好了。你之前蓝屏的原因有以下可能:
(1)没有处理IRP_MJ_SCSI的重入
(2)没有正确PassThrough IRP给下层设备。因为你的驱动挂在Disk Driver下面,所有磁盘的访问都会经过你的驱动,如果你的驱动没有正确把IRP传递到下层设备,则系统启动都会有问题(会读启动分区),蓝屏自然。
至于你说要在哪个函数里禁用,这个看你自己的选择了。你可以在PNP的START DEVICE例程里就禁用:
case IRP_MN_START_DEVICE:
&&//CallLowerDeviceDriver()
&&//SendSRBToRead()
在线时间0 小时
TA的帖子TA的资源
我想要实现的功能是先读取U盘扇区,找到我写入的标识,如果没有这个标识,则禁用U盘。所以我想不能在START DEVICE里直接禁用吧。
明天我再试验一下区分U盘和硬盘。
谢谢jintianyishiyeai
在线时间0 小时
TA的帖子TA的资源
我想在禁用U盘时,电脑里不会出现U盘的盘符,同时任务栏也不会出现U盘的图标,是不是将过滤驱动挂在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{36FC9E60-C465-11CF-40000}下,这样的效果最好。
记得前一段实验时如果挂载在disk的下面,没有盘符,但是任务栏里会有U盘的图标。
在线时间0 小时
TA的帖子TA的资源
我决定把过滤驱动放到disk的上面,但是和PartMgr放在一起会蓝屏,这是怎么回事?过滤驱动的启动类型应该是多少?0还是3?
我只是在代码里加入了IRP_MJ_CREATE的派遣函数
Powered by
逛了这许久,何不进去瞧瞧?IoAllocateIrp创建的IRP用IoFreeIrp删除蓝屏的问题
[问题点数:40分,结帖人yongbuyanbai88]
IoAllocateIrp创建的IRP用IoFreeIrp删除蓝屏的问题
[问题点数:40分,结帖人yongbuyanbai88]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
相关帖子推荐:
2013年1月 硬件/嵌入开发大版内专家分月排行榜第一2012年10月 硬件/嵌入开发大版内专家分月排行榜第一2012年9月 硬件/嵌入开发大版内专家分月排行榜第一2012年8月 硬件/嵌入开发大版内专家分月排行榜第一2012年7月 硬件/嵌入开发大版内专家分月排行榜第一2012年6月 硬件/嵌入开发大版内专家分月排行榜第一2012年5月 硬件/嵌入开发大版内专家分月排行榜第一2012年4月 硬件/嵌入开发大版内专家分月排行榜第一2012年3月 硬件/嵌入开发大版内专家分月排行榜第一2012年2月 硬件/嵌入开发大版内专家分月排行榜第一2012年1月 硬件/嵌入开发大版内专家分月排行榜第一2011年11月 硬件/嵌入开发大版内专家分月排行榜第一2011年10月 硬件/嵌入开发大版内专家分月排行榜第一2011年9月 硬件/嵌入开发大版内专家分月排行榜第一
2014年10月 硬件/嵌入开发大版内专家分月排行榜第二2014年2月 硬件/嵌入开发大版内专家分月排行榜第二2013年10月 硬件/嵌入开发大版内专家分月排行榜第二2013年8月 硬件/嵌入开发大版内专家分月排行榜第二2013年3月 硬件/嵌入开发大版内专家分月排行榜第二2012年12月 硬件/嵌入开发大版内专家分月排行榜第二2012年11月 硬件/嵌入开发大版内专家分月排行榜第二2011年12月 硬件/嵌入开发大版内专家分月排行榜第二
本帖子已过去太久远了,不再提供回复功能。

我要回帖

更多关于 星月挂瓷后还要盘吗 的文章

 

随机推荐