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 함수는 로컬 컴퓨터에 설치된 전송 프로토콜 컬렉션에 대한 정보를 검색하는 데 사용됩니다. 이 함수는 설치된 모든 프로토콜에 대한 WSAPROTOCOL_INFOW 구조가 반환된다는 점에서 API 대응(WSAEnumProtocols)과 다릅니다. 여기에는 서비스 공급자가 WSAPROTOCOL_INFOW 구조의 dwProviderFlags 멤버에서 PFL_HIDDEN 플래그를 설정하여 WSAEnumProtocols 함수에서 생성된 결과 버퍼에서 이 프로토콜을 반환해서는 안 됨을 Ws2_32.dll 나타내는 프로토콜이 포함됩니다. 또한 WSCEnumProtocols 는 체인 길이가 0(더미 LSP 공급자)인 WSAPROTOCOL_INFOW 구조체에 대한 데이터도 반환합니다. WSAEnumProtocols는 PFL_HIDDEN 플래그가 부족하고 프로토콜 체인 길이가 0이 아닌 기본 프로토콜 및 프로토콜 체인에 대한 정보만 반환합니다.
요청된 각 프로토콜에 대해 lpProtocolBuffer가 가리키는 버퍼에 WSAPROTOCOL_INFOW 구조가 제공됩니다. 제공된 버퍼가 충분히 크지 않으면( lpdwBufferLength의 입력 값으로 나타낸 대로) lpdwBufferLength 가 가리키는 값이 필요한 버퍼 크기를 나타내도록 업데이트됩니다. 그런 다음 Windows 소켓 SPI 클라이언트는 충분히 큰 버퍼를 가져와서 이 함수를 다시 호출해야 합니다. WSCEnumProtocols 함수는 여러 호출을 통해 열거할 수 없습니다. 함수가 성공하려면 전달된 버퍼가 모든 예상 항목을 저장할 수 있을 만큼 커야 합니다. 이렇게 하면 함수의 복잡성이 줄어들고 로컬 컴퓨터에 로드되는 프로토콜 수가 일반적으로 적기 때문에 문제가 되지 않아야 합니다.
버퍼에 WSAPROTOCOL_INFOW 구조가 표시되는 순서는 프로토콜 항목이 서비스 공급자가 WS2_32.dll 등록한 순서 또는 기본 전송 공급자를 설정하기 위해 제공된 Windows 소켓 애플릿을 통해 발생할 수 있는 후속 다시 정렬과 일치합니다.
예제
다음 예제에서는 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 |