WSPStartup 関数 (ws2spi.h)

WSPStartup 関数は、クライアントによる Windows ソケット サービス プロバイダー インターフェイス (SPI) の使用を開始します。

構文

int WSPStartup(
  [in]  WORD                wVersionRequested,
  [out] LPWSPDATA           lpWSPData,
  [in]  LPWSAPROTOCOL_INFOW lpProtocolInfo,
  [in]  WSPUPCALLTABLE      UpcallTable,
  [out] LPWSPPROC_TABLE     lpProcTable
);

パラメーター

[in] wVersionRequested

呼び出し元が使用できる Windows ソケット SPI サポートの最上位バージョン。 上位バイトはマイナー バージョン (リビジョン) 番号を指定します。下位バイトはメジャー バージョン番号を指定します。

[out] lpWSPData

Windows ソケット サービス プロバイダーに関する情報を受け取る WSPDATA データ構造へのポインター。

[in] lpProtocolInfo

目的のプロトコルの特性を定義する WSAProtocol_Info 構造体へのポインター。 これは、1 つのプロバイダー DLL で複数の異なるサービス プロバイダーをインスタンス化できる場合に特に便利です。

[in] UpcallTable

WSPUpCallTable 構造体で渡された Winsock 2 DLL (Ws2_32.dll) アップコール ディスパッチ テーブル。

[out] lpProcTable

SPI 関数ポインターのテーブルへのポインター。 このテーブルは、 WSPProc_Table 構造体として返されます。

戻り値

WSPStartup 関数は、成功した場合は 0 を返します。 それ以外の場合は、次に示すエラー コードのいずれかを返します。

エラー コード 意味
WSASYSNOTREADY
ネットワーク サブシステムは使用できません。 このエラーは、ネットワーク サービスを提供するために使用する基になるシステムが現在使用されていないため、現時点で Windows ソケットの実装が機能しない場合に返されます。
WSAVERNOTSUPPORTED
Winsock.dll バージョンが範囲外です。 このエラーは、要求された Windows ソケット SPI サポートのバージョンがこの特定の Windows ソケット サービス プロバイダーによって提供されていない場合に返されます。
WSAEINPROGRESS
Windows Sockets 1.1 のブロック操作が進行中です。
WSAEPROCLIM
Windows ソケットの実装でサポートされるタスクの数の制限に達しました。
WSAEFAULT
lpWSPData パラメーターまたは lpProcTable パラメーターが無効です。

注釈

Windows ソケット 2 トランスポート サービス プロバイダーは、サービス プロバイダー初期化関数に使用される、エクスポートされた単一のプロシージャ エントリ ポイント WSPStartup を持つ DLL です。 他のすべてのサービス プロバイダー関数は、 lpProcTable パラメーターで WSPStartup 関数に渡されるサービス プロバイダーのディスパッチ テーブルを介して Winsock 2 DLL からアクセスできます。 サービス プロバイダー DLL は、必要な場合にのみ WinSock 2 DLL によってメモリに読み込まれ、サービスが不要になったときにアンロードされます。

サービス プロバイダー インターフェイスでは、トランスポート サービス プロバイダーが Winsock 2 DLL (upcalls) を呼び出して DLL サポート サービスを取得する状況も定義されています。 トランスポート サービス プロバイダーは、WSPStartup 関数に渡される UpcallTable パラメーターで Winsock 2 DLL の upcall ディスパッチ テーブルを返します。

WSPStartup 関数は、プロセスごとに Windows ソケット SPI クライアントによって呼び出される最初の Windows ソケット SPI 関数である必要があります。 これにより、クライアントは必要な Windows ソケット SPI のバージョンを指定し、そのアップコール ディスパッチ テーブルを提供できます。 Windows Sockets サービス プロバイダーによって作成されたすべてのアップコール (つまり、WPU のプレフィックスが付いた関数) は、クライアントの upcall ディスパッチ テーブルを介して呼び出されます。 この関数を使用すると、クライアントは特定の Windows ソケット サービス プロバイダーの実装の詳細を取得することもできます。 Windows ソケット SPI クライアントは、 WSPStartup 呼び出しが成功した後にのみ、さらに Windows ソケット SPI 関数を発行できます。 SPI 関数の残りの部分へのポインターのテーブルは、WSPProc_Table構造体を返す lpProcTable パラメーターを使用して取得されます。

Winsock 2 DLL は、標準の Windows 動的ライブラリ読み込みメカニズムを使用してサービス プロバイダーのインターフェイス DLL をシステムに読み込み、 WSPStartup 関数を呼び出して初期化します。 これは通常、インターフェイス DLL がメモリに現在読み込まれていないサービス プロバイダーに関連付けられる新しいソケットを作成するために、 ソケット または WSASocket 関数を呼び出すアプリケーションによってトリガーされます。

