sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3315回复: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
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-01-16 15:50
IoGetNextIrpStackLocation是可用的吗?为什么要在这里做这样的事呢?
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-01-16 16:08
我把
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;

都注释掉了就不会黑屏,而留下IoBuildSynchronousFsdRequest()不注释仍然会导致黑屏啊(当然后面的IoCallDriver()啊都去掉了)。会是哪里的问题呢?我都要急死了。

我的程序流程是这样的,在DriverEntry中IoRegisterPlugPlayNotification注册监听某设备插拔,在其回调函数中,监测到此设备插入时,调用这个函数创建一个IRP发给它,可能的问题在哪里呢?
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-01-16 16:18
这样啊,呵呵.:):):)

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

你可以试试Build一个MJ_PNP给它,如果一样黑,那说明是别的问题,如果成功,十有八九是因为那个DeviceObject没启动.
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-01-16 16:38
太感谢你了,果然是问题所在。那我怎么确定底层设备启动了没有呢,它的驱动我没有源码,只有Read和Write的接口。我是否是应该在监测到插入后做一个等待呢,还是如何?
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于: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分
6楼#
发布于: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分
7楼#
发布于: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分
8楼#
发布于: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分
9楼#
发布于: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分
10楼#
发布于: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分
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-18 10:43
呵呵,我已经把IoGetNextIrpStackLocation()那部分去掉了。明天回家过年了,春节过了再来整。春节快乐!
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-01-18 14:28
OK,就先别想这些问题了,过个好年先. :):):)
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于: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分
15楼#
发布于: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分
16楼#
发布于:2004-02-04 09:03
在IoRegisterPlugPlayNotification()的回调函数中,我用IoGetDeviceObjectPointer()得到DeviceObject的。
sinking
驱动牛犊
驱动牛犊
  • 注册日期2003-08-18
  • 最后登录2006-02-06
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2004-02-09 08:50
我找到了底层驱动的源代码,发现在创建IRP_MJ_READ/IRP_MJ_WRITE以前,底层驱动已经收到了系统发出的MN_START_DEVICE这个IRP, 但是我创建IRP_MJ_READ/IRP_MJ_WRITE,仍然黑屏,555。。。
cockliujun
驱动牛犊
驱动牛犊
  • 注册日期2003-08-21
  • 最后登录2008-06-25
  • 粉丝0
  • 关注0
  • 积分860分
  • 威望16点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2004-03-18 18:51
read 和 write 时要填 StartingOffset 参数,而且它是个指针,不能填 0。
lnt_ddn
驱动牛犊
驱动牛犊
  • 注册日期2004-03-06
  • 最后登录2012-02-02
  • 粉丝0
  • 关注0
  • 积分37分
  • 威望5点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2004-03-20 20:36
pIrpStack->FileObject=fo;
fo是用户模式应用程序传给你的fileobject,
好像必须设置该域
上一页
游客

返回顶部