sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3317回复:21

求助:创建IRP时黑屏

楼主#
更多 发布于:2004-01-16 11:50
我的驱动中要创建IRP_MJ_WRITE, IRP_MJ_READ,发往低层驱动。但在创建IRP时,系统就黑屏了。请大侠指点,原程序如下:

NTSTATUS
WD_SendtoLower(IN PDEVICE_OBJECT DeviceObject, IN OUT BYTE *rwbuf, IN OUT PULONG len, IN BOOLEAN write)
{
        NTSTATUS status;
        KEVENT   kevent;
        PIRP     pIrp;
        IO_STATUS_BLOCK IoStatus;
        PIO_STACK_LOCATION  pIrpStack;
                
        PAGED_CODE();
        ASSERT(DeviceObject != NULL);

        KeInitializeEvent(&kevent, SynchronizationEvent, false);
        if(write)
        {
         pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, rwbuf, *len, 0, &kevent, &IoStatus);
        
         if(pIrp == NULL)
         {
         KdPrint((\"\\t%sWD_CardComand : Can\'t build the Write Irp\\n\",HEAD));
         return STATUS_INSUFFICIENT_RESOURCES;
         }

         pIrpStack = IoGetNextIrpStackLocation(pIrp);
         pIrpStack->MajorFunction = IRP_MJ_WRITE;
pIrpStack->Parameters.Write.Length = *len;
            pIrpStack->Parameters.Write.ByteOffset.QuadPart = 0;
        }
        else
        {
         pIrp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, rwbuf, *len, 0, &kevent, &IoStatus);
         if(pIrp == NULL)
         {
         KdPrint((\"\\t%sWD_CardComand : Can\'t build the Read Irp\\n\",HEAD));
         return STATUS_INSUFFICIENT_RESOURCES;
         }
         pIrpStack = IoGetNextIrpStackLocation(pIrp);
         pIrpStack->MajorFunction = IRP_MJ_READ;
pIrpStack->Parameters.Read.Length = *len;
           pIrpStack->Parameters.Read.ByteOffset.QuadPart = 0;
        }
        
        
        
        status = IoCallDriver(DeviceObject, pIrp);
        if (status == STATUS_PENDING)
        {
       KeWaitForSingleObject( &kevent, Executive, KernelMode, FALSE, NULL );
         status = IoStatus.Status;
     }
                return status;
    
}

最新喜欢:

ljmmaryljmmar... virminvirmin
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-12 11:32
检查下你得到的pTargetDeviceObject是SCSI设备的DeviceObject吗?
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-04-09 15:06
以下为代码拷贝,我用IoGetDeviceObjectPointer得到了一个scsi设备,此时想通过该设备句柄向scsi设备发送irp,但在IoCallDriver时老出错:
NTSTATUS status = 0;
UNICODE_STRING uniNtNameString;
PDEVICE_OBJECT pTargetDeviceObject = NULL;
PFILE_OBJECT pTargetFileObject = NULL;

RtlInitUnicodeString( &uniNtNameString, DeviceName);//SCSI_DEVICE_NAME );

status = IoGetDeviceObjectPointer(
IN &uniNtNameString,
IN FILE_ALL_ACCESS,
OUT &pTargetFileObject,
OUT &pTargetDeviceObject
);
if( !NT_SUCCESS(status) )
{
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return( status );
}
DbgPrint("Scsi设备句柄:%x,文件句柄:%xn",pTargetDeviceObject,pTargetFileObject);
if(!pTargetDeviceObject)
return status ;

PIRP pIrp=NULL;
KEVENT keIoctlComplete;
IO_STATUS_BLOCK ioSb;
SRB_SET_DEVOBJ iobuf;
UINT ubuffer;
PIO_STACK_LOCATION pIrpStack;

KeInitializeEvent(&keIoctlComplete,NotificationEvent,FALSE);

iobuf.SrbCtrl.HeaderLength = sizeof(SRB_IO_CONTROL);
FILLSIGNATURE(iobuf.SrbCtrl.Signature);
iobuf.SrbCtrl.Timeout = DEFAULT_TIMEOUT;
iobuf.SrbCtrl.ControlCode = 1;
iobuf.SrbCtrl.ReturnCode = 0xFFFFFFFF;
iobuf.SrbCtrl.Length = sizeof(gDeviceObject);
iobuf.pDeviceObj=gDeviceObject;

pIrp=IoBuildDeviceIoControlRequest(
IOCTL_SCSI_MINIPORT,
pTargetDevObj,
&iobuf,
sizeof(iobuf),
&ubuffer,
sizeof(ubuffer),
FALSE,
&keIoctlComplete,
&ioSb);
IoCallDriver(pTargetDevObj,pIrp); (出错处,缺页错误)

KeWaitForSingleObject(&keIoctlComplete,Executive,KernelMode,FALSE,NULL);

DbgPrint("Send Successn");




在scsi设备端,我使用了如下处理代码
DbgPrint("Get IoCtl_test eventn");
PIRP Pirp=(PIRP)Srb->OriginalRequest;
Pirp->IoStatus.Status=STATUS_SUCCESS;
Pirp->IoStatus.Information=0;


请大虾救命阿,搞了好久了
lnt_ddn
驱动牛犊
驱动牛犊
  • 注册日期2004-03-06
  • 最后登录2012-02-02
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-03-20 20:36
pIrpStack->FileObject=fo;
fo是用户模式应用程序传给你的fileobject,
好像必须设置该域
cockliujun
驱动牛犊
驱动牛犊
  • 注册日期2003-08-21
  • 最后登录2008-06-25
  • 粉丝0
  • 关注0
  • 积分860分
  • 威望16点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-03-18 18:51
read 和 write 时要填 StartingOffset 参数,而且它是个指针,不能填 0。
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-02-09 08:50
我找到了底层驱动的源代码,发现在创建IRP_MJ_READ/IRP_MJ_WRITE以前,底层驱动已经收到了系统发出的MN_START_DEVICE这个IRP, 但是我创建IRP_MJ_READ/IRP_MJ_WRITE,仍然黑屏,555。。。
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-02-04 09:03
在IoRegisterPlugPlayNotification()的回调函数中,我用IoGetDeviceObjectPointer()得到DeviceObject的。
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-02-03 21:23
IRP_MN_START_DEVICE应该由PnP Manager发出,你最好不要自己做。

还有一个问题,我一直没问你那个DeviceObject是怎么得到的?PnP Notification应该不会给你这个对象吧?
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-02-02 15:37
我现在在我的驱动中自己创建了一个同步的IRP_MN_START_DEVICE,发给下层驱动,其也返回成功了。是否证明该DeviceObject已经启动了呢?但是我创建IRP_READ, IRP_WRITE还是黑屏。郁闷。。。 :(
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-01-18 14:28
OK,就先别想这些问题了,过个好年先. :):):)
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-01-18 10:43
呵呵,我已经把IoGetNextIrpStackLocation()那部分去掉了。明天回家过年了,春节过了再来整。春节快乐!
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-01-17 15:37
是有点奇怪... ...

