そのプロトコルについての情報を取得しなければなりません。その中から適切なものを選択することになります。lpErrno);lpiProtocolsは、列挙したいプロトコルの値を格納したNULLで終了する配列を指定します。全てのプロトコルを列挙したい場合は、NULLを指定します。lpProtocolBufferは、WSAPROTOCOL_INFOW構造体の配列を受け取るバッファを指定します。lpdwBufferLengthは、lpProtocolBufferのサイズを格納した変数のアドレスを指定します。lpProtocolBufferがNULLの場合は、必要なサイズが返ります。lpErrnoは、エラーコードを受け取る変数のアドレスを指定します。エラーが発生していない場合は、NO_ERRORが格納されます。戻り値は、バッファに格納されたプロトコル数です。WSCEnumProtocolsで列挙できる情報は、WSAEnumProtocolsという関数でも列挙することができます。LSPのインストールする場合はできるだけWSCEnumProtocolsを呼び出した方がよいでしょう。後述するダミーエントリも列挙されないからです。WSAPROTOCOL_INFOW構造体は、次のように定義されています。*LPWSAPROTOCOL_INFO;dwServiceFlags1は、プロトコルが提供しているサービスを表す定数が格納されます。dwServiceFlags2からdwServiceFlags4は、予約されているため0が格納されます。dwProviderFlagsは、プロトコルカタログについて定義する定数が格納されます。ProviderIdは、このエントリのGUIDが格納されます。dwCatalogEntryIdは、プロトコルのエントリIDが格納されます。ProtocolChainは、WSAPROTOCOLCHAIN構造体へのアドレスが格納されます。iVersionは、プロトコルのバージョンを表す識別子が格納されます。iAddressFamilyは、アドレスファミリが格納されます。iMaxSockAddrは、アドレス情報の最大値が格納されます。iMinSockAddrは、アドレス情報の最小値が格納されます。iSocketTypeは、ソケットタイプが格納されます。iProtocolは、実装するプロトコルの値が格納されます。iProtocolMaxOffsetは、iProtocolに指定されるかもしれない最大値が格納されます。iNetworkByteOrderは、バイトオーダーを表す定数が格納されます。iSecuritySchemeは、セキュリティスキームのタイプが格納されます。dwMessageSizeは、データ送信における最大サイズが格納されます。dwProviderReservedは、予約されているため0が格納されます。szProtocolは、プロトコルを表す文字列が格納されます。WSCEnumProtocolsで返される情報には、特定のプロトコルだけでなく、LSPの情報も含まれることになっています。インストールしたLSPの情報も返されることになります。した事から、WSCEnumProtocolsで列挙できる情報は、プロトコルと呼ばれずにエントリ(またはカタログエントリ)と呼ばれることがあります。WSAPROTOCOLCHAIN構造体のメンバを確認します。*LPWSAPROTOCOLCHAIN;ChainLenは、プロトコルチェーンの長さを指定します。ChainEntriesは、チェーンのエントリのIDを指定します。ChainLenが0である場合、そのプロトコルはレイヤードプロトコルである。ChainLenが0であるため、ChainEntriesは初期化されない。ChainLenが1である場合、そのプロトコルはベースプロトコルである。通常LSPはこのプロトコルの上にインストールすることになる。ChainLenが1より大きい場合、そのプロトコルはLSPのエントリである。ChainEntries[1]以降に、下位に存在するプロトコルのエントリIDを格納する。レイヤードプロトコルについて理解するために、1つの例を挙げて考えてみましょう。TCPとUDPの通信を検出するLSPを開発するとします。この場合、実装したLSPを次のように分けてインストールすることになります。エントリ上では分割して存在しているという点です。そこで、これらのエントリを1つのエントリとして考えるために存在するのが、レイヤードプロトコルです。レイヤードプロトコルが存在することで、次のように分かりやすい図が完成します。本当に正しいのは最初に示した図です。いくつかの場面では役に立つことがあります。関連するエントリを列挙することができるようになります。上記の話から分かるように、LSPのインストールというのは、少なくとも2回実行する必要があります。2回目は特定のプロトコル上へのインストールです。この上というのは、正確には前方です。このオーダーの先頭に存在するエントリから、考慮されることになっているからです。この確認対象となる順番はオーダーを基にしています。ws2_32.dllからの呼び出しを最初に検出するようにします。DLL内部で必要な処理を行った後、下位(後方)に存在するエントリの関数を呼び出すことになります。オーダーに関する問題を考慮した場合、インストールに必要な作業は次の3つとなります。ダミーエントリ(レイヤードプロトコル)をインストールする。プロトコルチェーンを形成した実際のエントリをインストールする。インストールによって作成された実際のエントリをオーダーの先頭に移動させる。最初にダミーエントリのインストールを行っておく必要があります。インストールが終了してから、明示的にオーダーを変更することになります。上記3つの作業が全て関数内部で行われます。今回のプログラムは、WSCEnumProtocolsを呼び出して、システムに存在するエントリを列挙します。左のリストボックスに列挙されたエントリ名を選択すると、右のリストボックスに詳細が表示されます。このプログラムはオーダーを確認するという目的でも利用することができます。WSCEnumProtocolsの呼び出しは、WM_CREATEで行われています。&nError);WSCEnumProtocolsの第1引数にNULLを指定した場合、全てのエントリが列挙されるようになります。第2引数にNULLを指定することで必要なサイズを取得します。2回目の呼び出しでバッファを初期化することになります。忘れず取得しておきます。