USB デバイス用の Windows デスクトップ アプリ
この記事では、アプリケーションが WinUSB 関数を呼び出して USB デバイスと通信する方法について説明します。 そのようなアプリケーションの場合、WinUSB (Winusb.sys) をデバイスのファンクション ドライバーとしてインストールする必要があります。 デバイスのカーネル モード スタックに WinUSB があります。 このドライバーは Windows の \Windows\System32\drivers フォルダーに含まれています。
Winusb.sys を USB デバイスのファンクション ドライバーとして使用している場合は、アプリケーションから WinUSB 関数を呼び出してデバイスと通信できます。 これらの関数は、ユーザー モード DLL Winusb.dll によって公開されており、通信プロセスが簡素化されます。 標準的な USB 操作 (デバイスの構成、制御要求の送信、デバイスとの間のデータ転送など) を実行するデバイス I/O 制御要求を作成する代わりに、アプリケーションは同等の WinUSB 関数を呼び出します。
Winusb.dll は、アプリケーションから提供されたデータを使用して適切なデバイス I/O 制御要求を作成し、その要求を処理のために Winusb.sys に送信します。 USB スタックと通信するために、WinUSB 関数はアプリケーションの要求に関連する適切な IOCTL で DeviceIoControl 関数を呼び出します。 要求が完了すると、WinUSB 関数は Winusb.sys から返された情報 (読み取り要求からのデータなど) を呼び出し元のプロセスに返します。 DeviceIoControl の呼び出しが成功すると、0 以外の値が返されます。 呼び出しが失敗した場合、または保留中 (すぐに処理されない) 場合、DeviceIoControl は 0 の値を返します。 エラーが発生した場合、アプリケーションは GetLastError を呼び出して、より詳細なエラー メッセージを取得できます。
ドライバーを実装するよりも、WinUSB 関数を使用してデバイスと通信する方が簡単です。 ただし、次の制限事項に注意してください。
WinUSB 関数を使用する場合、同時に 1 つのアプリケーションのみがデバイスと通信できます。 同時に複数のアプリケーションがデバイスと通信するようにする場合は、ファンクション ドライバーを実装する必要があります。
Windows 8.1 より前では、WinUSB 関数はアイソクロナス エンドポイントとの間のストリーミング データをサポートしていません。
WinUSB 関数は、既にカーネル モードでサポートされているデバイスをサポートしていません。 そのようなデバイスの例としては、モデムやネットワーク アダプターがあり、それぞれテレフォニー API (TAPI) や NDIS でサポートされています。
多機能デバイスの場合、デバイスの INF ファイルを使用して、USB ファンクション別にインボックス カーネル モード ドライバーまたは Winusb.sys を指定できます。 ただし、特定の USB ファンクションに指定できるのはいずれか一方のみで、両方を指定することはできません。
Note
WinUSB 関数には Windows XP 以降が必要です。 これらの関数を C/C++ アプリケーションで使用して、USB デバイスと通信することができます。 WinUSB API を使用する UWP アプリを作成するには、「USB デバイス用の UWP アプリ」を参照してください。
作業の開始
デバイス用の Windows デスクトップ アプリの作成に必要なツールを入手します。
- 「Windows Driver Kit のダウンロード」の手順に従ってください。
テスト USB デバイスとそのハードウェア仕様を入手します。
この仕様を使用して、アプリの機能を確定し、関連する設計上の意思決定を行います。
Microsoft USB Test Tool (MUTT) デバイスは JJG Technologies から入手できます。 このデバイスには、「MUTT ソフトウェア パッケージのダウンロード」で入手できる Microsoft のファームウェアが必要です。
デバイスへのハンドルを取得するスケルトンアプリを作成します。
最初のアプリケーションを作成するには 2 つのアプローチがあります。
Visual Studio に含まれる WinUSB テンプレートに基づいて作成します。 詳細については、「WinUSB テンプレートに基づいて Windows デスクトップ アプリを作成する」を参照してください。
SetupAPI ルーチンを呼び出してデバイスへのハンドルを取得し、WinUsb_Initialize を呼び出してそのハンドルを開きます。 詳細については、「WinUSB 関数を使用して USB デバイスにアクセスする方法」を参照してください。
デバイスに Winusb.sys をインストールします。
Visual Studio を使用している場合は、Visual Studio のデプロイを使用してターゲット コンピューターにドライバー パッケージをインストールします。 手順については、「WinUSB テンプレートに基づいて Windows デスクトップ アプリを作成する」を参照してください。 それ以外の場合は、カスタム INF を作成して、デバイス マネージャーにドライバーを手動でインストールします。 詳細については、「WinUSB (Winusb.sys) のインストール」を参照してください。
デバイスに関する情報を取得し、その記述子を表示します。
概念的な情報については、「すべての USB 開発者向けの概念」を参照してください。 構成記述子、サポートされている各代替設定のインターフェイス記述子、それらのエンドポイント記述子を読んで、デバイスの機能に関する情報を取得します。 詳細については、「デバイスに USB 記述子を照会する」を参照してください。
USB コントロール転送を送信します。
標準の制御要求とベンダー コマンドをデバイスに送信します。 詳細については、「既定のエンドポイントにコントロール転送を送信する」を参照してください。
バルク転送または割り込み転送を送信します。
デバイスでサポートされているバルク、割り込み、およびアイソクロナス エンドポイントとの間で読み取りおよび書き込み操作を実行します。 詳細については、「I/O 要求を発行する」を参照してください。
アイソクロナス転送を送信します。
主にデータのストリーミング用にアイソクロナス読み取りおよび書き込み要求を送信します。 この機能は Windows 8.1 以降でのみ使用できます。 詳細については、「WinUSB デスクトップ アプリから USB アイソクロナス転送を送信する」を参照してください。