Share via


LPWSPDUPLICATESOCKET コールバック関数 (ws2spi.h)

LPWSPDuplicateSocket 関数は、共有ソケットの新しいソケット記述子を作成するために使用できるWSAPROTOCOL_INFO構造体を返します。

構文

LPWSPDUPLICATESOCKET Lpwspduplicatesocket;

int Lpwspduplicatesocket(
  [in]  SOCKET s,
  [in]  DWORD dwProcessId,
  [out] LPWSAPROTOCOL_INFOW lpProtocolInfo,
  [out] LPINT lpErrno
)
{...}

パラメーター

[in] s

ローカル ソケット記述子。

[in] dwProcessId

共有ソケットが使用されるターゲット プロセスの識別子。

[out] lpProtocolInfo

WSAPROTOCOL_INFO構造体を格納するのに十分な大きさのクライアントによって割り当てられたバッファーへのポインター。 サービス プロバイダーは、プロトコル情報構造体の内容をこのバッファーにコピーします。

[out] lpErrno

エラー コードへのポインター。

戻り値

エラーが発生しない場合、 LPWSPDuplicateSocket は 0 を返します。 それ以外の場合は、SOCKET_ERRORの値が返され、 lpErrno で特定のエラー番号を使用できます。

エラー コード 意味
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAEINVAL
指定されたパラメーターのいずれかが無効であることを示します。
WSAEINPROGRESS
Windows ソケット呼び出しのブロックが進行中であるか、サービス プロバイダーがコールバック関数を処理しています。
WSAEMFILE
これ以上使用できるソケット記述子がありません。
WSAENOBUFS
バッファーに空き領域がありません。 ソケットを作成できません。
WSAENOTSOCK
記述子はソケットではありません。

解説

ソース プロセスは LPWSPDuplicateSocket を呼び出して、特別な WSAPROTOCOL_INFO 構造体を取得します。 一部のプロセス間通信 (IPC) メカニズムを使用して、この構造体の内容をターゲット プロセスに渡し、 LPWSPSocket の呼び出しでそれを使用して、複製されたソケットの記述子を取得します。 特殊な WSAPROTOCOL_INFO 構造は、ターゲット プロセスで 1 回しか使用できないことに注意してください。

ソース プロセス コンテキストで必要な操作を実行し、ターゲット プロセスのコンテキストで LPWSPSocket のパラメーターとして表示されたときに認識されるWSAPROTOCOL_INFO構造を作成するのは、サービス プロバイダーの責任です。 その後、プロバイダーは、共通の基になるソケットを参照するソケット記述子を返す必要があります。 WSAPROTOCOL_INFO構造体の dwProviderReserved メンバーは、サービス プロバイダーの使用に使用でき、重複したハンドルを含む任意の有用なコンテキスト情報を格納するために使用できます。

新しいソケット記述子が割り当てられると、インストール可能なファイル システム (IFS) プロバイダーは WPUModifyIFSHandle を呼び出す必要があり、IFS 以外のプロバイダーは WPUCreateSocketHandle を呼び出す必要があります。 IFS プロバイダーは DuplicateHandle 関数を使用できます。 ソケットの重複を適切に実行するには、IFS 以外のサービス プロバイダーが LPWSPDuplicateSocket 関数を使用する必要があります。

ハンドオフ モードで共有ソケットを確立して使用するシナリオの 1 つを次に示します。

Source process (依存元プロセス) IPC 説明
1) LPWSPSocketLPWSPConnect
2) ターゲット プロセス識別子を要求します。
==>
3) プロセス識別子要求を受信し、応答します。
4) プロセス識別子を受信します。
<==
5) 特別な WSAPROTOCOL_INFO 構造体を取得するために **LPWSPDuplicateSocket** を呼び出します。
6) WSAPROTOCOL_INFO 構造体をターゲットに送信します。
==> 7) WSAPROTOCOL_INFO 構造を受け取ります。
8) LPWSPSocket を呼び出して、共有ソケット記述子を作成します。
9) データ交換に共有ソケットを使用します。
10) LPWSPCloseSocket
<==

共有ソケットを参照する記述子は、I/O に関する限り、個別に使用できます。 ただし、Windows ソケット インターフェイスは、どの種類のアクセス制御も実装していないため、共有ソケットでの操作を調整するプロセスに依存します。 共有ソケットの一般的な用途は、ソケットの作成と接続の確立を担当する 1 つのプロセスを持ち、情報交換を担当する他のプロセスにソケットを渡すことです。

複製されるのは、基になるソケットではなくソケット記述子であるため、ソケットに関連付けられているすべての状態は、すべての記述子で共通に保持されます。 たとえば、1 つの記述子を使用して実行された WSPSetSockOpt 操作は、その後、任意またはすべての記述子の LPWSPGetSockopt を使用して表示されます。 プロセスは、重複したソケットで LPWSPCloseSocket を呼び出すことができます。記述子は割り当て解除されます。 ただし、基になるソケットは、 LPWSPClosesocket が最後の残りの記述子によって呼び出されるまで開いたままです。

共有ソケットでの通知には、 LPWSPAsyncSelect と LPWSPEventSelect の通常の制約が適用 されます。 共有記述子のいずれかを使用してこれらの呼び出しのいずれかを発行すると、その登録を行うために使用された記述子に関係なく、ソケットの以前のイベント登録が取り消されます。 したがって、たとえば、共有ソケットは、A を処理FD_READイベントを配信できず、B を処理するためにイベントFD_WRITE。このような緊密な調整が必要な状況では、開発者は別のプロセスではなくスレッドを使用することをお勧めします。

階層型サービス プロバイダーは、この関数の実装を提供しますが、プロトコル チェーン内の次のレイヤーの LPWSPDuplicateSocket を呼び出す場合、また、この関数のクライアントでもあります。 この関数の lpProtocolInfo パラメーターは、プロトコル チェーンのレイヤーを経由して伝達されるため、いくつかの特別な考慮事項が適用されます。

プロトコル チェーン内の次のレイヤーが別のレイヤーである場合、次のレイヤーの LPWSPDuplicateSocket が呼び出されると、このレイヤーは、同じ変更されていないチェーン情報を持つ同じ変更されていないWSAPROTOCOL_INFO構造を参照する lpProtocolInfo を次のレイヤーに渡す必要があります。 ただし、次のレイヤーが基本プロトコル (つまり、チェーン内の最後の要素) である場合、このレイヤーは、ベース プロバイダーの LPWSPDuplicateSocket を呼び出すときに置換を実行します。 この場合、ベース プロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターで参照する必要があります。

このポリシーの重要な利点の 1 つは、基本サービス プロバイダーがプロトコル チェーンを認識する必要ができないことです。 この同じポリシーは、LPWSPAddressToStringWSPStartupLPWSPSocketLPWSPStringToAddress などの他の関数の階層化されたシーケンスを介してWSAPROTOCOL_INFO構造体を伝達する場合にも適用されます。

要件

   
サポートされている最小のクライアント Windows 2000 Professional [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows 2000 Server [デスクトップ アプリのみ]
Header ws2spi.h

関連項目

WPUCreateSocketHandle

WPUModifyIFSHandle