newsky
驱动牛犊
驱动牛犊
  • 注册日期2003-03-07
  • 最后登录2013-09-12
  • 粉丝1
  • 关注0
  • 积分25分
  • 威望220点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1593回复:0

求教 : USB虚拟串口写操作蓝屏重启

楼主#
更多 发布于:2009-03-10 18:41
现在在做一个USB的虚拟串口驱动,再加载后,用串口工具打开,发送数据时发生蓝屏死机,不知原因是什么,请教各位大侠赐教!

写入的源码如下:


NTSTATUS UsbWriteComplete(PDEVICE_OBJECT DeviceObject,
                                        PIRP Irp,
                                           PVOID pContext)

{
    NTSTATUS status=STATUS_SUCCESS;
    PEVCOM_DEVICE_EXTENSION dx=(PEVCOM_DEVICE_EXTENSION)pContext;

    KeSetEvent(&(dx->OutWriteEvent), IO_NO_INCREMENT, FALSE);

    return status;
}



NTSTATUS VcomWrite(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
    PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    NTSTATUS status=STATUS_SUCCESS;
    PEVCOM_DEVICE_EXTENSION dx=(PEVCOM_DEVICE_EXTENSION)fdo->DeviceExtension;

    ULONG flags;
    URB urb;

    PIRP irp = NULL;
    CCHAR stackSize;
    PIO_STACK_LOCATION nextSp;

    PMDL pMdl;
    ULONG WriteLength;
    ULONG_PTR VirtualAddress;

    DebugPrint("EVcomWrite %T,  Length : %d\n",&(dx->SymbolicName),IrpStack->Parameters.Write.Length);
    DebugPrint("EVcomWrite Length : %s\n",Irp->AssociatedIrp.SystemBuffer);

    if(dx->IsOpened == FALSE)
        return CompleteIrp(Irp,status,0);
    
    if(IrpStack->Parameters.Write.Length <= 0)
        return CompleteIrp(Irp,status,0);

    WriteLength = MmGetMdlByteCount(Irp->MdlAddress);
    if(WriteLength == 0)
        return CompleteIrp(Irp,status,0);
    VirtualAddress = (ULONG_PTR) MmGetMdlVirtualAddress(Irp->MdlAddress);
    pMdl = IoAllocateMdl (
                           (PVOID)VirtualAddress,                                  // buffer pointer - virtual address
                           WriteLength,                              // length
                           FALSE,                                    // not secondary
                           FALSE,                                    // don't charge quota
                           NULL );                                   // don't use irp

    if ( !pMdl )
        return CompleteIrp(Irp,status,0);
    
    flags = USBD_TRANSFER_DIRECTION_OUT | USBD_SHORT_TRANSFER_OK;

    IoBuildPartialMdl(Irp->MdlAddress,
                      pMdl,
                      (PVOID) VirtualAddress,
                      WriteLength);
    
    UsbBuildInterruptOrBulkTransferRequest((PURB) & urb,
                                        sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                                        dx->OutWritePipeHandle,
                                        NULL, //Irp->AssociatedIrp.SystemBuffer,
                                        pMdl,
                                        IrpStack->Parameters.Write.Length,
                                        flags,
                                        NULL);


    nextSp = IoGetNextIrpStackLocation(Irp);
    nextSp->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
    nextSp->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
    nextSp->Parameters.Others.Argument1 = (PURB) &urb;    //urb pointer

    IoMarkIrpPending(Irp);
    
    IoSetCompletionRoutine(Irp,
                            UsbWriteComplete,
                            (PVOID)dx,
                            TRUE,
                            TRUE,
                            TRUE);
    
    status = IoCallDriver(dx->LowerDeviceObject, Irp);

    if (status == STATUS_PENDING)
    {
        KeWaitForSingleObject(&dx->OutWriteEvent,
                            Executive,
                            KernelMode,
                            FALSE,
                            NULL);
    }
    
    return CompleteIrp(Irp,status,IrpStack->Parameters.Write.Length);
}




游客

返回顶部