LPWPUMODIFYIFSHANDLE
コールバックシグネチャ
SOCKET LPWPUMODIFYIFSHANDLE(
DWORD dwCatalogEntryId,
SOCKET ProposedHandle,
INT* lpErrno
);パラメーター
| フィールド | 型 | 説明 |
|---|---|---|
| dwCatalogEntryId | DWORD | 呼び出し元のサービスプロバイダーを識別する記述子です。 |
| ProposedHandle | SOCKET | プロバイダーが割り当てた IFS ハンドルです。 |
| lpErrno | INT* | エラーコードへのポインターです。 |
公式ドキュメント
WPUModifyIFSHandle 関数は、Ws2_32.dll から(場合によっては)変更された IFS ハンドルを受け取ります。
戻り値
エラーが発生しなかった場合、 WPUModifyIFSHandle は変更されたソケットハンドルを返します。それ以外の場合は INVALID_SOCKET を返し、具体的なエラーコードは lpErrno で取得できます。
| エラーコード | 意味 |
|---|---|
| 提案されたハンドルが無効です。 |
解説(Remarks)
WPUModifyIFSHandle ハンドルにより、WS2_32.dll は、渡された IFS ハンドルを場合によっては変更したものを返すことで、内部処理を効率化できます。返されるハンドルは、オペレーティングシステムから見て、提案されたハンドルと区別が付かないことが保証されます。IFS プロバイダーは、新しく作成したソケット記述子をサービスプロバイダーに返す前に、必ずこの関数を呼び出す必要があります。サービスプロバイダーは、以降のソケット操作では変更後のハンドルのみを使用します。このルーチンは、ソケット記述子が実際の IFS ハンドルであるIFS プロバイダーだけが使用します。
このプロシージャは、ベースとなる IFS プロバイダーの上に階層化されたプロバイダーが、 WPUCreateSocketHandle の呼び出しでハンドルを作成する代わりに、ベースプロバイダーのソケットハンドルを自身のものとして公開したい場合にも使用できます。チェーン内の次の層から受け取った IFS ソケットハンドルを「パススルー」したい階層化プロバイダーは、自身のカタログエントリ ID を dwCatalogEntryId として渡して WPUModifyIFSHandle を呼び出せます。これにより、そのソケットハンドルに関わる SPI 呼び出しの対象が、次の層ではなくこの層であることが Windows Sockets DLL に通知されます。
この方法を採用する場合、階層化プロバイダーが守るべきいくつかの制限があります。
- プロバイダーは、 WSPStartup の時点で返すプロシージャディスパッチテーブルに、 LPWSPSend と LPWSPRecv のベースプロバイダーのエントリポイントを公開し、Windows Sockets SPI クライアントからこれらの関数へのアクセスができるだけ効率的になるようにする必要があります。
- プロバイダーは、すべての I/O に対して自身の LPWSPSend および LPWSPRecv 関数が呼び出されることを前提にできません。特に、I/O システム関数である ReadFile や WriteFile の場合はそうです。これらの関数は、階層化プロバイダーがプロシージャディスパッチテーブルに自身のエントリポイントを登録していても、階層化プロバイダーをバイパスして、ベース IFS プロバイダーの実装を直接呼び出します。
- プロバイダーは、 LPWSPSend、 LPWSPSendTo、 LPWSPRecv、 LPWSPRecvFrom、 LPWSPIoctl を使ってオーバーラップ I/O を後処理できることを前提にできません。後処理の通知は完了ポートを経由して行われ、階層化プロバイダーを完全にバイパスすることがあります。階層化プロバイダーには、完了ポートが使用されたかどうかを判別する手段も、それがどのポートなのかを特定する手段もありません。また、通知のシーケンスに自身を割り込ませる手段もありません。
- プロバイダーは、すべてのオーバーラップ I/O 要求を、元のオーバーラップパラメーター(たとえば WSAOVERLAPPED 構造体や完了ルーチンのポインター)を使用して、ベースプロバイダーに直接パススルーする必要があります。また、 WSPGetOverlappedResult についてはベースプロバイダーのエントリポイントを公開する必要があります。一部のオーバーラップ I/O 要求は階層化プロバイダーを完全にバイパスできるため、階層化プロバイダーは、自身が結果を報告できるものと、下位プロバイダーの WSPGetOverlappedResult にパススルーしなければならないものとを区別するために、 WSAOVERLAPPED 構造体に確実にマークを付けることができません。これは事実上、 LPWSPIoctl が下位プロバイダーへのパススルー操作でなければならないことを意味します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)