一般情况下,只有PNP之类的IRP才需要IoGetNextIrpStackLocation(因为需要自己填写MinorFunction),如果你是MJ_READ或MJ_WRITE的话,只要在IoBuildSynchronousFsdRequest给出正确的参数(i.e. Buffer, Length, StartOffset), 然后就可以直接IoCallDriver了,用不着再去IoGetNextIrpStackLocation,因为Stack Location已经由系统帮你设置好了.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-01-17 14:41
不要这样撒,你已经帮了我很大的忙了,有些东东记不清了也很正常三。不要这么客气嘛。

我按照你说的做了,果然他好像没有处理IRP_MN_QUERY_PNP_DEVICE_STATE,看来我只有等写那个驱动的哥们过完年回来再说了。BTW,一个很奇怪的现象,我发了这个IRP给下层后,在发IRP_MJ_WRITE就不会黑屏了,但是建IRP_MJ_READ还是黑屏,真是奇怪了啊 :o :o :o
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-01-17 14:05
Oops!!!

你是对的,我给搞错乐,对不起. :(

是用IoBuildSynchronousFsdRequest,完乐用IoGetNextIrpStackLocation.

对不起. :(:(:(

[编辑 -  1/17/04 by  cool-net]
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-01-17 13:53
DDK的文档不是说IRP_MJ_PNP用IoBuildSynchronousFsdRequest()建吗?为什么要用IoBuildDeviceIoControlRequest()去建啊,他不是用来建IRP_MJ_DEVICE_CONTROL的IRP的么?不明白的说,迷茫
PIRP
  IoBuildSynchronousFsdRequest(
  IN ULONG  MajorFunction,
  IN PDEVICE_OBJECT  DeviceObject,
  IN OUT PVOID  Buffer  OPTIONAL,
  IN ULONG  Length  OPTIONAL,
  IN PLARGE_INTEGER  StartingOffset  OPTIONAL,
  IN PKEVENT  Event,
  OUT PIO_STATUS_BLOCK  IoStatusBlock
  );
IoBuildSynchronousFsdRequest allocates and builds an IRP to be sent synchronously to lower driver(s).

Parameters
MajorFunction
Specifies the major function code, one of IRP_MJ_PNP, IRP_MJ_READ, IRP_MJ_WRITE, IRP_MJ_FLUSH_BUFFERS, or IRP_MJ_SHUTDOWN.
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-01-17 12:48
对于PNP,你要用IoBuildDeviceIoControlRequest而不是IoBuildXXXXXXFsdRequest,用IoBuildDeviceIoControlRequest完了直接IoCallDriver就行了,不用理会Stack location.

对于IRP_MN_QUERY_PNP_DEVICE_STATE,inputBuffer和outputBuffer都为NULL,返回后检查你给的那个IoStatusBlock里的内容,Status为STATUS_SUCCESS时,Information里是一个PNP_DEVICE_STATE bitmask.

重申一下,驱动对IRP_MN_QUERY_PNP_DEVICE_STATE是Optional的,所以这种方式未必可用.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-01-17 09:58
谢谢你的指教。但是我还是有些不太明白,如果我不把我驱动的DeviceObject用IoAttachDeviceToDeviceStack()加入底层设备的IRP栈的话,那么我创建IRP_MN_QUERY_PNP_DEVICE_STATE这个IRP后,像要设置那个PIO_STACK_LOCATION的话,应该用IoGetNextIrpStackLocation()还是IoGetCurrentIrpStackLocation()。创建后,用IoCallDriver()发给底层设备,是根据返回的NTSTATUS来判断设备的状态吗?我发下去IRP还可以被我的驱动检查吗?
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-01-16 18:44
这个... ...Kernel Mode的PnPNotification我还真没用过,不过我想你是不是可以先Build一个MJ_PNP->IRP_MN_QUERY_PNP_DEVICE_STATE下去看看设备状态(但是,不幸的是驱动对这个Minor Code的支持是Optional的),也许还有别的什么方法(比如你可以Attach到那个DeviceObject上去,这样你可以收到它的MN_START_DEVICE),你可以试试先。
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-01-16 16:38
太感谢你了,果然是问题所在。那我怎么确定底层设备启动了没有呢,它的驱动我没有源码,只有Read和Write的接口。我是否是应该在监测到插入后做一个等待呢,还是如何?
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-01-16 16:18
这样啊,呵呵.:):):)

在调用IoBuildSynchronousFsdRequest之前你可能得先确定那个DeviceObject已经被启动了(就是已经收到MN_START_DEVICE了),否则你Build MJ_READ或WRITE恐怕不行吧?

你可以试试Build一个MJ_PNP给它,如果一样黑,那说明是别的问题,如果成功,十有八九是因为那个DeviceObject没启动.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
上一页
游客

返回顶部