shlei20
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2003-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1257回复:4

usb驱动程序中的一些问题。

楼主#
更多 发布于:2002-04-18 11:17
  我在编制的驱动程序中,driverEntry中的dispatch函数如下:
 
   DriverObject->MajorFunction[IRP_MJ_PNP]=YH_DispatchPnp;

DriverObject->MajorFunction[IRP_MJ_POWER]=YH_DispatchPower;

DriverObject->MajorFunction[IRP_MJ_CREATE]=YH_Create;

DriverObject->MajorFunction[IRP_MJ_CLOSE]=YH_Close;

DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=YH_ProcessIOCTL;


编译安装成功后,应用程序通过API 函数DeviceIoControl对YH_ProcessIOCTL调用,却总是出现蓝屏。而YH_Create,YH_Close
都没有问题。

   现在想知道的是怎么会出现这样的问题呢?怎么解决?
LIUTANG
驱动大牛
驱动大牛
  • 注册日期2001-03-30
  • 最后登录2020-12-27
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望58点
  • 贡献值0点
  • 好评度12点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-04-18 12:45
跟踪一下,肯定是你哪句代码有问题,或者把你的处理函数贴出来看一下看有没有人能找出来哪里错了。
jeffhu
驱动牛犊
驱动牛犊
  • 注册日期2002-02-21
  • 最后登录2005-09-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-18 15:04
一般是内存缺页,在不合适的中断级别使用了什么
用softice一跟就清楚了
hehe
shlei20
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2003-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-04-18 15:39
贴出部分原码:

