WSCEnumProtocols 関数 (ws2spi.h)

WSCEnumProtocols 関数は、使用可能なトランスポート プロトコルに関する情報を取得します。

構文

int WSCEnumProtocols(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOW lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength,
  [out]     LPINT               lpErrno
);

パラメーター

[in] lpiProtocols

iProtocol 値の NULL で終わる配列。 このパラメーターは省略可能です。 lpiProtocols が NULL の場合は、使用可能なすべてのプロトコルに関する情報が返されます。 それ以外の場合、情報は配列にリストされているプロトコルに対してのみ取得されます。

[out] lpProtocolBuffer

WSAPROTOCOL_INFOW構造体が格納されているバッファーへのポインター。

[in, out] lpdwBufferLength

入力時に、WSCEnumProtocols に渡される lpProtocolBuffer バッファーのサイズ (バイト単位)。 出力時に、要求されたすべての情報を取得するために WSCEnumProtocols に渡すことができる最小バッファー サイズ (バイト単位)。

[out] lpErrno

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

戻り値

エラーが発生しない場合、 WSCEnumProtocols は報告されるプロトコルの数を返します。 それ以外の場合は、SOCKET_ERRORの値が返され、 lpErrno で特定のエラー コードを使用できます。

エラー コード 意味
WSAEFAULT
その他の引数の 1 つが、ユーザー・アドレス・スペースの有効な部分にありません。
WSAEINVAL
指定されたパラメーターのいずれかが無効であることを示します。
WSAENOBUFS
バッファー長が小さすぎて、関連するすべての WSAProtocol_Info 構造と関連情報を受信できませんでした。 lpdwBufferLength で返される値と同じ大きさ以上のバッファーを渡します。

解説

WSCEnumProtocols 関数は、ローカル コンピューターにインストールされているトランスポート プロトコルのコレクションに関する情報を検出するために使用されます。 この関数は、インストールされているすべてのプロトコルのWSAPROTOCOL_INFOW構造体が返される点で、対応する API (WSAEnumProtocols) とは異なります。 これには、サービス プロバイダーが WSAPROTOCOL_INFOW 構造体のdwProviderFlags メンバーで PFL_HIDDEN フラグを設定したプロトコルが含まれます。このプロトコルは、WSAEnumProtocols 関数によって生成された結果バッファーで返されないことを Ws2_32.dll に示します。 さらに、 WSCEnumProtocols は、チェーン長が 0 (ダミー LSP プロバイダー) のWSAPROTOCOL_INFOW 構造体のデータも返します。 WSAEnumProtocols は、PFL_HIDDEN フラグがなく、プロトコル チェーンの長さが 0 ではない基本プロトコルとプロトコル チェーンに関する情報のみを返します。

**注** 階層型サービス プロバイダーは非推奨です。 Windows 8 および Windows Server 2012 以降では、 Windows フィルター プラットフォームを使用します
 
lpiProtocols パラメーターは、提供される情報の量を制限するフィルターとして使用できます。 通常、null ポインターが提供されるため、関数は使用可能なすべてのトランスポート プロトコルに関する情報を返します。

WSAPROTOCOL_INFOW構造体は、要求されたプロトコルごとに lpProtocolBuffer によって指されるバッファーに提供されます。 指定されたバッファーが十分な大きさでない場合 ( lpdwBufferLength の入力値で示されているように)、 lpdwBufferLength が指す値は、必要なバッファー サイズを示すように更新されます。 Windows ソケット SPI クライアントは、十分な大きさのバッファーを取得し、この関数を再度呼び出す必要があります。 WSCEnumProtocols 関数は、複数の呼び出しを列挙できません。渡されたバッファーは、関数が成功するために必要なすべてのエントリを保持するのに十分な大きさである必要があります。 これにより、関数の複雑さが軽減され、ローカル コンピューターに読み込まれるプロトコルの数が通常は少ないため、問題を引き起こすべきではありません。

バッファーにWSAPROTOCOL_INFOW構造体が表示される順序は、プロトコル エントリがサービス プロバイダーによって WS2_32.dll に登録された順序、または既定のトランスポート プロバイダーを確立するために提供された Windows ソケット アプレットを介して発生した可能性がある後続の並べ替えと一致します。

次の例では、 WSCEnumProtocols 関数を使用して、ローカル コンピューターにインストールされているプロトコルの WSAPROTOCOL_INFOW 構造体の配列を取得する方法を示します。

#ifndef UNICODE
#define UNICODE 1
#endif

#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <objbase.h>
#include <stdio.h>

// Link with ws2_32.lib and ole32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "ole32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
// Note: could also use malloc() and free()

