我的U盘过滤驱动程序为什么不能读取U盘扇区?

matrix2009 2009-10-14 03:50:10
最近一直在研究U盘过滤驱动,在这个版块发了不少贴,谢谢大家帮忙。
现在一个主要的问题是不能读取U盘扇区,试了很多办法,就是不行。
后来参考机器狗读写硬盘扇区的代码,加到我的代码里面,但是不论我怎么试都不能读取U盘扇区,真郁闷。
我把代码贴一下,劳烦大家再给我看看。先谢谢了。

ULONG AtapiReadWriteDisk(PDEVICE_OBJECT dev_object,ULONG MajorFunction, PVOID buffer,ULONG DiskPos, int BlockCount,PIRP Irp)
{
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;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) dev_object->DeviceExtension;
PDEVICE_OBJECT DeviceObject = pdx->DeviceObject;
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->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;

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] = SCSIOP_READ;
srb->Cdb[1] = 0x80;
srb->Cdb[2] = (unsigned char)(DiskPos>>0x18);
srb->Cdb[3] = (unsigned char)(DiskPos>>0x10);
srb->Cdb[4] = (unsigned char)(DiskPos>>0x08);
srb->Cdb[5] = (UCHAR)DiskPos; //填写sector位置
srb->Cdb[7] = BlockCount>>0x08;
srb->Cdb[8] = (UCHAR)BlockCount;

KeInitializeEvent(&Event, NotificationEvent, FALSE);
irp=IoAllocateIrp(DeviceObject->StackSize,0);
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=0;
irp->Cancel=0;
irp->RequestorMode=0;
irp->CancelRoutine=0;
irp->Tail.Overlay.Thread=PsGetCurrentThread(); //delete by scott

isl=IoGetNextIrpStackLocation(irp);
isl->DeviceObject=DeviceObject;
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;
}
...全文
397 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
A33228371 2011-08-29
  • 打赏
  • 举报
回复
我也终于搞定了。

联系方式 qq33228371
victorypiter 2010-11-24
  • 打赏
  • 举报
回复
楼主,能不能说下解决方案啊?我也想知道。。。
www2010mnx 2010-08-20
  • 打赏
  • 举报
回复
lz! 能不能说下解决方法啊!
angelfriend 2010-01-20
  • 打赏
  • 举报
回复
楼主加我QQ,想请教你读写U盘的问题~QQ120204126
angelfriend 2010-01-19
  • 打赏
  • 举报
回复
怎么搞定的~??
wwww2 2010-01-19
  • 打赏
  • 举报
回复
楼上能说下怎么搞定的吗?
matrix2009 2009-10-15
  • 打赏
  • 举报
回复
搞定了
matrix2009 2009-10-14
  • 打赏
  • 举报
回复
过滤驱动加载在注册表HKEY_LOCAL_MACHINE\SYSTEM\CurrentConrolSet\Control\Class\{4D36E967-E325-11CE-BFC1-08002BE10318}下,是一个下层过滤驱动。

在AtapiReadWriteDisk函数中,在几个位置
irp=IoAllocateIrp(DeviceObject->StackSize,0);
isl->DeviceObject=DeviceObject

分别试过pdx->Pdo,pdx->DeviceObject都不行,就差用pdx->LowerDeviceObject。
但是我觉得不能用pdx->LowerDeviceObject。因为这是下层驱动。
机器狗的代码里面的参数PDEVICE_OBJECT dev_object是硬盘设备对象吧。我觉得用pdx->Pdo就可以了,但是读不到U盘扇区。
其它的地方我觉得也不需要怎么修改吧。

请大家帮帮忙
matrix2009 2009-10-14
  • 打赏
  • 举报
回复
这是IRP_MJ_CREATE的派遣函数,在这里调用函数读取U盘扇区
#pragma LOCKEDCODE
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT fido, IN PIRP Irp)
{

PDEVICE_EXTENSION pdx;
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
ULONG DeviceType;

irpStack = IoGetCurrentIrpStackLocation(Irp);
pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;
PDEVICE_OBJECT DeviceObject = pdx->DeviceObject;

DeviceType = GetDeviceType(fido);
if (DeviceType == 7)
{
PVOID buffer;
buffer=ExAllocatePool(NonPagedPool,512);
RtlZeroMemory(buffer,512);

status = AtapiReadWriteDisk(fido,IRP_MJ_READ,buffer,1,1,Irp);//读取U盘扇区
if (NT_SUCCESS(status))
{
Irp->IoStatus.Status = STATUS_ACCESS_DENIED;
Irp->IoStatus.Information = 0;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_ACCESS_DENIED;
}
}
status = IoAcquireRemoveLock(&pdx->RemoveLock, Irp);
if (!NT_SUCCESS(status))
return CompleteRequest(Irp, status, 0);
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pdx->LowerDeviceObject, Irp);
IoReleaseRemoveLock(&pdx->RemoveLock, Irp);
return status;
}

这是AddDevice函数
NTSTATUS AddDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT pdo)
{ // AddDevice
KdPrint((DRIVERNAME " - Entering AddDevice: DriverObject %8.8lX\n", DriverObject));
//确保当前函数运行在分页内存中
PAGED_CODE();
NTSTATUS status;
PDEVICE_OBJECT fido;
ULONG DeviceType = 0;
DeviceType = GetDeviceTypeToUse(pdo);

//创建设备对象
status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL,
DeviceType, 0, FALSE, &fido);
//判断是否成功创建设备对象
if (!NT_SUCCESS(status))
{ // can't create device object
KdPrint((DRIVERNAME " - IoCreateDevice failed - %X\n", status));
//如果不能成功创建设备对象就返回
return status;
} // can't create device object

//获得设备扩展
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fido->DeviceExtension;

do
{ // finish initialization
//初始化自旋锁
IoInitializeRemoveLock(&pdx->RemoveLock, 0, 0, 0);
pdx->DeviceObject = fido;
pdx->Pdo = pdo;
//将过滤驱动附加在底层驱动之上
PDEVICE_OBJECT fdo = IoAttachDeviceToDeviceStack(fido, pdo);
if (!fdo)
{ // can't attach
KdPrint((DRIVERNAME " - IoAttachDeviceToDeviceStack failed\n"));
status = STATUS_DEVICE_REMOVED;
break;
} // can't attach

//记录底层驱动
pdx->LowerDeviceObject = fdo;
//由于不知道底层驱动是直接IO还是BufferIO,因此将标志都置上
fido->Flags |= fdo->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO | DO_POWER_PAGABLE);
// Clear the "initializing" flag so that we can get IRPs
fido->Flags &= ~DO_DEVICE_INITIALIZING;
} while (FALSE); // finish initialization

if (!NT_SUCCESS(status))
{ // need to cleanup
//如果没有成功,则从设备堆栈中删除设备
if (pdx->LowerDeviceObject)
IoDetachDevice(pdx->LowerDeviceObject);
IoDeleteDevice(fido);
} // need to cleanup

return status;
} // AddDevice

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