WSCEnumProtocols32 函数 (ws2spi.h)
WSCEnumProtocols32 函数检索有关可用传输协议的信息。
语法
int WSCEnumProtocols32(
[in] LPINT lpiProtocols,
[out] LPWSAPROTOCOL_INFOW lpProtocolBuffer,
[in, out] LPDWORD lpdwBufferLength,
[out] LPINT lpErrno
);
参数
[in] lpiProtocols
以 Null 结尾的 iProtocol 值数组。 此参数是可选的;如果 lpiProtocols 为 null,则返回有关所有可用协议的信息。 否则,仅检索数组中列出的那些协议的信息。
[out] lpProtocolBuffer
用WSAPROTOCOL_INFOW结构填充 的 缓冲区。
[in, out] lpdwBufferLength
输入时,传递给 WSCEnumProtocols 的 lpProtocolBuffer 缓冲区的大小(以字节为单位)。 输出时,可以传递给 WSCEnumProtocols 以检索所有请求的信息的最小缓冲区大小(以字节为单位)。
[out] lpErrno
指向错误代码的指针。
返回值
如果未发生错误, WSCEnumProtocols32 将返回要报告的协议数。 否则,将返回值 SOCKET_ERROR,并在 lpErrno 中提供特定的错误代码。
错误代码 | 含义 |
---|---|
其中一个参数不在用户地址空间的有效部分。 | |
:指示指定参数之一无效。 | |
缓冲区长度太小,无法接收所有相关 WSAProtocol_Info 结构和相关信息。 传入缓冲区至少与 lpdwBufferLength 中返回的值一样大。 |
注解
WSCEnumProtocols32 是 WSCEnumProtocols 的严格 32 位版本。 例如,在 64 位计算机上,所有不专门调用 32 位 (所有不以“32”结尾的函数 ) 本机 64 位目录上运行。 在 64 位计算机上执行的进程必须使用特定的 32 位函数调用,才能对严格的 32 位目录进行操作并保持兼容性。 特定 32 位调用的定义和语义与其本机调用的定义和语义相同。
此函数用于发现有关本地计算机上安装的传输协议集合的信息。 此函数与 WSAEnumProtocols () 的 API 对应函数不同,因为它返回所有已安装协议 的WSAPROTOCOL_INFOW 结构。 这包括服务提供程序在 WSAPROTOCOL_INFOW 结构的 dwProviderFlags 成员中设置 PFL_HIDDEN标志的 协议,以向 Ws2_32.dll 指示不应在 WSAEnumProtocols 函数生成的结果缓冲区中返回此协议。 此外, WSCEnumProtocols32 还会返回链长度为零 的WSAPROTOCOL_INFOW 结构的数据 ( 虚拟 LSP 提供程序) 。 WSAEnumProtocols 仅返回缺少PFL_HIDDEN标志且协议链长度不为零的基本协议和协议链的信息。
对于每个请求的协议,lpProtocolBuffer 指向的缓冲区中提供了WSAPROTOCOL_INFOW结构。 如果提供的缓冲区 (不够大,如 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 版本 [仅限桌面应用] |
最低受支持的服务器 | Windows Server 2008、Windows Server 2003 x64 Edition [仅限桌面应用] |
目标平台 | Windows |
标头 | ws2spi.h |
Library | Ws2_32.lib |
DLL | Ws2_32.dll |