您所在的位置: 首页>>读书频道>>设计开发>>其它开发>>

17.3.3 发送USB请求包

http://book.51cto.com  2008-07-07 10:07  张帆/史彩成等编著  电子工业出版社  我要评论(0)
  • 摘要:《Windows驱动开发技术详解》第17章USB设备驱动,这一章首先介绍USB协议,使大家对USB协议有个整体认识,然后介绍USB设备在WDM中的开发框架,本节为大家介绍的是发送USB请求包。
  • 标签:Windows  驱动  开发  技术  Windows驱动开发技术详解

17.3.3  发送USB请求包

功能驱动将URB包构造完毕后,就可以发送到底层总线驱动上了。URB包要和一个IRP相关联起来,这就需要用IoBuildDeviceIoControlRequest创建一个IO控制码的IRP,然后将URB作为IRP的参数,用IoCallDriver将URB发送到底层总线驱动上。由于上层驱动无法知道底层驱动是同步还是异步完成的,因此需要做一个判断。if语句判断当异步完成IRP时,用事件等待总线驱动完成这个IRP。

 #001   //该函数实现对发送URB到USB物理总线驱动
#002   NTSTATUS
#003   CallUSBD(
#004       IN PDEVICE_OBJECT DeviceObject,
#005       IN PURB           Urb
#006       )
#007   {
#008       PIRP               irp;
#009       KEVENT             event;
#010       NTSTATUS           ntStatus;
#011       IO_STATUS_BLOCK    ioStatus;
#012       PIO_STACK_LOCATION nextStack;
#013       PDEVICE_EXTENSION  deviceExtension;
#014  
#015    //首先是变量初始化
#016       irp = NULL;
#017       deviceExtension = DeviceObject->DeviceExtension;
#018       //初始化事件
#019       KeInitializeEvent(&event, NotificationEvent, FALSE);
#020    //创建IO控制码相关的IRP
#021       irp = IoBuildDeviceIoControlRequest
(IOCTL_INTERNAL_USB_SUBMIT_URB,
#022                                           deviceExtension->
TopOfStackDeviceObject,
#023                                           NULL,
#024                                           0,
#025                                           NULL,
#026                                           0,
#027                                           TRUE,
#028                                           &event,
#029                                           &ioStatus);
#030  
#031       if(!irp) {
#032     //如果IRP创建失败则返回
#033           BulkUsb_DbgPrint(1, ("IoBuildDeviceIo
ControlRequest failed\n"));
#034           return STATUS_INSUFFICIENT_RESOURCES;
#035       }
#036    //得到下一层设备栈
#037       nextStack = IoGetNextIrpStackLocation(irp);
#038       ASSERT(nextStack != NULL);
#039       nextStack->Parameters.Others.Argument1 = Urb;
#040       BulkUsb_DbgPrint(3, ("CallUSBD::"));
#041       BulkUsb_IoIncrement(deviceExtension);
#042    //通过IoCallDriver将IRP发送到底层驱动
#043       ntStatus = IoCallDriver(deviceExtension->
TopOfStackDeviceObject, irp);
#044    //如果IRP是异步完成时,等待其结束
#045       if(ntStatus == STATUS_PENDING) {
#046     //等待IRP结束
#047           KeWaitForSingleObject(&event,
#048                                 Executive,
#049                                 KernelMode,
#050                                 FALSE,
#051                                 NULL);
#052           ntStatus = ioStatus.Status;
#053       }
#054       //调用结束
#055       BulkUsb_DbgPrint(3, ("CallUSBD::"));
#056       BulkUsb_IoDecrement(deviceExtension);
#057       return ntStatus;
#058   }

此段代码可以在配套光盘中本章的sys目录下找到。

【责任编辑:夏书 TEL:(010)68476606】

回书目   上一节   下一节
深入Vista应用程序开发
Hyper-V 虚拟化技术专题
让你的代码“炫”起来——WPF开发教程
重复数据删除技术
2008年上半年IT技术图书阅读排行大盘点
 
 验证码: (点击刷新验证码)   匿名发表
  • Visual C++ 完全自学宝典

  • 作者:强锋科技,朱洪波
  • Visual C++ 6.0是微软公司为程序人员提供的Visual Studio 6.0工具套件中的重要组成部分。本书由浅入深地介绍使用Visual C++ 6.0..
Copyright©2005-2008 51CTO.COM 版权所有