Leonsoft
驱动小牛
驱动小牛
  • 注册日期2003-05-08
  • 最后登录2012-08-11
  • 粉丝1
  • 关注0
  • 积分21分
  • 威望281点
  • 贡献值1点
  • 好评度103点
  • 原创分0分
  • 专家分0分
阅读:1657回复:0

一个很奇怪的问题,各位高手请进, 送100分。

楼主#
更多 发布于:2005-08-03 11:01
我正在port我们公司一个读卡器driver到Windows XP 64bit上,其中有一个filter driver,当S1或S3,或者S4回来时候,用来保存和配置一些寄存器的。我们的读卡器是被看作一个PCMCIA上的一个ATA device,
这个filter driver被加载到两个PCMCIA和读卡器driver上。
filter driver主要做的事情就是,在处理IRP_MJ_POWER时候,读写一些寄存器的。
在访问寄存器的时候,我用了WDM方式去访问,就是自己发送IRP去做。在Windows XP 32bit下,工作的很好,但是在64bit,电脑S4(休眠)回来后,有时侯会停在那里(进度条刚走完)死机,但不蓝屏。下面是我访问寄存器的代码:

ULONG ReadDWord( PDEVICE_OBJECT DeviceObject,
                             USHORT Offset )
{
       ULONG RawData = 0;
       MBXConfigRegisterBufferRead( DeviceObject, &RawData,
                                           Offset&0xFC, sizeof(ULONG) );
       return RawData;
}


NTSTATUS MBXConfigRegisterBufferRead(
                           PDEVICE_OBJECT  DeviceObject, // target device object
              PVOID   buffer,        //the read buffer
                           ULONG  offset,           //buffer offset
              ULONG  Length        //the length of buffer
       )

{
    PIRP               pIrp = NULL;
       KEVENT             event;
    NTSTATUS           status;
    PIO_STACK_LOCATION stack = NULL;
    PDEVICE_OBJECT     AttachedPDO = NULL;
    IO_STATUS_BLOCK    ioSattus;
    PDEVICE_EXTENSION  pdx = NULL ;
    ULONG              Transferred;
              
    pdx =(PDEVICE_EXTENSION)DeviceObject->DeviceExtension;

    KdPrint((" Enter MBXConfigRegisterBufferRead \n"));
    if( KeGetCurrentIrql() < DISPATCH_LEVEL )
   {
         KdPrint(("KeGetCurrentIrql() < DISPATCH_LEVEL\n"));
         RtlZeroMemory( buffer,Length);
    
         KeInitializeEvent( &event, NotificationEvent, FALSE );

         //
         //get the pdo of function 0!
         //
         AttachedPDO = pdx->NextLowerDriver;//LowerDeviceObject;
              if( NULL == AttachedPDO )
              {
                     KdPrint(("Error! The AttachedPDO is NULL"));
                     return STATUS_UNSUCCESSFUL;
              }
              //
              //allocate a irp for next stack.
              //
              KdPrint(("Begin to build IRP \n"));              
              pIrp = IoBuildSynchronousFsdRequest (
                                   IRP_MJ_PNP,
                                   AttachedPDO,
                                   NULL,
                                   0,
                                   NULL,
                                   &event,
                                   &ioSattus
                                   );
              if ( pIrp == NULL )
              {
                     KdPrint(("Failed to build IRP \n"));      
                     return( STATUS_INSUFFICIENT_RESOURCES );
              }

              //get the next pci stack!
              stack = IoGetNextIrpStackLocation( pIrp );

              // Fill the IRP
              pIrp->IoStatus.Status                        = STATUS_NOT_SUPPORTED;
              stack->MajorFunction                         = IRP_MJ_PNP;
              stack->MinorFunction                         = IRP_MN_READ_CONFIG;
              stack->Parameters.ReadWriteConfig.WhichSpace = 0;
              stack->Parameters.ReadWriteConfig.Buffer     = buffer;
              stack->Parameters.ReadWriteConfig.Offset     = offset;
              stack->Parameters.ReadWriteConfig.Length     = Length;
      
              //
              // this step will call the function 0 of pcmcia bus driver.
              //
              KdPrint(("Begin to send IRP \n"));      
              status = IoCallDriver( AttachedPDO, pIrp );
              KdPrint(("Have sent IRP \n"));      
              if(!NT_SUCCESS(status))
              {
                     KdPrint(("iocaller failed!"));
              }
              if (status == STATUS_PENDING)
              {
              // Wait for completion
                     KdPrint(("Wait the IRP completion \n"));      
                     KeWaitForSingleObject( &event, Executive, KernelMode, FALSE, NULL );
                     status = pIrp->IoStatus.Status;
              }
              KdPrint(("Read %x = %x\n",offset, *((PULONG)buffer)));                    
       }
       else
       {
              //irp level>=dispatch_level
              KdPrint(("KeGetCurrentIrql() >= DISPATCH_LEVEL \n"));      
              Transferred = pdx->BusInterfaceStandard.GetBusData(
                                                        pdx->BusInterfaceStandard.Context,
                                                        PCI_WHICHSPACE_CONFIG,
                                                        buffer,
                                                        offset,
                                                        Length
                                                        );

              KdPrint(("Read %x = %x\n",offset, *((PULONG)buffer)));

              if( Transferred == Length )
              {
                     KdPrint(("KeGetCurrentIrql() = DISPATCH_LEVEL---success\n"));
                     status = STATUS_SUCCESS;
              }
              else
              {
                     KdPrint(("KeGetCurrentIrql() = DISPATCH_LEVEL---failed\n"));
                     status = STATUS_UNSUCCESSFUL;              
              }
       }
       KdPrint((" Exit MBXConfigRegisterBufferRead\n"));
       return status;      
}


在Windows 64bit 下,当从s4状态回来后,有时候call完 IoCallDriver后,系统就停在那里了。是把IRP发送到下层device driver后,下层driver在处理我发送的IRP出问题了,因为没有打印出Have sent IRP!  我一直都不知道其中的原因,因为在32bit没有问题,在64bit下,S1和S3状态下回来也没有什么问题。
有哪位高手可以指点下啊,谢谢。
I will do the best with what the God gave me.
游客

返回顶部