NTSTATUS
YH_ProcessIOCTL( IN PDEVICE_OBJECT        fdo,
IN PIRP                  Irp)
{  
NTSTATUS               ntStatus;
PDEVICE_EXTENSION      pdx=fdo->DeviceExtension;
PIO_STACK_LOCATION     irpStack,nextStack;

PVOID                  ioBuffer;
ULONG                  inputBufferLength;
ULONG                  outputBufferLength;
ULONG                  ioControlCode;

ULONG                  length;
PUCHAR                 pch;

Evk_KdPrint((\"Enter IRP_MJ_DEVICE_CONTROL\\n\"));

if(!fdo)
return HCompleteRequest(Irp,STATUS_DELETE_PENDING,0);

//
    // Get a pointer to the current location in the Irp. This is where
    //     the function codes and parameters are located.
    //
    // IoGetCurrentIrpStackLocation returns a pointer to the caller\'s
    // stack location in the given IRP.

irpStack=IoGetCurrentIrpStackLocation(Irp);

Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;

ioBuffer=Irp->AssociatedIrp.SystemBuffer;
inputBufferLength=irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputBufferLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
    ioControlCode=irpStack->Parameters.DeviceIoControl.IoControlCode;

//
//handle IOCTLS from user mode
    //
    
switch(ioControlCode)
{
    case IOCTL_YH_RESETPIPE:
 {
 ULONG pipeNum=*((PULONG)ioBuffer);
 Irp->IoStatus.Status=YH_ResetPipe(fdo,pipeNum);
 }
 break;
 case IOCTL_YH_ABORTPIPE:
 {  
int pipenum=*((PULONG)ioBuffer);
    YH_AbortPipe(fdo,
            (USBD_PIPE_HANDLE)pdx->Interface->Pipes[pipenum].PipeHandle);
   Irp->IoStatus.Status=STATUS_SUCCESS;
   Irp->IoStatus.Information=0;

 }
 break;

 case IOCTL_EVK_BULK_READ:
 case IOCTL_EVK_BULK_WRITE:
 {  
             Irp->IoStatus.Status=YH_Read_Write(fdo,Irp);
 }
 break;
 case IOCTL_EVK_GET_DRIVER_VERSION:
 {
 PEVK_DRIVER_VERSION version = (PEVK_DRIVER_VERSION) ioBuffer;

            if (outputBufferLength >= sizeof(EVK_DRIVER_VERSION))
            {
               version->MajorVersion = EVK_MAJOR_VERSION;
               version->MinorVersion = EVK_MINOR_VERSION;
               version->BuildVersion = EVK_BUILD_VERSION;

               Irp->IoStatus.Status = STATUS_SUCCESS;
               Irp->IoStatus.Information = sizeof(EVK_DRIVER_VERSION);
            }
            else
            {
               Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
            }
 }
 break;

 default:
   Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
}
HUnLockDevice(fdo);

   ntStatus = Irp->IoStatus.Status;

   IoCompleteRequest (Irp,IO_NO_INCREMENT);

   return ntStatus;  

}



下面是其中IOCTL_EVK_BULK_READ 和IOCTL_EVK_BULK_WRITE
的处理:


NTSTATUS
YH_Read_Write(IN PDEVICE_OBJECT fdo,
 IN PIRP           Irp)
{

   PDEVICE_EXTENSION         pdx=fdo->DeviceExtension;
   PIO_STACK_LOCATION        irpStack=IoGetCurrentIrpStackLocation(Irp);
   NTSTATUS                  ntStatus=STATUS_SUCCESS;
   PBULK_TRANSFER_CONTROL    bulkControl=(PBULK_TRANSFER_CONTROL)Irp->AssociatedIrp.SystemBuffer;
   ULONG                     bufferLength=irpStack->Parameters.DeviceIoControl.OutputBufferLength;
   PURB                      urb=NULL;
   ULONG                     urbSize=0;
   ULONG                     transferFlags=0;

   PUSBD_INTERFACE_INFORMATION    interfaceInfo=NULL;
   PUSBD_PIPE_INFORMATION         pipeInfo=NULL;
   USBD_PIPE_HANDLE               pipeHandle=NULL;

   Evk_KdPrint((\"Enter YH_Read_Write\\n\"));

   //valify the selected pipe is valid and get a handle to it.
   //if anything is wrong ,return an error

   interfaceInfo=pdx->Interface;
   if(!interfaceInfo)
   {
  Evk_KdPrint((\"YH_Read_Write() has no interface info -exiting\"));
  return STATUS_UNSUCCESSFUL;
   }

   if(bulkControl->pipeNum>interfaceInfo->NumberOfPipes)
   {
  Evk_KdPrint((\"YH_Read_Write() invalid pipe\"));
  return STATUS_INVALID_PARAMETER;
   }

   pipeInfo=&(interfaceInfo->Pipes[bulkControl->pipeNum]);

   if(!((pipeInfo->PipeType==UsbdPipeTypeBulk)||
   (pipeInfo->PipeType==UsbdPipeTypeInterrupt)))
   {
  Evk_KdPrint((\"YH_Read_Write() invalid pipe - Exiting\\n\"));
  return STATUS_INVALID_PARAMETER;
   }

   pipeHandle=pipeInfo->PipeHandle;
    
   if(!pipeHandle)
   {
Evk_KdPrint((\"YH_Read_Write() invalid pipe-Exiting\\n\"));
return STATUS_UNSUCCESSFUL;
   }

   if(bufferLength>pipeInfo->MaximumPacketSize)
   {
  Evk_KdPrint((\"YH_Read_Write() invalid transfer size - Exiting\\n\"));
      return STATUS_INVALID_PARAMETER;
   }

   //
   //allocate and fill in the usb request
   //
   urbSize=sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER);

   urb=ExAllocatePool(NonPagedPool,urbSize);

   if(!urb)
   {
  Evk_KdPrint((\"YH_Read_Write() unable to allocate urb--exiting\\n\"));
  return STATUS_NO_MEMORY;
   }

   transferFlags=USBD_SHORT_TRANSFER_OK;

   //
   //get direction info from endpoints address
   //
 if(USB_ENDPOINT_DIRECTION_IN(pipeInfo->EndpointAddress))
  transferFlags|=USBD_TRANSFER_DIRECTION_IN;

  UsbBuildInterruptOrBulkTransferRequest(urb,
                                     (USHORT) urbSize,
 pipeHandle,        //pipeHandle
 NULL,              //transferBuffer
 Irp->MdlAddress,   //transferBufferMDL
 bufferLength,      //transferBufferLength
 transferFlags,     //transferFlags
 NULL               //link
 );

   //call the USB stack
   ntStatus=Evk_CallUSBD(fdo,urb);

   //
   // If the transfer was successful, report the length of the transfer to the
   // caller by setting IoStatus.Information
   //

  if(NT_SUCCESS(ntStatus))
  {
  Irp->IoStatus.Information=urb->UrbBulkOrInterruptTransfer.TransferBufferLength;
  Evk_KdPrint((\"Successfully transfered 0x%x bytes\\n\",Irp->IoStatus.Information));
   }

  
   // free the URB
   //
   ExFreePool(urb);
  
   return ntStatus;
 
}

麻烦liutan等高手看一下,有什么问题。
shlei20
驱动牛犊
驱动牛犊
  • 注册日期2002-02-01
  • 最后登录2003-02-08
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-04-18 20:41
找到原因了,是我的粗心。真是要不得呀!!!
游客

返回顶部