WSAEnumProtocolsA 関数 (winsock2.h)

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

構文

int WSAAPI WSAEnumProtocolsA(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOA lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength
);

パラメーター

[in] lpiProtocols

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

[out] lpProtocolBuffer

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

[in, out] lpdwBufferLength

入力時に、WSAEnumProtocols に渡される lpProtocolBuffer バッファー内のバイト数。 出力時に、要求されたすべての情報を取得するために WSAEnumProtocols に渡すことができる最小バッファー サイズ。 このルーチンには、複数の呼び出しを列挙する機能がありません。渡されたバッファーは、ルーチンが成功するために、すべてのエントリを保持するのに十分な大きさである必要があります。 これにより、API の複雑さが軽減され、コンピューターに読み込まれるプロトコルの数が通常は少ないため、問題を引き起こすべきではありません。

戻り値

エラーが発生しない場合、 WSAEnumProtocols は報告するプロトコルの数を返します。 それ以外の場合は、SOCKET_ERRORの値が返され、 WSAGetLastError を呼び出すことによって特定のエラー コードを取得できます。

エラー コード 意味
WSANOTINITIALIZED
この関数を使用する前に、 WSAStartup 呼び出しが正常に行われる必要があります。
WSAENETDOWN
ネットワーク サブシステムが失敗しました。
WSAEINPROGRESS
ブロックしている Windows ソケット 1.1 呼び出しが進行中です。
WSAEINVAL
指定されたパラメーターのいずれかが無効であることを示します。
WSAENOBUFS
バッファー長が小さすぎて、関連するすべての WSAPROTOCOL_INFO 構造と関連情報を受信できませんでした。 lpdwBufferLength で返される値と同じ大きさ以上のバッファーを渡します。
WSAEFAULT
1 つ以上の lpiProtocolslpProtocolBuffer、または lpdwBufferLength パラメーターは、ユーザー アドレス空間の有効な部分ではありません。

注釈

WSAEnumProtocols 関数は、ローカル コンピューターにインストールされているトランスポート プロトコルのコレクションに関する情報を検出するために使用されます。 階層化されたプロトコルは、プロトコル チェーンにインストールされている場合にのみアプリケーションで使用できます。 lpProtocolBuffer にチェーン長が 0 のダミーレイヤード サービス プロバイダー (LSP) がインストールされている場合を除き、階層化されたプロトコルに関する情報は返されません。

メモ 階層型サービス プロバイダーは非推奨です。 Windows 8とWindows Server 2012以降では、Windows フィルター プラットフォームを使用します
 
lpiProtocols パラメーターは、提供される情報の量を制限するフィルターとして使用できます。 多くの場合、 lpiProtocolsNULL ポインターとして指定されます。これにより、関数は使用可能なすべてのトランスポート プロトコルとプロトコル チェーンに関する情報を返します。

WSAEnumProtocols 関数は、WSCEnumProtocols 関数と WSCEnumProtocols32 関数とは異なり、WSAEnumProtocols 関数は、インストールされているすべてのプロトコルのWSAPROTOCOL_INFO構造体を返しません。 WSAEnumProtocols 関数は、サービス プロバイダーが WSAPROTOCOL_INFO 構造体のdwProviderFlags メンバーでPFL_HIDDEN フラグを設定したプロトコルを除外して、WSAEnumProtocols 関数によって生成された結果バッファーでこのプロトコルを返してはならないことを Ws2_32.dll に示します。 さらに、 WSAEnumProtocols 関数は、チェーン長が 1 つ以上の WSAPROTOCOL_INFO 構造体 (LSP プロバイダー) のデータを返しません。 WSAEnumProtocols は、PFL_HIDDEN フラグがなく、プロトコル チェーンの長さが 0 ではない基本プロトコルとプロトコル チェーンに関する情報のみを返します。

WSAPROTOCOL_INFO構造体は、要求されたプロトコルごとに lpProtocolBuffer によって指されるバッファーに用意されています。 指定したバッファーが十分な大きさでない場合 ( lpdwBufferLength の入力値で示されているように)、 lpdwBufferLength が指す値は、必要なバッファー サイズを示すように更新されます。 その後、アプリケーションは十分な大きさのバッファーを取得し、 WSAEnumProtocols を再度呼び出す必要があります。

バッファーにWSAPROTOCOL_INFO構造体が表示される順序は、プロトコル エントリがサービス プロバイダーによって登録された順序と、WS2_32.DLL を使用して登録された順序、または既定の TCP/IP プロバイダーを確立するために提供された Windows ソケット アプリケーションまたは DLL を介して発生した後続の並べ替えと一致します。

Windows Phone 8:WSAEnumProtocolsW 関数は、Windows Phone 8 以降のWindows Phone ストア アプリでサポートされています。

Windows 8.1およびWindows Server 2012 R2: WSAEnumProtocolsW 関数は、Windows 8.1、Windows Server 2012 R2 以降の Windows ストア アプリでサポートされています。

次の例では、 WSAEnumProtocols 関数を使用して、使用可能なトランスポート プロトコルの WSAPROTOCOL_INFO 構造体の配列を取得する方法を示します。

#ifndef UNICODE
#define UNICODE 1
#endif

#include <winsock2.h>
#include <ws2tcpip.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 iError = 0;
    INT iNuminfo = 0;

    int i;

    // Allocate a 16K buffer to retrieve all the protocol providers
    DWORD dwBufferLen = 16384;

    LPWSAPROTOCOL_INFO lpProtocolInfo = NULL;

    // 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_INFO) MALLOC(dwBufferLen);
    if (lpProtocolInfo == NULL) {
        wprintf(L"Memory allocation for providers buffer failed\n");
        WSACleanup();
        return 1;
    }

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

        }
    }

    wprintf(L"WSAEnumProtocols 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;
}


注意

winsock2.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして WSAEnumProtocols を定義します。 encoding-neutral エイリアスの使用を encoding-neutral ではないコードと混在すると、コンパイル エラーまたはランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「 関数プロトタイプの規則」を参照してください。

要件

要件
サポートされている最小のクライアント Windows 8.1、Windows Vista [デスクトップ アプリ |UWP アプリ]
サポートされている最小のサーバー Windows Server 2003 [デスクトップ アプリのみ | UWP アプリ]
対象プラットフォーム Windows
ヘッダー winsock2.h
Library Ws2_32.lib
[DLL] Ws2_32.dll

こちらもご覧ください

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

Winsock 関数

Winsock リファレンス