阅读:2927回复:5
U盘读过滤的问题,创建Irp
我的在usbstor.sys上加载了我的过滤驱动,当插入U盘的时候就开启驱动,建立了一个设备,现在是我想在我的设备捕获读命令的时候,发一个IRP来读我的u盘,怎么做???我知道U盘的读命令到了我的设备的时候都成了SCSI命令了。
我用iobuildsynchronousfsdrequest发了irp_mj_read的IRP下去,但是每次都是失败~~~~~ 到了USBSTOR.SYS之后是不是不能用iobuildsynchronousfsdrequest来发irp了,是不是用ioallocateirp才行~~请高人指点 |
|
沙发#
发布于:2010-01-20 23:16
ULONG AtapiReadWriteDisk(PDEVICE_OBJECT dev_object,ULONG MajorFunction,PVOID buffer,ULONG DiskPos,int BlockCount,PIRP Irp)
{ PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) dev_object->DeviceExtension; NTSTATUS status; PSCSI_REQUEST_BLOCK srb; PSENSE_DATA sense; KEVENT Event; PIRP irp; PMDL mdl; IO_STATUS_BLOCK isb; PIO_STACK_LOCATION isl; PVOID psense; int count=8; while(1){ srb=(PSCSI_REQUEST_BLOCK)ExAllocatePool(NonPagedPool,sizeof(SCSI_REQUEST_BLOCK)); if(!srb) break; sense=(PSENSE_DATA)ExAllocatePool(NonPagedPool,sizeof(SENSE_DATA)); psense=sense; if(!sense) break; memset(srb,0,sizeof(SCSI_REQUEST_BLOCK)); memset(sense,0,sizeof(SENSE_DATA)); srb->Length=sizeof(SCSI_REQUEST_BLOCK);//更多关于srb,请看《SCSI 总线和IDE接口:协议、应用和编程》和《SCSI程序员指南》 srb->Function=0; srb->DataBuffer=buffer; srb->DataTransferLength=BlockCount*512;//sector size*number of sector srb->QueueAction=SRB_FLAGS_DISABLE_AUTOSENSE; srb->SrbStatus=0; srb->ScsiStatus=0; srb->NextSrb=0; srb->SenseInfoBuffer=sense; srb->SenseInfoBufferLength=sizeof(SENSE_DATA); if(MajorFunction==IRP_MJ_READ) srb->SrbFlags=SRB_FLAGS_DATA_IN; else srb->SrbFlags=SRB_FLAGS_DATA_OUT; 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=DiskPos; 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)DiskPos; //填写sector位置 srb->Cdb[7]=(UCHAR)BlockCount>>0x08; srb->Cdb[8]=(UCHAR)BlockCount; //By:Eros412 KeInitializeEvent(&Event, NotificationEvent, FALSE); irp=IoAllocateIrp(dev_object->StackSize,false); mdl=IoAllocateMdl(buffer, BlockCount*512, 0, 0, irp); irp->MdlAddress=mdl; if(!mdl){ ExFreePool(srb); ExFreePool(psense); IoFreeIrp(irp); return STATUS_INSUFFICIENT_RESOURCES; } MmProbeAndLockPages(mdl,0,(MajorFunction==IRP_MJ_READ?IoReadAccess:IoWriteAccess)); srb->OriginalRequest=irp; irp->UserIosb=&isb; irp->UserEvent=&Event; irp->IoStatus.Status=0; irp->IoStatus.Information=0; irp->Flags=IRP_SYNCHRONOUS_API|IRP_NOCACHE; irp->AssociatedIrp.SystemBuffer=mdl; irp->Cancel=0; irp->RequestorMode=0; irp->CancelRoutine=0; irp->Tail.Overlay.Thread=PsGetCurrentThread(); isl=IoGetNextIrpStackLocation(irp);//by zenghui设置下一层的IRP,ISL的内容, isl->DeviceObject=dev_object; isl->MajorFunction=IRP_MJ_SCSI; isl->Parameters.Scsi.Srb=srb; // isl->CompletionRoutine=IrpCompletionRoutine_0; isl->Context=srb; isl->Control=SL_INVOKE_ON_CANCEL|SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR; IoSetCompletionRoutine(irp,IrpCompletionRoutine_0,srb,1,1,1); status=IoCallDriver(pdx->LowerDeviceObject,irp); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, 0); if(srb->SenseInfoBuffer!=psense&&srb->SenseInfoBuffer) ExFreePool(srb->SenseInfoBuffer); ExFreePool(srb); ExFreePool(psense); if ( status >= 0 || !count ) return status; DbgPrint("Send XXX Failed..%08x\r\n", status); KeStallExecutionProcessor(1u); --count; } return STATUS_INSUFFICIENT_RESOURCES; } 是用这个来创建一个IRP来给我的下层驱动,我的驱动加载在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR下边的一个U盘建立的项上,现在就是想根据我发的这个IRP读到U盘上的扇区来判断是否要禁用U盘,一直没有成功,请高人指点下,不知道思路有没有错! |
|
板凳#
发布于:2010-01-20 23:19
希望大家能帮帮忙,搞了好多天了,但是一直没有头绪~~~
|
|
地板#
发布于:2010-01-25 17:11
还是没有人帮忙吗?唉~~
|
|
地下室#
发布于:2010-03-25 17:52
这里的高手好象不热情! 基本上问题都没人回答? 是不是因为没有经济驱动?
找找哪儿有收费的技术支持站点. |
|
|
5楼#
发布于:2010-03-26 14:58
USBSTOR已经不处理IRP_MJ_READ请求了,只能通过IRP_MJ_SCSI来发送SCSI命令来读写数据。
过滤驱动中可以用IoBuildDeviceIoControlRequest来发送同步请求到下级驱动,比用IoAllocateIrp要方便得多 |
|