Windows XP下usbport.sys驱动内部实现解析(一)

Windows XP USB启动安装全攻略:驱动注入原理与实战 操作系统安装的核心在于引导程序对硬件驱动的识别与加载。Windows XP等早期系统在安装阶段,其文本模式安装环境默认不包含USB大容量存储驱动,导致无法直接从USB设备启动安装。通过修改安装源文件中的关键配置文件,如TXTSETUP.SIF和DOSNET.INF,可以将USB存储驱动(如usbstor.sys)的加载时机提前至系统引导的初始阶段,这一过程被称为“驱动注入”。这项技术的价值在于突破了原生安装程序的限制,使得为老旧工业设备、嵌入式系统或特定兼容性测试创建便携式、隔离的Windows XP工作环 阅读详情

http://hi.baidu.com/jlgwxq/blog/item/a3bcc30356a3cc057aec2c64.html

Windows XP下usbport.sys驱动内部实现解析(一)
2010-01-22 18:10

上一篇讲了USB驱动栈整体结构,说明了usbport.sys的重要作用,现在就具体分析usbport.sys的内部实现细节。

首先再重复一下:

usbport 是一个USB主机控制器的port driver,而usbuhci是uhci类型的USB主机控制器的miniport driver,usbehci则是ehci类型的USB主机控制器的miniport driver,usbport负责创建管理USB主机控制器的 FDO ( Function Device Object )。而 FDO 对应的 PDO (Physical Device Object) 是由谁创建的呢?当然是这个主机控制器所在总线的总线驱动创建管理的了 -- 一般就是PCI总线驱动。

usbport主要完成的功能如下:

1. 抽象层次上管理USB主机控制器,实际的操作是由各个miniport driver 完成的。
2. 创建并管理集成在USB主机控制器里面的根总线的PDO,这个PDO上会附加由usbhub.sys创建并管理的FDO 对象。
3. 管理维护所有挂在当前这个主机控制器上的最多127个usb 设备。
4. 处理大多数针对当前这个主机控制器管理下的总线上的所有usb设备所发出的USB请求(URB)。

基本功能如上所述,这里就这几方面的功能一一描述。

1. 抽象层次上管理USB主机控制器

这个是集成到各个其他操作里面的,通用的操作由usbport完成,特定了和硬件相关的操作通过调用各个miniport所注册的callback routine来完成。USB主机控制器的miniport跟其他各种的miniport driver一样,在DriverEntry里面填写好一个结构,调用usbport的一个导出函数,usbport修改这些结构的某些成员提供自己实现的一些函数指针以供miniport driver调用。

下面是注册所用的数据结构:

struct _USB_MINIPORT_REGISTRATION_PACKET
{
ULONG ulVersion;
ULONG ulFlags;
ULONG ulTotalBandWidth;

// some other fields
// ......
// miniport\'s routines
// ......
// // output service routines filled by usbport.sys
// ......
};

2. 创建并管理集成在USB主机控制器里面的根总线的PDO

根总线的PDO创建很简单,不外乎就是在query bus relationship的是创建一个device并且返回就行了。至于关联到这个根总线PDO上的操作,大部分都交给了USB主机控制器 FDO 来完成了。马上就能看到其实大部分的操作都是发送给这个PDO的。

3.跟4.就是今天的重点部分了,这两个部分也是 usbport.sys里面着墨最多的地方。我讲的顺序也是先说第三部分,再说第四部分。但是这两个部分并不是完全分开的,比如设备管理的时候可能涉及到要向某个设备发送一些urb。最典型的就是要set address,这里当然就必须由第四个部分来完成了,而且urb的处理也极大的依赖管理设备的时候所建立和维护的诸多数据结构。但是为了讲解方便,在说到第三个部分的时候总是假设usbport有某种方法能把某个urb发送出去并且完成,暂时不管他具体是怎么完成的。

3. 管理维护所有挂在当前这个主机控制器上的最多127个usb 设备

