ユーザーモード サービスから GenericUSBFn.sys と通信する
すべてのユーザー モード要求は Microsoft 提供のカーネル モード ドライバー GenericUSBFn.sys に送信されます。 これらの I/O 制御コード (IOCTL) を送信して GenericUSBFn.sys と通信する、ユーザー モード サービスを作成できます。GenericUSBFn.sys は USB ファンクション ドライバーとのカーネル モード通信を処理します。
Genericusbfnioctl.h で宣言した IOCTL は、ユーザー モード サービスから GenericUSBFn.sys と通信するために使用します。
以下の手順では、GenericUSBFn.sys とやり取りして USB ファンクション ドライバーと通信する USB インターフェイス サービスを定義する方法について説明します。
- 起動時に、サービスはデバイス インターフェイスの到着をリッスンします。 デバイス インターフェイス GUID は、OEM 定義のサブキー HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\USBFN\Interfaces 下のレジストリで宣言されている InterfaceGUID の値です。 デバイスの到着をリッスンするには、次の 2 つの一般的な方法があります。
- サービスの開始をトリガーする。 詳細については、「サービス トリガー イベント」を参照してください。
- デバイス インターフェイスの到着を登録する。 詳細については、「CM_Register_Notification 関数」を参照してください。
- インターフェイスが到着すると、サービスはデバイスへのハンドルを開きます。
- CM_Get_Device_Interface_List 関数を呼び出して、デバイスのシンボリック名を取得します。 レジストリ内の InterfaceGUID の値で宣言されているデバイス インターフェイス GUID を指定します。
- デバイスのシンボリック名を取得したら、CreateFile を使用してデバイスへのハンドルを開きます。
- このサービスは、IOCTL_GENERICUSBFN_GET_CLASS_INFO を発行して、レジストリで構成されている使用可能なパイプに関する情報を取得します。
- サービスは通信の準備ができると、IOCTL_GENERICUSBFN_ACTIVATE_USB_BUS を発行します。 すべてのクラス ドライバーがアクティブ化されると、USB ファンクション クラス拡張機能がホストに接続できるようになります。
- USB 通知を受信するために、サービスは IOCTL_GENERICUSBFN_BUS_EVENT_NOTIFICATION を発行します。 この IOCTL は、新しい USB イベントが発生すると完了します。 特に重要なイベント (USBFN_EVENT) には次のものがあります。
- UsbfnEventReset: 接続された USB デバイスの速度を特定するために使用します。
- UsbfnEventConfigured: サービスは転送要求を発行できるようになりました。
- UsbfnEventSetupPacket: USB ファンクション クラス拡張機能がインターフェイス固有のセットアップ パケットを受信しました (bmRequestType.Type == BMREQUEST_CLASS)。 サービスは、パイプ 0 で転送要求を発行し、続いてパイプ 0 で逆方向のハンドシェイク要求 (IOCTL_GENERICUSBFN_CONTROL_STATUS_HANDSHAKE_OUT) を発行することでセットアップ パケットに応答する必要があります。
- UsbfnEventConfigured イベントを受信すると、サービスは IOCTL_GENERICUSBFN_TRANSFER_IN、IOCTL_GENERICUSBFN_TRANSFER_IN_APPEND_ZERO_PKT、および IOCTL_GENERICUSBFN_TRANSFER_OUT を使用して転送要求を発行できるようになります。