WSCEnumProtocols32 函式 (ws2spi.h)

WSCEnumProtocols32函式會擷取可用傳輸通訊協定的相關資訊。

注意 此呼叫是 32 位版本的 WSCEnumProtocols ,可用於 64 位平臺上。 它提供來允許 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

在輸入上,以位元組為單位傳遞至WSCEnumProtocolslpProtocolBuffer緩衝區大小。 在輸出上,可以傳遞至 WSCEnumProtocols 的最小緩衝區大小以位元組為單位,以擷取所有要求的資訊。

[out] lpErrno

錯誤碼的指標。

傳回值

如果沒有發生錯誤, WSCEnumProtocols32 會傳回要回報的通訊協定數目。 否則會傳回SOCKET_ERROR值,並在 lpErrno中提供特定的錯誤碼。

錯誤碼 意義
WSAEFAULT
其中一個引數不在使用者位址空間的有效部分。
WSAEINVAL
表示其中一個指定的參數無效。
WSAENOBUFS
緩衝區長度太小,無法接收所有相關 WSAProtocol_Info 結構和相關資訊。 至少傳入緩衝區,與 lpdwBufferLength中所傳回的值一樣大。

備註

WSCEnumProtocols32 是嚴格 32 位版本的 WSCEnumProtocols。 在 64 位電腦上,所有呼叫並非特別 32 位 (,例如,不會以 「32 ) 」 結尾的所有函式都會在原生 64 位目錄上運作。 在 64 位電腦上執行的處理常式必須使用特定的 32 位函式呼叫,以在嚴格 32 位目錄上運作,並保留相容性。 特定 32 位呼叫的定義和語意與其原生對應專案相同。

此函式可用來探索本機電腦上安裝之傳輸通訊協定集合的相關資訊。 此函式與其 API 對應專案不同 (WSAEnumProtocols) ,其中會傳回所有已安裝通訊協定 的WSAPROTOCOL_INFOW 結構。 這包括服務提供者在WSAPROTOCOL_INFOW結構的dwProviderFlags成員中設定PFL_HIDDEN旗標的通訊協定,以向 Ws2_32.dll 指出此通訊協定不應該在WSAEnumProtocols函式所產生的結果緩衝區中傳回。 此外, WSCEnumProtocols32 也會傳回具有零鏈結長度 ( 虛擬 LSP 提供者) WSAPROTOCOL_INFOW結構的資料。 WSAEnumProtocols只會傳回基底通訊協定和通訊協定鏈結的資訊,這些通訊協定和通訊協定鏈結缺少PFL_HIDDEN旗標,而且沒有零的通訊協定鏈結長度。

**注意** 分層服務提供者已被取代。 從 Windows 8 和 Windows Server 2012 開始,請使用 Windows 篩選平台
 
lpiProtocols參數可用來做為篩選準則,以限制提供的資訊量。 一般而言,會提供 Null 指標,讓函式會傳回所有可用傳輸通訊協定的相關資訊。

每個要求通訊協定的lpProtocolBuffer所指向的緩衝區中會提供WSAPROTOCOL_INFOW結構。 如果提供的緩衝區不夠大 (,如 輸入值 lpdwBufferLength) 所示, lpdwBufferLength 所指向的值將會更新,以指出所需的緩衝區大小。 Windows Sockets SPI 用戶端應該接著取得足夠的緩衝區,然後再次呼叫此函式。 WSCEnumProtocols32函式無法列舉多個呼叫;傳入的緩衝區必須夠大,才能保存所有預期的專案,才能讓函式成功。 這可減少函式的複雜度,而且不應該造成問題,因為電腦上載入的通訊協定數目通常很小。

緩衝區中 出現WSAPROTOCOL_INFOW 結構的順序會與服務提供者向 WS2_32.dll 註冊通訊協定專案的順序一致,或透過提供給建立預設傳輸提供者的 Windows Sockets 小程式進行後續重新排序的順序。

範例

下列範例示範如何在 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
程式庫 Ws2_32.lib
Dll Ws2_32.dll

另請參閱

WSAEnumProtocols

WSAPROTOCOL_INFOW

WSCEnumProtocols