在前面说到usbport实现了两个interface以提供usbhub.sys调用,并在usbhub的帮助下来收集所有连接到总线上的设备信息。这里我们跳过这两个interface的具体说明以及调用方式调用时间等等信息,等到讲到usbhub的时候再回头来看这个过程,那个时候再来说究竟在什么时候在什么样子的情况下usbhub会调用哪个函数。如果没有调用上下文要去分析一个函数的功能是比较盲目的,这里大家了解这样一个规则:usbhub用某种方式得知了总线上有个设备连接进来了(比如你插入了一个u盘)?usbhub是通过调用USBPORTBUSIF_CreateUsbDevice 通知usbport这个事件发生了(函数参数信息可以查阅ddk)。下面得分析也就是从这个地方开始的。

在经过必要的参数检查测试以后,usbport为这个新报告的设备分配一个结构,用来保存必要的信息。下面是结构体的成员:

struct DEVICE_HANDLE // (sizeof=0X70)
{
ULONG dwSignature; // signature = \'HveD\'
USHORT DeviceAddress; // usb device addr (1-127)
USHORT PortNumber; // port number
ULONG RefCount; // reference count
ULONG Tt; // for usb2.0
PVOID ParentHandle; // parent hub device handle
PCONFIG_HANDLE ConfigHandle; //
PIPE_HANDLE PipeHandle; // for default pipe
ULONG DeviceSpeed; // see ddk
USB_DEVICE_DESCRIPTOR DeviceDesc; //
UCHAR reserved; // padding,alignment
ULONG DeviceFlags; //
LIST_ENTRY DeviceHandleListEntry; // link all device handle together
LIST_ENTRY PipeHandleListHead; // pipe handle list header
ULONG TtCount; // for usb2.0
LIST_ENTRY TtListHead; // for usb2.0
};

usbport 设置好某些域以后,开始open the default pipe。完成以后,发送一个get device descriptor的urb到这个新出现的usb设备用来填写DeviceDesc成员。成功以后把这个新创建的device handle添加到由USB主机控制器所维护的device handle list上去。具体流程参看下面的伪代码:

createdevice(parenthandle,portnumber,portstatus)
{
检查参数是否合法

为DEVICE_HANDLE分配内存handle

handle->refcount = 0
handle->confighandle = 0
handle->parenthandle = parenthandle
handle->portnumber = portnumber
handle->deviceaddress = 0 // default usb address

根据portstatus,设置handle->devicespeed
根据devicespeed,设置默认 pipe 的maxpacketsize
初始化默认 pipe 的 pipe_handle 的其它成员变量
打开默认 pipe 的端点
得到设备的描述信息 device descriptor
将这个handle保存到 device handle list 链表中
}

在看open default pipe之前得先看看pipe handle这个结构:

struct PIPE_HANDLE // sizeof=0X20
{
ULONG dwSignature; // signature = \'HpiP\'
USB_ENDPOINT_DESCRIPTOR EndPointDesc;
UCHAR reserved; // padding,alignment
ULONG Flags // flags
ULONG unknown;
ENDPOINT* EndpointPointer;
LIST_ENTRY ListEntry;
};

很简单的一个结构。

现在来看open endpoint这个函数:1. 先照样作一些检查,然后为endpoint结构分配内存。因为这个endpoint结构不仅仅是usbport使用,miniport也会使用。所有这个结构的大小是不固定的,miniport在注册自己的时候会指定自己所需要的结构大小,usbport在这个大小的基础上加上自己所管理的大小来决定要分配多大的内存。2. 然后usbport作很多的初始化工作,设置大部分endpoint结构的成员,必要的时候还需要miniport的帮助。3. 完成以后把这个pipe handle连接到device的pipe handle list header上面,同时把新创建的endpoint也连接到由fdo维护的全局endpoint list header上面去。

endpoint是一个很大的结构,0x160个字节(checked xp版本),篇幅原因不一一列举了,看几个与我们分析相关的成员:

