Win32 API 日本語リファレンス
ホーム › Networking.WinSock › LPWPUCREATESOCKETHANDLE

LPWPUCREATESOCKETHANDLE

コールバック

シグネチャ

SOCKET LPWPUCREATESOCKETHANDLE(
    DWORD dwCatalogEntryId,
    UINT_PTR dwContext,
    INT* lpErrno
);

パラメーター

フィールド型説明
dwCatalogEntryIdDWORD呼び出し元のサービスプロバイダーを識別する記述子です。
dwContextUINT_PTR新しいソケットハンドルに関連付けるコンテキスト値です。
lpErrnoINT*エラーコードへのポインターです。

公式ドキュメント

WPUCreateSocketHandle 関数は、新しいソケットハンドルを作成します。

戻り値

エラーが発生しなかった場合、 WPUCreateSocketHandle は新しいソケットハンドルを返します。それ以外の場合は INVALID_SOCKET を返し、具体的なエラーコードは lpErrno で取得できます。

エラーコード 意味
WSAENOBUFS
新しいソケットハンドルを作成するための十分なバッファーがありません。

解説(Remarks)

WPUCreateSocketHandle 関数は、指定されたプロバイダー用に新しいソケットハンドルを作成します。 WPUCreateSocketHandle によって作成されたハンドルは、本物のファイルシステムハンドルと区別できません。これは 2 つの点で重要です。1 つ目は、Windows Socket 2 のアーキテクチャが、ファイルシステム関数 ReadFile と WriteFile を、このサービスプロバイダーの LPWSPRecv と LPWSPSend にそれぞれリダイレクトする点です。2 つ目は、完了ポートをサポートするオペレーティングシステムにおいて、Windows Sockets 2 のアーキテクチャが、ソケットハンドルへの完了ポートの関連付けと、それを使用したオーバーラップ I/O の完了報告をサポートする点です。

**注** ReadFile と WriteFile をリダイレクトする仕組みでは、リダイレクターに到達するためにユーザーモードからカーネルモードへの遷移が必然的に発生し、続いて [LPWSPRecv](nc-ws2spi-lpwsprecv.md) または [LPWSPSend](nc-ws2spi-lpwspsend.md) に到達するためにカーネルモードからユーザーモードへの遷移が発生します。復帰時には、これらの遷移が逆順にたどられます。これは大きなパフォーマンス上のペナルティになり得ます。 **WPUCreateSocketHandle** を使用してソケットハンドルを作成するサービスプロバイダーは、 WSAProtocol_Info 構造体に XP1_IFS_HANDLES を設定しないでください。クライアントは、XP1_IFS_HANDLES が指定されていないことを、**ReadFile** と **WriteFile** の使用を避けるべき指針として扱ってください。
**注** **WPUCreateSocketHandle** で作成されたソケットハンドルに対して完了ポートの仕組みを使用しても、特別なパフォーマンス上のペナルティはありません。サービスプロバイダーは、完了ポートが関係する可能性のあるオーバーラップ I/O 操作の完了を通知するために、 WPUCompleteOverlappedRequest を使用してください。クライアントは、完了通知用の完了ポートを作成、関連付け、使用するために、オペレーティングシステムの関数を自由に使用できます (たとえば CreateIoCompletionPort、GetQueuedCompletionStatus など。詳細は該当するオペレーティングシステムのドキュメントを参照してください)。なお、完了ポートは Windows Sockets 2 が提供する他の非同期通知メカニズムとは統合されていません。つまり、クライアントは複数のイベントと完了コールバックを含む複数待機を行えますが、その複数待機に完了ポートを含める定義済みの方法はありません。
**階層化サービスプロバイダーに関する考慮事項**

この手続きは、特に階層化サービスプロバイダー (Layered Service Provider) にとって重要です。階層化サービスプロバイダーは、クライアントに公開するソケットハンドルを作成する際に、 WPUModifyIFSHandle の代わりにこの手続きを使用できます。この手続きを使用する利点は、そのソケットに関わるすべての I/O 要求が、必ずこのサービスプロバイダーを経由することを保証できる点です。これは、クライアントがソケットをファイルシステムハンドルとみなして、ファイルシステム関数 ReadFile や WriteFile を呼び出した場合でも同様です (ただし、その前提にはパフォーマンス上の代償が伴います)。

すべての I/O がこの層を経由するという保証は、実際の I/O 操作の前後で I/O ストリームを処理する必要がある層にとって必須の要件です。 WPUCreateSocketHandle を使用してソケットハンドルを作成し、 WSPStartup の時点で適切なサービスプロバイダーインターフェイスの手続きディスパッチテーブルを指定することで、各 I/O 操作の開始にこの層が関与する機会が確保されます。クライアントがオーバーラップ I/O 操作を要求する場合、このサービスプロバイダー層は通常、I/O 完了通知の経路にも入る必要があります。

この理由を理解するために、クライアントがオーバーラップ I/O の完了通知のために完了ポートをソケットハンドルに関連付けた場合に何が起きるかを考えてみます。この完了ポートは、この層が公開するソケットハンドルに関連付けられており、次の層のソケットハンドルには関連付けられていません。この層には、完了ポートが関連付けられているかどうか、またそのポートが何であるかを知る手段がありません。この層が次の層の I/O 操作を呼び出すときには、次の層のソケットハンドルを使用します。次の層のソケットハンドルには、同じ完了ポートの関連付けがありません。そのため、何らかの追加の手当てがなければ、クライアントが期待する完了ポート通知は発生しません。

階層化サービスプロバイダーがこれに対処する一般的な方法は、次の層の I/O 操作を呼び出す際に、別のオーバーラップ I/O 構造体と別のオーバーラップ I/O パラメーターを代わりに使用することです。この代替のオーバーラップ I/O 構造体は、保存しておいたクライアントのオーバーラップ構造体とパラメーターを参照します。次の層の呼び出しではコールバック通知を設定します。コールバック通知が発生すると、この層は必要な後処理を行い、クライアントの代わりに保存しておいたオーバーラップ I/O 情報を取得し、代替の構造体を破棄して、適切な完了通知をクライアントに転送します。

出典・ライセンス: 上記「公式ドキュメント」の内容は Microsoft の Win32 API ドキュメント(MicrosoftDocs/sdk-api)を日本語に翻訳・改変したものです。© Microsoft Corporation. CC BY 4.0 で提供。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)