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中提供特定的錯誤碼。
錯誤碼 | 意義 |
---|---|
其中一個引數不在使用者位址空間的有效部分中。 | |
表示其中一個指定的參數無效。 | |
緩衝區長度太小,無法接收所有相關 WSAProtocol_Info 結構和相關資訊。 至少傳入緩衝區,與 lpdwBufferLength中傳回的值一樣大。 |
備註
WSCEnumProtocols 函式可用來探索本機電腦上安裝之傳輸通訊協定集合的相關資訊。 此函式與其 API 對應專案不同 (WSAEnumProtocols) ,因為會傳回所有已安裝通訊協定 的WSAPROTOCOL_INFOW 結構。 這包括服務提供者在WSAPROTOCOL_INFOW結構的dwProviderFlags成員中設定PFL_HIDDEN旗標的通訊協定,以向 Ws2_32.dll 指出WSAEnumProtocols函式所產生的結果緩衝區中不應傳回此通訊協定。 此外, WSCEnumProtocols 也會傳回具有零鏈結長度 ( 虛擬 LSP 提供者) 之 WSAPROTOCOL_INFOW 結構的資料。 WSAEnumProtocols只會傳回缺少PFL_HIDDEN旗標且沒有通訊協定鏈結長度為零的基礎通訊協定和通訊協定鏈結資訊。
每個要求通訊協定的lpProtocolBuffer指向的緩衝區中會提供WSAPROTOCOL_INFOW結構。 如果提供的緩衝區不夠大, (,如 輸入值 lpdwBufferLength) 所示, lpdwBufferLength 所指向的值將會更新,以指出所需的緩衝區大小。 接著,Windows Sockets SPI 用戶端應該會取得夠大的緩衝區,並再次呼叫此函式。 WSCEnumProtocols 函式無法列舉多個呼叫;傳入的緩衝區必須夠大,才能保存所有預期的專案,函式才能成功。 這可減少函式的複雜度,而且不應該造成問題,因為本機電腦上載入的通訊協定數目通常很小。
緩衝區中出現WSAPROTOCOL_INFOW結構的順序與服務提供者向 WS2_32.dll 註冊通訊協定專案的順序,或透過提供給建立預設傳輸提供者的 Windows Sockets 小程式所發生的任何後續重新排序次序一致。
範例
下列範例示範如何使用 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 |
程式庫 | Ws2_32.lib |
Dll | Ws2_32.dll |