struct ENDPOINT // sizeof=0X160
{
ULONG dwSignature; // \'PEch\'
PDEVICE_OBJECT FunctionDevice; // host controller fdo
PDEVICE_HANDLE DeviceHandle; // device handle
ULONG CurrentState; // endpoint state
ULONG NextState; // hose two field will be protected by StateLock(see below)
ULONG FrameNumber32Bit; // for iso,current frame number
PWORK_ROUTINE WorkerRoutine; // core work routine
LIST_ENTRY ActiveTransfer; // activer transfer list header
LIST_ENTRY PendingTransfer; // pending transfer list header
LIST_ENTRY CancelTransferList; // cancel transfer list header
LIST_ENTRY AbortIrpList; // abort irp list header
LIST_ENTRY EndpointListEntry; // link all endpoints together to fdo\'s list header
LIST_ENTRY AttendLink; // see below
LIST_ENTRY StateChangeListEntry; // endpoint state change list entry linked to fdo\'s list header
LIST_ENTRY ClosedLink; // for lazy close,linked to fdo\'s list header
LIST_ENTRY FlushList; // flush list entry,linked to fdo
USB_LOCK ResourceLock; // spin lock for this struct
USB_LOCK StateLock; // spin lock for endpoint\'s state
KIRQL SavedResIrql; // save irpl
KIRQL SavedStateIrql;
COMMON_BUFFER* CommonBuffer; // for miniport driver COMMON_BUFFER*
USHORT DeviceAddress; // device addr,copied from device handle
USHORT EndPointAddr; // endpoint number
ULONG MaxPacketSize; // max packet size
UCHAR Period; // period
ULONG DeviceSpeed;
ULONG BandWidth;
ULONG Offset; // schedule offset
ULONG TransferType; //
ULONG Direction; // in or out
ULONG CommonBufferVir; // for common buffer
ULONG CommonBufferPhy; // for common buffer
ULONG CommonBufferLen; // for common buffer
ULONG MaxTransferLen;
USHORT PortNumber;
PVOID ClientContextPointer; // point to miniport endpoint context

};

许多成员的作用就像他的名字所描述的一样,不过有几个特别提出要特别注意的地方。

首先是state,有两个成员表征了endpoint的state信息。state是用来描述当前endpoint的状态的,在不同的状态下面对于发送到endpoint的urb的处理方式是不一样,这个会在后面看到。

然后是诸多的list entry,他们大多数是用来作urb的排队的,后面也会一一看到用法。

workroutine 是一个函数指针,他的存在是因为发送到root hub的urb必须特殊处理,而不用转换成usb信号出现在usb总线上面。所有root hub对应的两个endpoint的workroutine是特别设计的,其他的endpoint对应的workroutine是一个通用的函数,这个 workroutine要作的工作就是处理urb。

至于那个common buffer,多数情况下是不是用来作传输用的。因为usbport所使用的dma是一个master而且还能scatter-gather的,所以大部分的urb都直接使用他自己的buffer本身占用的物理页,而不需要一个额外的copy操作,只有在某个buffer很不幸的跨越了两个不连续的物理页的时候才需要使用到这个common buffer作额外的copy操作。特别注意这个common buffer是提供给miniport driver使用的,而不是由usbport来使用的,miniport driver还会从这个common buffer里面提交一些内存来作额外的维护信息。

create device就到这里,基本操作就是分配device handle结构,分配endpoint zero 的结构,链接他们到各自对应的list header上面去。

device创建好了以后,usbhub再发出另外一个initialize device的请求。对于usbport来说这个请求唯一的处理就是为其分配一个地址,并且发出set address的urb。

完成这两步,这个device就能交付使用了。

使用的时候第一个步骤就是select configuration,device的驱动程序读取device的configuration descriptor,然后选择适当的interface构造一个select configuration的urb传递下来。中间的处理由usbhub完成,暂时忽略。假定这个urb到达了root hub的pdo,经过一系列的检查(这个部分会在urb的处理的时候再次提到),最终来到处理函数 _USBPORT_SelectConfiguration。

首先为其分配一个config handle的结构:

struct CONFIG_HANDLE //sizeof=0X14
{
ULONG dwSignature; // \'HgfC\'
PVOID ConfigDescPointer; // ptr config desc buffer
LIST_ENTRY InterfaceListHead; // link interfaces together
USB_CONFIGURATION_DESCRIPTOR ConfigDesc;
};

很简单的一个变长结构(因为configurtation descriptor是变长的),实际上的configuration descriptor就跟在这个结构的末尾,从0ffset 0x10开始。当然,device handle结构的config handle成员指向了这个新分配的内存。