今後のバージョンの Windows ソケット SPI と Ws2_32.dll をサポートするために、現在の Windows ソケット SPI と機能上の違いがある場合は、 WSPStartup でネゴシエーションが行われます。 WSPStartup の呼び出し元 (Ws2_32.dll または階層化されたプロトコル) と Windows ソケット サービス プロバイダーは、サポートできる Windows ソケットの最高バージョンを互いに示し、それぞれが他方の最高バージョンが許容可能であることを確認します。 WSPStartup に入ると、Windows ソケット サービス プロバイダーはクライアントによって要求されたバージョンを調べます。 このバージョンがサービス プロバイダーでサポートされている最も低いバージョン以上の場合、呼び出しは成功し、サービス プロバイダーは WSPDATA 構造体の wHighVersion メンバーでサポートされている最も高いバージョンを返し、wVersion メンバーでは wVersionRequested パラメーターで指定された上位バージョンとバージョンの最小値を返します。 その後、Windows ソケット サービス プロバイダーは、Windows Sockets SPI クライアントが wVersion メンバーで指定されたバージョンの Windows ソケットを使用することを前提としています。 WSPDATA 構造体の wVersion メンバーが呼び出し元に受け入れられない場合は、LPWSPCleanup を呼び出して、別の Windows ソケット サービス プロバイダーを検索するか、初期化に失敗する必要があります。

このネゴシエーションにより、Windows ソケット サービス プロバイダーと Windows ソケット SPI クライアントの両方で、さまざまな Windows ソケット バージョンをサポートできます。 バージョン範囲に重複がある場合、クライアントは Windows ソケット サービス プロバイダーを正常に利用できます。

Windows ソケット仕様の現在のバージョンはバージョン 2.2 です。 現在の Winsock DLL Ws2_32.dllでは、次のいずれかのバージョンの Windows ソケット仕様を要求するアプリケーションがサポートされています。

  • 1.0
  • 1.1
  • 2.0
  • 2.1
  • 2.2

上位バージョンの Windows ソケット仕様の新しい構文に完全にアクセスするには、アプリケーションがこの上位バージョンに対してネゴシエートする必要があります。 この場合、 wVersionRequested パラメーターは、バージョン 2.2 を要求するように設定する必要があります。 また、アプリケーションは、適切なヘッダー ファイルに対するコンパイル、新しいライブラリとのリンク、その他の特殊なケースなど、その上位バージョンの Windows ソケット仕様に完全に準拠している必要があります。 Winsock 2 サポート用の Winsock2.h ヘッダー ファイルは、Microsoft Windows ソフトウェア開発キット (Windows SDK) (SDK) に含まれています。

Windows ソケット バージョン 2.2 は、Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP、Windows 2000、Windows NT 4.0 Service Pack 4 (SP4) 以降、Windows Me、Windows 98、Windows 95 OSR2 でサポートされています。 Windows ソケット バージョン 2.2 も でサポートされています
Windows 95 と Windows Socket 2 Update。 これらのプラットフォーム上のアプリケーションでは、通常、 wVersionRequested パラメーターを適宜設定して Winsock 2.2 を要求する必要があります。

Windows 95 および Windows NT 3.51 以前のバージョンでは、Windows ソケット バージョン 1.1 がサポートされている Windows ソケット仕様の最上位バージョンです。

Winsock DLL でサポートされている Windows ソケット仕様の下位バージョンを使用するように記述されたアプリケーションまたは DLL が 、WSPStartup 関数を使用してこの下位バージョンを正常にネゴシエートすることは有効であり、可能です。 たとえば、アプリケーションは、Winsock 2.2 DLL を使用してプラットフォーム上の WSPStartup 関数に渡される wVersionRequested パラメーターでバージョン 1.1 を要求できます。 この場合、アプリケーションは、要求されたバージョンに適合する機能にのみ依存する必要があります。 新しい Ioctl コード、既存の関数の新しい動作、および新しい関数は使用しないでください。 WSPStartup によって提供されたバージョン ネゴシエーションは、主に、Windows 95 および Windows NT 3.51 以前用に開発された古い Winsock 1.1 アプリケーションを、新しいバージョンの Windows で同じ動作で実行できるようにするために使用されました。 Winsock 1.1 サポートの Winsock.h ヘッダー ファイルは、Windows SDKに含まれています。

