次の方法で共有


UMDFでの I/O 要求の完了

警告

UMDF 2 は UMDF の最新バージョンであり、UMDF 1 に取って代わるものです。 すべての新しい UMDF ドライバーは、UMDF 2 を使用して記述する必要があります。 UMDF 1 には新機能が追加されておらず、Windows 10 の新しいバージョンでは UMDF 1 のサポートが制限されています。 ユニバーサル Windows ドライバーでは、UMDF 2 を使用する必要があります。

アーカイブされた UMDF 1 サンプルは、Windows 11, バージョン 22H2 - 2022 年 5 月 ドライバー サンプル アップデートでご確認いただけます。

詳しくは、UMDFの概要をご覧ください。

すべての I/O 要求は、最終的に UMDF ドライバーによって完了する必要があります。 要求を完了するには、ドライバーが IWDFIoRequest::Complete または IWDFIoRequest::CompleteWithInformation メソッドを呼び出す必要があります。 ドライバーが要求を完了すると、次のいずれかのシナリオが示されます。

  • 要求された I/O 操作が正常に完了しました。

  • 要求された I/O 操作は開始されましたが、完了する前に失敗しました。

  • 要求された I/O 操作はサポートされていないか、受信した時点では無効であるため、デバイスと通信できません。

  • 要求された I/O 操作が 取り消されました

ドライバーは IWDFIoRequest ::CompleteWithInformation メソッドを呼び出して、要求操作に関する追加情報を渡します。 たとえば、読み取り操作の場合、ドライバーは読み取ったバイト数を指定する必要があります。

I/O 要求を完了するには、ドライバーは IWDFIoRequest::Complete または IWDFIoRequest::CompleteWithInformation の呼び出しで、CompletionStatus パラメーターに適切な完了状態を渡す必要があります。 ドライバーは、HRESULT コードを使用して、完了した要求の状態を伝えます。

UMDF ドライバー ホスト プロセスは、完了した要求をリフレクター (Wudfrd.sys) に渡す前に、HRESULT コードを NTSTATUS コードに変換します。 リフレクタは NTSTATUS コードをオペレーティング システムに渡します。 オペレーティング システムは、NTSTATUS コードを Microsoft Win32 エラー コードに変換してから、呼び出し元のアプリケーションに結果を表示します。

ドライバーのエラー コードを正しく変換できるようにするには、次のいずれかの方法でエラー コードを作成する必要があります。

  • Winerror.h のエラー コードを使用し、HRESULT_FROM_WIN32 マクロを適用します。

  • Ntstatus.h のエラー コードを使用し、HRESULT_FROM_NT マクロを適用します。

これらのマクロの詳細については、Microsoft Windows SDK のドキュメントを参照してください。

次のコード例は、適切なエラー コードを使用して要求を完了する方法を示しています。

VOID
STDMETHODCALLTYPE
CMyQueue::OnWrite(
    __in IWDFIoQueue *pWdfQueue,
    __in IWDFIoRequest *pWdfRequest,
    __in SIZE_T BytesToWrite
    )
{
            -------------------- 
    if( BytesToWrite > MAX_WRITE_LENGTH ) {
        pWdfRequest->CompleteWithInformation(HRESULT_FROM_WIN32(ERROR_MORE_DATA), 0);
        return;
    }
            ---------------------
}

ドライバーは、要求が正常に完了すると、HRESULT 値であるS_OKを返します。 S_OKは Winerror.h の NO_ERROR と Ntstatus.h の STATUS_SUCCESS に相当するため、変換マクロは必要ありません。

リフレクターに対してドライバー検証ツールが有効になっている場合は、無効な状態コードが識別され、システム バグチェックが発生します。

注: Windows XP のドライバー検証ツールでは、値が 10 進数の 1024 (1024L) を超える Win32 エラー コードに対して、誤ってシステム バグチェックが発生します。 ドライバーが Windows XP で実行されている場合は、リフレクターのドライバー検証ツールを有効にした場合、この問題に注意してください。

ドライバーが以前に下位レベルのドライバーに要求を送信した場合、ドライバーは、下位レベルのドライバーが要求を完了したときに通知を必要とします。 通知を登録するために、ドライバーは IWDFIoRequest::SetCompletionCallback メソッドを呼び出して、下位レベルのドライバーが要求を完了したときにフレームワークが呼び出すメソッドのインターフェイスを登録します。 ドライバーは、要求を完了するために必要な操作を実行する IRequestCallbackRequestCompletion::OnCompletion コールバック関数を実装します。

ドライバーは、IWDFDevice::CreateRequest を呼び出して作成した I/O 要求を完了しません。 代わりにドライバーは、通常 I/O ターゲットが要求を完了した後に、IWDFObject::D eleteWdfObject を呼び出して要求オブジェクトを削除する必要があります。です。

たとえば、ドライバーは、ドライバーの I/O ターゲットが一度に処理できるよりも大きい量のデータの読み取りまたは書き込み要求を受け取る場合があります。 ドライバーは、データを複数の小さな要求に分割し、これらの小さな要求を 1 つ以上の I/O ターゲットに送信する必要があります。 この状況を処理する手法は次のとおりです。

  • IWDFDevice::CreateRequest を呼び出して、より小さな要求を表す 1 つの追加要求オブジェクトを作成します。

    ドライバーは、I/O ターゲットに同期的にこの要求を送信できます。 小さい要求の IRequestCallbackRequestCompletion::OnCompletion コールバック関数は、IWDFIoRequest2::Reuse を呼び出して、ドライバーが要求を再利用して I/O ターゲットに再度送信できるようにします。 I/O ターゲットが最後の小さい要求を完了すると、OnCompletion コールバック関数は IWDFObject::D eleteWdfObject を呼び出してドライバーが作成した要求オブジェクトを削除し、ドライバーは IWDFIoRequest::Complete を呼び出して元の要求を完了できます。

  • IWDFDevice::CreateRequest を呼び出して、より小さな要求を表す複数の追加要求オブジェクトを作成します。

    ドライバーの I/O ターゲットは、これらの複数の小さな要求を非同期的に処理できます。 ドライバーは、小さい要求ごとに OnCompletion コールバック関数を登録できます。 OnCompletion コールバック関数が呼び出されるたびに、IWDFObject::D eleteWdfObject を呼び出して、ドライバーによって作成された要求オブジェクトを削除できます。 I/O ターゲットがすべての小さい要求を完了すると、ドライバーは IWDFIoRequest::Complete を呼び出して元の要求を完了できます。

完了情報の取得

別のドライバーが完了した I/O 要求に関する情報を取得するには、UMDF ベースのドライバーは次のことができます。

  • IWDFRequestCompletionParams インターフェイスを使用して、I/O 要求の完了状態やその他の情報を取得します。

  • IWDFIoRequestCompletionParams インターフェイスを使用して、I/O 要求のメモリ バッファーを取得します。

  • IWDFUsbRequestCompletionParams インターフェイスを使用して、USB ターゲット パイプ オブジェクトに送信された要求に関連するメモリ バッファーやその他の情報を取得します。

さらに、UMDF ベースのドライバーは、IWDFIoRequest2::GetStatus メソッドを使用して、要求が完了する前または後に、I/O 要求の現在の状態を取得できます。