接下来发送一个set configuration的urb到设备。然后一一open 这个select configuration里面所描述的interface,并且填写将来要返回的USBD_INTERFACE_INFORMATION结构。填写 information结构是一个很简单的操作,所有必须的信息都在前面的步骤里面完成了,我们只是看看open interface完成的操作:

首先还是要分配结构:

struct INTERFACE_HANDLE
{
ULONG dwSignature; // \'HxfI\'
LIST_ENTRY ListEntry; // linked to config handle\'s interface list header
ULONG HasAltSetting;
USB_INTERFACE_DESCRIPTOR InterfaceDesc;
UCHAR reserved[3]; // Padding db 3 dup(?)
PIPE_HANDLE PipeHandle;
};

这个结构是变长的,结尾由若干个pile handle结构组成。个数当然由interface desc里面的endpointnumber指出。

结构分配完了,照例对各个成员进行初始化,然后调用open endpoint函数(如上所述)。最后再把这些个interface handle连接到config handle上面,工作就完成了...

客户驱动程序在这个select configuration urb返回的时候,就能查看USBD_INTERFACE_INFORMATION结构,一一了解各个自己感兴趣的东西。当然其中最最主要的就是所返回的 pipe handle,正如你所想象的那样,他就是一个指向PIPE_HANDLE结构的指针。客户驱动保存这个指针,因为随后的很多urb都需要你去填写这个 pipe handle成员,usbport也需要使用这个指针去寻找对应的endpoint结构。

select configuration完成以后,就能开始传输数据了,这也就是下来的内容了--- urb的处理。

Windows 2000 USB驱动完整安装包:INF配置与微端口驱动深度解析 USB驱动是操作系统与物理外设通信的基础技术,其核心原理在于硬件抽象、协议栈匹配与内核服务注册。在Windows 2000这类早期NT内核系统中,USB支持高度依赖INF配置文件的精确语法和微端口驱动(如usbport.sys、usbd.sys)的版本一致性,任何偏差都将导致Error Code 10、28等典型故障。该技术具有显著的工业现场价值——支撑老旧工控设备、医疗仪器及嵌入式教学平台的持续运行,尤其适用于无法升级却必须接入现代USB传感器、串口模块或HID设备的严苛场景。本文聚焦Windows 20 阅读详情

相关推荐

Windows 7 SP1增强型升级安装实战:USB3.0驱动注入与离线补丁部署

Windows 7作为NT6.x内核的经典操作系统,虽已终止支持,但在工控、教育及嵌入式场景中仍承担关键业务。其升级本质不是版本迭代,而是面向Legacy BIOS环境的系统兼容性工程——需解决USB3.0驱动缺失、NVMe识别失败、SHA-2签名支持不足等底层限制。技术核心在于离线镜像服务(DISM注入)、启动介质定制(Rufus+bootmgr适配)与补丁依赖链管理(KB4474419为前置基点)。该方案兼顾业务连续性与硬件兼容性,适用于戴尔OptiPlex等老平台在不重装系统前提下获得USB3.0识别

a6t2007的博客 592

Windows XP下usbport.sys驱动内部实现解析(二)

http://hi.baidu.com/jlgwxq/blog/item/e0f223312c0aa548ac4b5f67.html  Windows XP下usbport.sys驱动内部实现解析(二) 2010-01-22 18:15 (接上一篇) 4. 处理USB请求(URB) 在进入下一个主题之前我总结几个事实让大家注意: 1. 对于每个usb总线上的设备,usbpo

killcpp的专栏 716

USBport.sys驱动修复系统蓝屏问题实战指南

当USB设备插入主机端口后,主机控制器(Host Controller)会检测到物理连接的变化,并启动设备初始化流程。整个流程可以分为以下几个阶段:设备检测与复位主机检测到设备插入后,会向设备发送复位信号(Reset),将设备置于默认状态(Default State),并准备进入地址分配阶段。获取设备描述符复位完成后,主机会通过控制传输(Control Transfer)向设备发送请求,获取设备的基本信息,包括设备支持的USB版本、最大包大小等。分配设备地址。