次のグラフは、 WSPStartup がさまざまな WS2_32.DLL および Windows ソケット サービス プロバイダー (SP) バージョンと組み合わせて動作する方法の例を示しています。

[DLL]
 
versions
SP
 
versions
wVersionRequested wVersion wHighVersion 最終結果
1.1 1.1 1.1 1.1 1.1 use 1.1
1.0 1.1 1.0 1.1 1.0 1.0 1.0 を使用する
1.0 1.0 1.1 1.0 1.0 1.1 1.0 を使用する
1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.1 1.0 1.1 1.0 1.0 DLL が失敗する
1.0 1.1 1.0 --- --- WSAVERNOTSUPPORTED
1.0 1.1 1.0 1.1 1.1 1.1 1.1 use 1.1
1.0 1.1 2.0 1.1 2.0 1.1 1.1 use 1.1
1.0 1.1 2.0 2.0 2.0 2.0 2.0 2.0 を使用する
1.0 1.1 2.0 2.1 2.2 2.2 2.2 2.2 2.2 2.2 を使用する
 

次のコード フラグメントは、Windows ソケット SPI のバージョン 2 のみをサポートする Windows ソケット SPI クライアントが WSPStartup 呼び出しを行う方法を示しています。

WORD wVersionRequested;
WSPDATA WSPData;
 
int err;
 
WSPUPCALLTABLE upcallTable =
{ 
    /* initialize upcallTable with function pointers */
};
 
LPWSPPROC_TABLE lpProcTable =
{ 
    /* allocate memory for the ProcTable */
};
 
wVersionRequested = MAKEWORD( 2, 2 );
 
err = WSPStartup( wVersionRequested, &WSPData, lpProtocolBuffer, upcallTable, lpProcTable );
if ( err != 0 ) {
    /* Tell the user that we could not find a usable */
    /* Windows Sockets service provider.                     */
    return;
}
 
/* Confirm that the Windows Sockets service provider supports 2.2.*/
/* Note that if the service provider supports versions */
/* greater than 2.2 in addition to 2.2, it will still */
/* return 2.2 in wVersion since that is the version we  */
/* requested.                                           */
 
if ( LOBYTE( WSPData.wVersion ) != 2 ||
         HIBYTE( WSPData.wVersion ) != 2 ) {
    /* Tell the user that we could not find a usable */
    /* Windows Sockets service provider.                     */
    LPWSPCleanup( );
    return;   
}
 
/* The Windows Sockets service provider is acceptable. Proceed. */

このコード フラグメントは、バージョン 2.2 のみをサポートする Windows ソケット サービス プロバイダーが WSPStartup ネゴシエーションを実行する方法を示しています。

/* Make sure that the version requested is >= 2.2.  */
/* The low byte is the major version and the high   */
/* byte is the minor version.                       */
 
if ( (LOBYTE( wVersionRequested ) < 2) ||
     ((LOBYTE( wVersionRequested ) == 2) &&
     (HIBYTE( wVersionRequested ) < 2))) {
    return WSAVERNOTSUPPORTED;
}
 
/* Since we only support 2.2, set both wVersion and  */
/* wHighVersion to 2.2.                              */
 
lpWSPData->wVersion = MAKEWORD( 2, 2 );
lpWSPData->wHighVersion = MAKEWORD( 2, 2 );


Windows ソケット SPI クライアントが WSPStartup 呼び出しに成功すると、必要に応じて他の Windows ソケット SPI 呼び出しを行うことができます。 Windows ソケット サービス プロバイダーのサービスの使用が完了したら、クライアントが LPWSPCleanup を呼び出して、Windows ソケット サービス プロバイダーがクライアントに割り当てられたリソースを解放できるようにする必要があります。

WSPStartup 関数は、クライアント プロセスごとに少なくとも 1 回呼び出す必要があり、Winsock 2 DLL またはその他のエンティティによって複数回呼び出される場合があります。 WSPStartup 呼び出しが成功するたびに、一致する LPWSPCleanup 関数を呼び出す必要があります。 サービス プロバイダーは、プロセスごとに参照カウントを維持する必要があります。 各 WSPStartup 呼び出しで、呼び出し元はサービス プロバイダー DLL でサポートされている任意のバージョン番号を指定できます。

サービス プロバイダーは、WSPStartup 関数によって UpcallTable パラメーターとして受け取られたクライアントの upcall ディスパッチ テーブルへのポインターをプロセスごとに格納する必要があります。 特定のプロセスが WSPStartup を 複数回呼び出す場合、サービス プロバイダーは、最後に指定された upcall ディスパッチ テーブル ポインターのみを使用する必要があります。

