WSAEnumProtocolsW 함수(winsock2.h)
WSAEnumProtocols 함수는 사용 가능한 전송 프로토콜에 대한 정보를 검색합니다.
구문
int WSAAPI WSAEnumProtocolsW(
[in] LPINT lpiProtocols,
[out] LPWSAPROTOCOL_INFOW lpProtocolBuffer,
[in, out] LPDWORD lpdwBufferLength
);
매개 변수
[in] lpiProtocols
iProtocol 값의 NULL로 끝나는 배열입니다. 이 매개 변수는 선택 사항입니다. lpiProtocols 가 NULL이면 사용 가능한 모든 프로토콜에 대한 정보가 반환됩니다. 그렇지 않으면 배열에 나열된 프로토콜에 대해서만 정보가 검색됩니다.
[out] lpProtocolBuffer
WSAPROTOCOL_INFO 구조체로 채워진 버퍼에 대한 포인터입니다.
[in, out] lpdwBufferLength
입력에서 WSAEnumProtocols에 전달된 lpProtocolBuffer 버퍼의 바이트 수입니다. 출력에서 요청된 모든 정보를 검색하기 위해 WSAEnumProtocols 에 전달할 수 있는 최소 버퍼 크기입니다. 이 루틴은 여러 호출을 열거할 수 없습니다. 전달된 버퍼는 루틴이 성공하려면 모든 항목을 저장할 수 있을 만큼 커야 합니다. 이렇게 하면 API의 복잡성이 줄어들고 컴퓨터에 로드되는 프로토콜 수가 일반적으로 적기 때문에 문제가 되지 않아야 합니다.
반환 값
오류가 발생하지 않으면 WSAEnumProtocols 는 보고할 프로토콜 수를 반환합니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.
오류 코드 | 의미 |
---|---|
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다. | |
네트워크 하위 시스템이 실패했습니다. | |
차단 Windows 소켓 1.1 호출이 진행 중입니다. | |
지정된 매개 변수 중 하나가 잘못되었음을 나타냅니다. | |
버퍼 길이가 너무 작아 관련 WSAPROTOCOL_INFO 구조 및 관련 정보를 모두 받을 수 없습니다. lpdwBufferLength에서 반환된 값만큼 큰 버퍼를 전달합니다. | |
lpiProtocols, lpProtocolBuffer 또는 lpdwBufferLength 매개 변수 중 하나 이상이 사용자 주소 공간의 유효한 부분이 아닙니다. |
설명
WSAEnumProtocols 함수는 로컬 컴퓨터에 설치된 전송 프로토콜 컬렉션에 대한 정보를 검색하는 데 사용됩니다. 계층화된 프로토콜은 프로토콜 체인에 설치된 경우에만 애플리케이션에서 사용할 수 있습니다. lpProtocolBuffer에 체인 길이가 0으로 설치된 더미 계층화된 LSP(서비스 공급자)를 제외하고 계층화된 프로토콜에 대한 정보는 반환되지 않습니다.
WSAEnumProtocols 함수는 WSAEnumProtocols 함수가 설치된 모든 프로토콜에 대한 WSAPROTOCOL_INFO 구조를 반환하지 않는다는 점에서 WSCEnumProtocols 및 WSCEnumProtocols32 함수와 다릅니다. WSAEnumProtocols 함수는 서비스 공급자가 WSAPROTOCOL_INFO 구조체의 dwProviderFlags 멤버에 PFL_HIDDEN 플래그를 사용하여 설정한 프로토콜을 제외하여 WSAEnumProtocols 함수에서 생성된 결과 버퍼에서 이 프로토콜을 반환해서는 안 됨을 Ws2_32.dll 나타냅니다. 또한 WSAEnumProtocols 함수는 체인 길이가 하나 이상인 WSAPROTOCOL_INFO 구조체(LSP 공급자)에 대한 데이터를 반환하지 않습니다. WSAEnumProtocols는 PFL_HIDDEN 플래그가 없고 프로토콜 체인 길이가 0이 아닌 기본 프로토콜 및 프로토콜 체인에 대한 정보만 반환합니다.
요청된 각 프로토콜에 대해 lpProtocolBuffer가 가리키는 버퍼에 WSAPROTOCOL_INFO 구조가 제공됩니다. 지정된 버퍼가 충분히 크지 않으면( 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 헤더는 WSAEnumProtocols를 유니코드 전처리기 상수의 정의에 따라 이 함수의 ANSI 또는 유니코드 버전을 자동으로 선택하는 별칭으로 정의합니다. 인코딩 중립 별칭을 인코딩 중립이 아닌 코드와 혼합하면 컴파일 또는 런타임 오류가 발생하는 불일치가 발생할 수 있습니다. 자세한 내용은 함수 프로토타입에 대한 규칙을 참조하세요.
요구 사항
지원되는 최소 클라이언트 | Windows 8.1, Windows Vista [데스크톱 앱 | UWP 앱] |
지원되는 최소 서버 | Windows Server 2003 [데스크톱 앱 | UWP 앱] |
대상 플랫폼 | Windows |
헤더 | winsock2.h |
라이브러리 | Ws2_32.lib |
DLL | Ws2_32.dll |