weixin_35756624的博客 1298

关于解决插入USB设备蓝屏的思路【转】

近日在作维修服务时发现不少用户存在一个问题就是很多电脑在插入部分USB设备时电脑会立刻蓝屏,首先我尝试了卸载了设备管理器里的所有关于USB的项目,然后重启后测试,结果发现在系统自动检测USB设备时再次立刻蓝屏,无法只能试着卸载删除所有的USB驱动文件,最终问题才得已解决,方法如下: 1、进入C:>windows>system32>drives下删掉USBehci.sys usb...

weixin_30768661的博客 1348

Windows 2000专用USB驱动完整安装包(含INF配置与微端口驱动)

简介:本资源为面向Windows 2000操作系统的USB设备兼容性解决方案,包含经验证的主机控制器驱动、通用USB驱动模型及设备级微端口驱动。核心文件win2000_usb.inf提供标准化安装指引,支持硬件ID识别与自动驱动部署;压缩包集成可执行安装程序、PUDN来源说明文档及完整驱动签名/配置信息,适用于解决Win2000下USB设备无法识别、枚举失败或功能异常等典型问题,助力老旧系统延续USB外设支持能力。

weixin_35755640的博客 255

HASP4加密锁Windows驱动包(含DOS下hdd32.exe调试工具与HTML版安装指南)

