虚拟子单元驱动程序说明

虚拟子单元驱动程序通过使用具有 Avc.sys的IOCTL_AVC_CLASS接口响应来自外部 AV/C 设备的控制、状态和通知 AV/C 请求和命令。

IOCTL_AVC_CLASS子函数代码 AVC_FUNCTION_GET_REQUESTAVC_FUNCTION_SEND_RESPONSE 是虚拟子单元驱动程序与虚拟驱动程序堆栈其余部分交互的关键机制。 虚拟子单元驱动程序在IRP_MN_START_DEVICE例程中,将AVC_FUNCTION_GET_REQUEST IRP 提交到Avc.sys(在堆栈内的底层驱动程序完成 IRP_MN_START_DEVICE 之后)。 每次收到虚拟子单元请求时,都会调用 AVC_FUNCTION_GET_REQUEST IRP 的 I/O 完成例程。 I/O 完成例程必须在 100 毫秒内发送响应(由具有异步 IRP 的AVC_FUNCTION_SEND_RESPONSE )(根据 AV/C 协议规则):它可以使用请求中包含的 AVC_COMMAND_IRB 结构发送响应。 然后,它必须重新提交 AVC_FUNCTION_GET_REQUEST IRP,才能最终从响应的 I/O 完成例程中返回。

虚拟驱动程序堆栈中的子单元驱动程序无法将命令直接发送到外部设备。 对等驱动程序堆栈提供此功能。 但是,虚拟子单元驱动程序可以使用AVC_FUNCTION_FIND_PEER_DOAVC_FUNCTION_PEER_DO_LIST这两个IOCTL_AVC_CLASS子函数来发现和引用Avc.sys的对等实例,然后与外部 AV/C 子单元进行交互。

对于枚举的每个虚拟子单元, Avc.sys 创建相应的设备对象。 因此,当添加和删除虚拟子单元时, Avc.sys 触发 IEEE 1394 总线重置。 此重置允许 IEEE 1394 总线上的其他设备检测计算机上公开的新功能。 虚拟子单元驱动程序基于 Avc.sys 实例的注册表设置加载,并且可以在运行时由 IOCTL 代码请求添加和删除。 请注意, Avc.sys 无法区分同一类型的多个虚拟子单元,因此添加和删除这些子单元会加载和卸载具有最高子单位标识符的相应虚拟子单元驱动程序。

虚拟子单元驱动程序可以是厚或薄的。 唯一的要求是将其编写为 WDM 驱动程序。 厚驱动程序实现了虚拟设备的大多数功能,如果不是全部功能的话。 精简驱动程序提供虚拟设备功能的代理接口,它可以是另一个驱动程序或用户模式组件。 用户模式和虚拟子单元驱动程序之间的接口特定于实现,可以通过 IOCTL 代码、专用设备接口(请参阅 IoRegisterDeviceInterface)或通过 Windows Management Instrumentation (WMI)来完成。

VEN_和MOD_值与 INF 文件中指定的值相同,导致 61883.sys 的虚拟实例加载。 当 Avc.sys 枚举虚拟子单元时,TYP_ 和 ID_ 值按照指定方式设置。

虚拟子单元的枚举通过使用 IOCTL_AVC_UPDATE_VIRTUAL_SUBUNIT_INFOIOCTL_AVC_REMOVE_VIRTUAL_SUBUNIT_INFOIOCTL_AVC_BUS_RESET IOCTL 代码来实现。

必须发送正确的 IEEE 1394 IOCTLs、 IEEE1394_API_ADD_VIRTUAL_DEVICEIEEE1394_API_REMOVE_VIRTUAL_DEVICE 才能开始枚举过程。 要了解更多信息(IOCTL_IEEE1394_API_REQUEST的子命令)。 61883.inf 文件已包含用于此目的的设备标识符(ID):V1394\A02D&10001,尽管自定义 INF 文件中可能提供了不同的标识符。

可以使用 INF 文件以静态方式枚举虚拟子单元。

虚拟设备列表密钥下的每个值都是打包的子单位地址(子单位类型和最大标识符组合在一起,如 AV/C 常规规范中所述)。 与子单位地址关联的名称并不重要,尽管该名称对于该实例必须是唯一的。 以编程方式创建时,为值名称提供顺序数字以避免冲突。

例如,若要通过 INF 文件创建单个虚拟优化器子单元,请使用以下 AddReg 指令:

[Subunit_Device.NT.HW.AddReg]
HKR,%VirtualAvc.DeviceList%,Tuner,0x00000001,0x28 ;0x00000001 = Binary value, 0x28 = Registry key value

此指令添加一个REG_BINARY值0x28(子单位类型0x5编码在最左边的五个位,最大标识符0x0编码在最右边的三个位)。 此处0x0的最大标识符意味着将有该类型的单个子单位。

注意:还需要在子单元的 INF 文件的某一部分中定义%VirtualAvc.DeviceList%令牌。