WSCEnumProtocols32 関数 (ws2spi.h)

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

メモ この呼び出しは、64 ビット プラットフォームで使用する WSCEnumProtocols の厳密な 32 ビット バージョンです。 64 ビット プロセスが 32 ビット カタログにアクセスできるように提供されています。

 

構文

int WSCEnumProtocols32(
  [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

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

戻り値

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

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

解説

WSCEnumProtocols32 は、厳密には 32 ビット バージョンの WSCEnumProtocols です。 64 ビット コンピューターでは、32 ビット以外のすべての呼び出し (たとえば、"32" で終わっていないすべての関数) は、ネイティブの 64 ビット カタログで動作します。 64 ビット コンピューターで実行されるプロセスでは、特定の 32 ビット関数呼び出しを使用して、厳密に 32 ビット カタログを操作し、互換性を維持する必要があります。 特定の 32 ビット呼び出しの定義とセマンティクスは、ネイティブの呼び出しと同じです。

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

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

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

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

次の例では、64 ビット プラットフォームで使用する WSCEnumProtocols32 関数を使用して、32 ビット カタログ内のローカル コンピューターにインストールされているプロトコルの 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 = WSCEnumProtocols32(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
    if (iNuminfo == SOCKET_ERROR) {
        if (iErrno != WSAENOBUFS) {
            wprintf(L"WSCEnumProtocols32 failed with error: %d\n", iErrno);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            WSACleanup();
            return 1;
        } else {
            wprintf(L"WSCEnumProtocols32 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 =
                WSCEnumProtocols32(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
            if (iNuminfo == SOCKET_ERROR) {
                wprintf(L"WSCEnumProtocols32 failed with error: %d\n", iErrno);
                if (lpProtocolInfo) {
                    FREE(lpProtocolInfo);
                    lpProtocolInfo = NULL;
                }
                WSACleanup();
                return 1;
            }

        }
    }

    wprintf(L"WSCEnumProtocols32 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 Vista、Windows XP Professional x64 Edition [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows Server 2008、Windows Server 2003 x64 Edition [デスクトップ アプリのみ]
対象プラットフォーム Windows
ヘッダー ws2spi.h
Library Ws2_32.lib
[DLL] Ws2_32.dll

関連項目

WSAEnumProtocols

WSAPROTOCOL_INFOW

WSCEnumProtocols