int wmain()
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult = 0;

    INT iNuminfo = 0;

    int i;

    // Allocate a 16K buffer to retrieve all the protocol providers
    DWORD dwBufferLen = 16384;
    LPWSAPROTOCOL_INFOW lpProtocolInfo = NULL;
    int iErrno = 0;

    // variables needed for converting provider GUID to a string
    int iRet = 0;
    WCHAR GuidString[40] = { 0 };

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }

    lpProtocolInfo = (LPWSAPROTOCOL_INFOW) MALLOC(dwBufferLen);
    if (lpProtocolInfo == NULL) {
        wprintf(L"Memory allocation for providers buffer failed\n");
        WSACleanup();
        return 1;
    }

    iNuminfo = WSCEnumProtocols(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
    if (iNuminfo == SOCKET_ERROR) {
        if (iErrno != WSAENOBUFS) {
            wprintf(L"WSCEnumProtocols failed with error: %d\n", iErrno);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            WSACleanup();
            return 1;
        } else {
            wprintf(L"WSCEnumProtocols failed with error: WSAENOBUFS (%d)\n",
                    iErrno);
            wprintf(L"  Increasing buffer size to %d\n\n", dwBufferLen);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            lpProtocolInfo = (LPWSAPROTOCOL_INFOW) MALLOC(dwBufferLen);
            if (lpProtocolInfo == NULL) {
                wprintf(L"Memory allocation increase for buffer failed\n");
                WSACleanup();
                return 1;
            }
            iNuminfo =
                WSCEnumProtocols(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
            if (iNuminfo == SOCKET_ERROR) {
                wprintf(L"WSCEnumProtocols failed with error: %d\n", iErrno);
                if (lpProtocolInfo) {
                    FREE(lpProtocolInfo);
                    lpProtocolInfo = NULL;
                }
                WSACleanup();
                return 1;
            }

        }
    }

    wprintf(L"WSCEnumProtocols succeeded with protocol count = %d\n\n",
            iNuminfo);
    for (i = 0; i < iNuminfo; i++) {
        wprintf(L"Winsock Catalog Provider Entry #%d\n", i);
        wprintf
            (L"----------------------------------------------------------\n");
        wprintf(L"Entry type:\t\t\t ");
        if (lpProtocolInfo[i].ProtocolChain.ChainLen == 1)
            wprintf(L"Base Service Provider\n");
        else
            wprintf(L"Layered Chain Entry\n");

        wprintf(L"Protocol:\t\t\t %ws\n", lpProtocolInfo[i].szProtocol);

        iRet =
            StringFromGUID2(lpProtocolInfo[i].ProviderId,
                            (LPOLESTR) & GuidString, 39);
        if (iRet == 0)
            wprintf(L"StringFromGUID2 failed\n");
        else
            wprintf(L"Provider ID:\t\t\t %ws\n", GuidString);

        wprintf(L"Catalog Entry ID:\t\t %u\n",
                lpProtocolInfo[i].dwCatalogEntryId);

        wprintf(L"Version:\t\t\t %d\n", lpProtocolInfo[i].iVersion);

        wprintf(L"Address Family:\t\t\t %d\n",
                lpProtocolInfo[i].iAddressFamily);
        wprintf(L"Max Socket Address Length:\t %d\n",
                lpProtocolInfo[i].iMaxSockAddr);
        wprintf(L"Min Socket Address Length:\t %d\n",
                lpProtocolInfo[i].iMinSockAddr);

        wprintf(L"Socket Type:\t\t\t %d\n", lpProtocolInfo[i].iSocketType);
        wprintf(L"Socket Protocol:\t\t %d\n", lpProtocolInfo[i].iProtocol);
        wprintf(L"Socket Protocol Max Offset:\t %d\n",
                lpProtocolInfo[i].iProtocolMaxOffset);

        wprintf(L"Network Byte Order:\t\t %d\n",
                lpProtocolInfo[i].iNetworkByteOrder);
        wprintf(L"Security Scheme:\t\t %d\n",
                lpProtocolInfo[i].iSecurityScheme);
        wprintf(L"Max Message Size:\t\t %u\n", lpProtocolInfo[i].dwMessageSize);

        wprintf(L"ServiceFlags1:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags1);
        wprintf(L"ServiceFlags2:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags2);
        wprintf(L"ServiceFlags3:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags3);
        wprintf(L"ServiceFlags4:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags4);
        wprintf(L"ProviderFlags:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwProviderFlags);

        wprintf(L"Protocol Chain length:\t\t %d\n",
                lpProtocolInfo[i].ProtocolChain.ChainLen);

        wprintf(L"\n");
    }

    if (lpProtocolInfo) {
        FREE(lpProtocolInfo);
        lpProtocolInfo = NULL;
    }
    WSACleanup();

    return 0;
}


要件

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

関連項目

WSAEnumProtocols

WSAPROTOCOL_INFOW

WSCEnumProtocols32