Windows ソケット SPI クライアントは 、WSPDATA 構造体情報を複数回取得する必要がある場合に 、WSPStartup を複数回呼び出すことができます。 このような呼び出しごとに、クライアントはプロバイダーでサポートされている任意のバージョン番号を指定できます。

サードパーティの DLL が Windows ソケット プロバイダーを使用できるようにするには、WSPStartup 呼び出しが成功するたびに対応する LPWSPCleanup 呼び出しが 1 つ必要です。 つまり、たとえば、 WSPStartup が 3 回呼び出された場合、 対応する LPWSPCleanup の呼び出しが 3 回発生する必要があります。 LPWSPCleanup への最初の 2 回の呼び出しでは、内部カウンターをデクリメントする以外は何も行われません。最終的な LPWSPCleanup 呼び出しでは、必要なすべてのリソース割り当て解除が行われます。

この関数 (およびその他のほとんどのサービス プロバイダー関数) は、クライアントが 16 ビット Windows ソケット 1.1 クライアントの場合、16 ビット プロセスとして開始されたスレッドで呼び出すことができます。 16 ビット プロセスの重要な制限の 1 つは、16 ビット プロセスでスレッドを作成できないことです。 これは、実装の一部として内部サービス スレッドを使用することを計画しているサービス プロバイダーの実装者にとって重要です。

幸いなことに、通常、サービス スレッドの条件が強い領域は 2 つだけです。

これらの領域は、32 ビット プロセスでのみ呼び出すことができる新しい Windows ソケット 2 関数を介してのみアクセスできます。

次の 2 つの設計規則に慎重に従う場合は、サービス スレッドを安全に使用できます。

  • サービス スレッドは、16 ビット Windows ソケット 1.1 クライアントで使用できない機能にのみ使用します。
  • オンデマンドでのみサービス スレッドを作成します。

内部サービス スレッドの使用には、他にもいくつかの注意が必要です。 最初に、スレッドには通常、パフォーマンスの低下が発生します。 できるだけ少ない数を使用し、可能な限りスレッド遷移を回避します。 次に、コードでは、スレッドを作成する際のエラーを常にチェックし、正常かつ有益に失敗する必要があります (WSAEOPNOTSUPP など)。

階層型サービス プロバイダーは、この関数の実装を提供しますが、 WSPStartup を呼び出してプロトコル チェーン内の次のレイヤーを初期化する場合も、この関数のクライアントです。 次のレイヤーの WSPStartup の呼び出しは、このレイヤーの WSPStartup の実行中に発生する可能性があります。また、 LPWSPSocket が呼び出されたときなど、遅延してオンデマンドで呼び出される可能性があります。 いずれの場合も、この関数の lpProtocolInfo パラメーターがプロトコル チェーンのレイヤーを介して伝達されるため、いくつかの特別な考慮事項が適用されます。

階層化プロバイダーは、lpProtocolInfo によって参照される構造体の ProtocolChain を検索して、チェーン内の独自の場所 (レイヤーのカタログ エントリ ID を検索することによって) とチェーン内の次の要素の ID を決定します。 次の要素が別のレイヤーの場合、次のレイヤーの WSPStartup が呼び出されると、このレイヤーは、同じ変更されていないチェーン情報を持つ同じ変更されていないWSAProtocol_Info構造を参照する lpProtocolInfo を次のレイヤーに渡す必要があります。 ただし、次のレイヤーが基本プロトコル (つまり、チェーン内の最後の要素) である場合、このレイヤーは、ベース プロバイダーの WSPStartup を呼び出すときに置換を実行します。 この場合、ベース プロバイダーの WSAPROTOCOL_INFO 構造体は lpProtocolInfo パラメーターによって参照する必要があります。

このポリシーの重要な利点の 1 つは、基本サービス プロバイダーがプロトコル チェーンを認識する必要ができないことです。

この同じ伝達ポリシーは、LPWSPAddressToString、LPWSPDuplicateSocket、LPWSPSocketLPWSPStringToAddress などの他の関数のレイヤーシーケンスを介してWSAPROTOCOL_INFO構造体を伝達する場合にも適用されます。

要件

要件
サポートされている最小のクライアント Windows 2000 Professional [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows 2000 Server [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー ws2spi.h

こちらもご覧ください

WSAProtocol_Info

LPWSPAddressToString

LPWSPStringToAddress

LPWSPCleanup

LPWSPDuplicateSocket

LPWSPEventSelect

WSPProc_Table

LPWSPSend

LPWSPSendTo

LPWSPSocket

WSPUpCallTable