使用 Avc.sys
Windows 加载并初始化 Avc.sys后 ,Avc.sys 使用标准 AV/C 单元和子单元命令发现连接到 IEEE 1394 总线的所有 AV/C 设备上的活动子单元 (包括计算机是虚拟 AV/C 单元) 时的任何虚拟子单元。 然后,Avc.sys为所有活动子单元生成设备标识符 (id) 。 接下来, Avc.sys使用标准即插即用 (PnP) 机制为每个子单元加载相应的子单元驱动程序。 根据安装子单元驱动程序的 INF 文件和子单元的设备标识符选择要加载的子单元驱动程序,如 Avc.sys 生成并 如 AV/C 设备 ID 中所述。 设备标识符是从 AV/C 设备的单元信息与子单元的 SubunitType 和 SubunitID 字段一起生成的。 支持子单元的驱动程序可以是特定于供应商的,也可以是子单元类型的泛型。 例如,大多数 DV 摄像机的子单元驱动程序是 Microsoft 提供的 Msdv.sys。
子单元驱动程序通过基于 WDM 体系结构的所有驱动程序采用的标准基于 IRP 的机制与Avc.sys通信。 子单元驱动程序通过分配驱动程序堆栈中的 IRP 并将其发送到 AV/C 协议驱动程序来与其 AV/C 子单元通信, Avc.sys。 若要发出 I/O 请求,请包含 Microsoft Windows 驱动程序工具包 (WDK) 附带的头文件 Avc.h。
子单元驱动程序分配并初始化要由 Avc.sys处理的 IRP。 子单元驱动程序将 IRP 的 Parameters.DeviceIoControl.IoControlCode 成员设置为对应于所需 AV/C 操作的 IOCTL。
Avc.sys 注册两个 设备接口中的一个,具体取决于加载该接口以支持 (对等或虚拟) 的子单元驱动程序堆栈。 这些接口定义 Avc.sys 导出的功能,以供子单元驱动程序、其他驱动程序和应用程序使用。 Avc.sys 然后根据驱动程序的 PnP 状态将接口的状态更改为“已启用”或“已禁用”。
如果 加载 GUID_AVC_CLASS 实例是为了在对等堆栈) (外部 AV/C 子单元提供支持,Avc.sys会注册新的 GUID_AVC_CLASS 实例。 此接口仅支持以下 I/O 控件 (IOCTL) 代码:
IOCTL_AVC_CLASS又支持多个函数代码。 支持对等子单元的 Avc.sys 实例的子驱动程序保证通过其父设备对象访问此接口。
GUID_AVC_CLASS 接口支持所有IOCTL_AVC_CLASS函数代码,尽管某些函数代码的使用存在限制,如每个函数的参考页中所述。
Avc.sys 将注册GUID_VIRTUAL_AVC_CLASS的新实例(如果已加载),以 (虚拟堆栈) 提供对虚拟 AV/C 子单元的支持。 此接口支持四个 I/O 控制 (IOCTL) 代码:
GUID_VIRTUAL_AVC_CLASS 接口不支持每个IOCTL_AVC_CLASS函数代码。 每个函数代码的引用页指定是否支持GUID_VIRTUAL_AVC_CLASS Avc.sys实例。
IOCTL_AVC_CLASS IRP 仅在内核模式下受支持, (通常通过 IRP_MJ_INTERNAL_DEVICE_CONTROL 进行驱动程序到驱动程序的通信) 。 因此,应用程序无法直接访问IOCTL_AVC_CLASS IOCTL 代码提供的函数。
通过 IRP_MJ_DEVICE_CONTROL,内核模式和用户模式都支持最后三个 IOCTL 代码。 这意味着应用程序可以直接将这些 IOCTL 发送到 Avc.sys。
IOCTL_AVC_CLASS IOCTL 代码必须始终附带 I/O 请求块 (IRB) ,该块进一步描述了要执行的 AV/C 操作。 IRB 标头包含一个函数编号,用于确定 IRB 其余部分的结构。 IRB 结构和大小因 函数而异。 Avc.sys 使用两个自定义 IRB:
选择子单元驱动程序必须使用哪个 IRB 取决于所需的函数。 有关Avc.sys 支持的IOCTL_AVC_CLASS函数代码的详细信息 , 请参阅 AV/C 协议驱动程序函数代码。
子单元驱动程序使用的主要 AV/C 函数 AVC_FUNCTION_COMMAND,它使用 AVC_COMMAND_IRB 结构。 AVC_FUNCTION_COMMAND 发送 AV/C 请求并接收相应的 AV/C 响应。 生成 AV/C 命令的详细信息由 Avc.sys处理,但子单元驱动程序必须提供每个命令的 AV/C 操作码和操作数。