HASP4硬件加密锁配套驱动安装程序,支持主流Windows系统(XP至Win10/11 32位与64位),主安装程序HASP4_driver_setup自动完成驱动文件部署、注册表配置及服务注册,实现即插即用式硬件认证。包内附带hdd32.exe——专为纯DOS环境设计的32位HASP4设备识别与状态检测工具,适用于老旧工控系统、驱动兼容性验证或无GUI场景下的底层调试;readme.html提供完整操作指引,涵盖安装流程、系统要求(如需管理员权限、禁用驱动签名强制)、常见故障代码释义(如设备未识别、服务

mango的博客 207

WinXP下USB驱动开发(六)

3.3.2.3.    操作USBD.SYS正如前面所述,对USBD.SYS驱动操作的中介只URB结构体,因此对USBD.SYS的操作主要可以分构造URB和调用请求两部分,如下以USB读写操作过程为例进行分析。第一步构造URB:由于EasyArm2400下位机固件程序USB采用的是中断方式进行数据传输,因此我们就需要构造一个中断传输的URB,实现如下代码。 UsbBui

Tech is Online(物联网技术传播) 6262

QF9700 USB网卡驱动程序完整安装与配置指南

QF9700 USB网卡驱动是专为基于QF9700芯片组设计的USB接口网络适配器提供的核心软件支持,旨在实现设备与操作系统的无缝通信。该驱动不仅承担硬件识别、资源分配和数据传输调度等基础功能,还通过标准化接口向上层网络协议栈提供稳定的数据链路服务。作为连接物理网络与操作系统之间的桥梁,QF9700驱动在即插即用(Plug and Play)、电源管理(如Suspend/Resume)以及热拔插响应机制中发挥关键作用。

weixin_42600128的博客 843

Windows XP下usbport.sys驱动内部实现解析(四)

http://hi.baidu.com/jlgwxq/blog/item/e54543100b5cb7c5c2fd7860.html Windows XP下usbport.sys驱动内部实现解析(四) 2010-01-22 18:16 (接上一篇) 然后来看看实际上的work routine,先看通用的这个。root hub的是一个特殊的函数。 USBPORT_DmaEndpoi

killcpp的专栏 629

usbport.sys文件下载 系统蓝屏修复 很管用 已测

usbport.sys文件下载 系统蓝屏修复 很管用 已测

USBport调试通畅版本

USB编程基本第一课,USBport一般都是有很多的问题,缺少很多文件。这是一个调试正常运行的版本。具体调节可以查看saitevuq新浪博客。

Windows XP下usbport.sys驱动内部实现解析(三)

Windows XP下usbport.sys驱动内部实现解析(三) 2010-01-22 18:16 (接上一篇) _USBPORT_MapTransfer是个比较复杂的函数了,他涉及到transfer的切割、sgList结构的填写,少安毋躁。。。哈哈 struct SG_LIST { ULONG Flags; PVOID CurrentVa; PVOID MappedSy

killcpp的专栏 665

USB鼠标所需驱动HIDUSB.SY_ mouhid.sys

安装USB鼠标所需驱动 HIDUSB.SY_ mouhid.sys

Windows操作系统的USB驱动架构

Winows操作系统下关于USB的驱动可分为: Windows2000 在Windows2000时代,USB设备基本是USB1.0.USB1.1和少量的USB2.0设备。 所以USB驱动架构构为: Windows2000 USB控制器 usbd.sys - Universal Serial Bus Driver 这是USB控制器的类驱动程序,配合2个端口驱动程序openhci.sys和uhcd.sys,这2个端口驱动分别对应于usb1.0和usb.1.1 Windows2000 USB集线器-HUB US

T76230169的专栏 2272

usbport

VC++编写的USB程序源码

基于Ansys Fluent 的颗粒分离/过滤解决方案

过滤是指通过特殊装置将颗粒移除,将流体提纯净化的过程。过滤的方式很多,应用的物系也很广泛,固-液、固-气、大颗粒-小颗粒等。

sh_djoin的博客 1852

USB 驱动程序堆栈体系结构

USB 驱动程序堆栈体系结构 本主题提供了通用串行总线 (USB) 驱动程序堆栈体系结构的概述。 下图显示了 Windows 8 USB 驱动程序堆栈体系结构框图。该图分别显示了 USB 2.0 和 USB 3.0 的 USB 驱动程序堆栈。当设备附加到 xHCI 控制器时,Windows 会加载 USB 3.0 驱动程序堆栈。USB 3.0 堆栈是 Windows 8 中的新功能。 当

M_O_Bz的专栏 2437

Ubuntu安装ToDesk远程控制软件

前几天有同学问我怎么在 Ubuntu 系统上安装 ToDesk 远程控制软件, 帮他安装完成后就 顺手整理了一下安装过程,所以就顺手有了这篇在 Ubuntu 系统上安装 todesk 的文章。

小白的博客 8657

USB设备偶发断连根因与实战加固指南

USB设备连接稳定性是嵌入式系统开发中的核心基础问题,其本质涉及协议时序、电源完整性、主机驱动兼容性及硬件鲁棒性等多层协同。从USB枚举超时、端点使能延迟、挂起/唤醒握手失败,到字符串描述符编码错误,每一个微小偏差都可能引发‘识别成功但通信失效’的偶发断连现象。结合ft231x usb uart驱动适配、stm32 如何做usb设备等高频实践场景,本文聚焦CDC类USB Device在Windows/Linux多平台下的真实落地挑战,提供基于USB抓包、逻辑分析仪和主机日志的分层诊断路径,并输出可工程复用的

weixin_33937913的博客 404

YOLOv8中Anchor-Based、Anchor-Free及样本分配策略

本文主要介绍yolov8中的anchor机制与样本分配策略的静态策略和动态策略

qq_52889317的博客 2211

物联网低功耗广域网NB-IoT开发(一):初识NB-IoT

(二)NB-IoT的关键特性: (三)NB-IoT的应用场景: 二、NB-IOT介绍

weixin_49763156的博客 853

usb控制器和usb port之间有什么联系-usbview工具的使用?

usbview 是一个可以查看usb 拓扑的工具,可以通过这个工具查看当前USB Host控制器的个数和连接device信息.

tugouxp的专栏 3136

从零到一:uniPush2.0全链路集成与多厂商通道配置实战

本文提供了uniPush2.0从零开始的全链路集成与多厂商通道配置实战指南。详细讲解了DCloud平台配置、uniCloud云函数开发、客户端CID获取与消息监听,并重点攻克了华为、小米、OPPO、vivo等主流厂商推送通道的配置难点与避坑技巧,帮助UniApp开发者实现“一次集成,全端覆盖”的高效消息推送方案。

onion的博客 431
上一篇: Windows XP下USB整体结构
下一篇: Windows XP下usbport.sys驱动内部实现解析(二)
killcpp
博客等级 码龄20年 13粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值