After Windows loads and initializes Avc.sys, Avc.sys uses standard AV/C unit and subunit commands to discover the active subunits on all AV/C devices connected to the IEEE 1394 bus (including any virtual subunits when the computer is a virtual AV/C unit). Avc.sys then generates device identifiers (IDs) for all of the active subunits. Next, Avc.sys uses standard Plug and Play (PnP) mechanisms to load the appropriate subunit driver for each subunit. The subunit driver to be loaded is selected based on the INF file that installs the subunit driver, and the subunit's device identifier, as generated by Avc.sys and described in AV/C Device IDs. The device identifier is generated from the unit information of the AV/C device, in combination with the subunit's SubunitType and SubunitID fields. The driver that supports a subunit can be vendor-specific, or it can be generic for the type of subunit. For example, the subunit driver for most DV camcorders is the Microsoft-provided Msdv.sys.
Subunit drivers communicate with Avc.sys through the standard IRP-based mechanism employed by all drivers based upon the WDM architecture. A subunit driver communicates with its AV/C subunit by allocating and sending IRPs down the driver stack to the AV/C protocol driver, Avc.sys. To make I/O requests, include the header file Avc.h, which is shipped with the Microsoft Windows Driver Kit (WDK).
A subunit driver allocates and initializes IRPs to be processed by Avc.sys. A subunit driver sets the IRP's Parameters.DeviceIoControl.IoControlCode member to the IOCTL that corresponds to the desired AV/C operation.
Avc.sys registers one of two device interfaces, depending upon which subunit driver stack that it was loaded to support (peer or virtual). These interfaces define the functionality that Avc.sys exports for subunit drivers, other drivers, and applications to use. Avc.sys then changes the interface's state to enabled or disabled according to the driver's PnP state.
Avc.sys registers a new instance of GUID_AVC_CLASS if it was loaded to provide support for external AV/C subunits (the peer stack). This interface supports only the following I/O control (IOCTL) code:
IOCTL_AVC_CLASS in turn supports multiple function codes. Child drivers of instances of Avc.sys to support peer subunits are guaranteed to have access to this interface through their parent device object.
The GUID_AVC_CLASS interface supports all IOCTL_AVC_CLASS function codes, although some have limitations on their use, as described in the reference pages for each function.
Avc.sys registers a new instance of GUID_VIRTUAL_AVC_CLASS, if it was loaded, to provide support for virtual AV/C subunits (the virtual stack). This interface supports four I/O control (IOCTL) codes:
The GUID_VIRTUAL_AVC_CLASS interface does not support every IOCTL_AVC_CLASS function code. The reference page for each individual function code specifies whether it is supported for GUID_VIRTUAL_AVC_CLASS instances of Avc.sys.
IOCTL_AVC_CLASS IRPs are only supported in kernel mode (generally for driver-to-driver communication) through IRP_MJ_INTERNAL_DEVICE_CONTROL. Therefore, applications cannot directly access the functions provided by the IOCTL_AVC_CLASS IOCTL code.
The last three IOCTL codes are supported in both kernel-mode and user-mode through IRP_MJ_DEVICE_CONTROL. This means that applications can send these IOCTLs directly to Avc.sys.
The IOCTL_AVC_CLASS IOCTL code must always be accompanied by an I/O request block (IRB), which further describes the AV/C operation to perform. The IRB header includes a function number, which determines the structure of the rest of the IRB. The IRB structure and size varies according to the function. Avc.sys uses two custom IRBs:
The choice of which IRB a subunit driver must use depends on the desired function. For more information about the IOCTL_AVC_CLASS function codes supported by Avc.sys, see AV/C Protocol Driver Function Codes.
The primary AV/C function used by subunit drivers is AVC_FUNCTION_COMMAND, which uses the AVC_COMMAND_IRB structure. AVC_FUNCTION_COMMAND sends AV/C requests and receives the corresponding AV/C responses. Details for building AV/C commands are handled by Avc.sys, but the subunit driver must provide the AV/C opcode and operands of each command.