다음을 통해 공유


WSAEnumProtocolsW 함수(winsock2.h)

WSAEnumProtocols 함수는 사용 가능한 전송 프로토콜에 대한 정보를 검색합니다.

구문

int WSAAPI WSAEnumProtocolsW(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOW lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength
);

매개 변수

[in] lpiProtocols

iProtocol 값의 NULL로 끝나는 배열입니다. 이 매개 변수는 선택 사항입니다. lpiProtocolsNULL이면 사용 가능한 모든 프로토콜에 대한 정보가 반환됩니다. 그렇지 않으면 배열에 나열된 프로토콜에 대해서만 정보가 검색됩니다.

[out] lpProtocolBuffer

WSAPROTOCOL_INFO 구조체로 채워진 버퍼에 대한 포인터입니다.

[in, out] lpdwBufferLength

입력에서 WSAEnumProtocols에 전달된 lpProtocolBuffer 버퍼의 바이트 수입니다. 출력에서 요청된 모든 정보를 검색하기 위해 WSAEnumProtocols 에 전달할 수 있는 최소 버퍼 크기입니다. 이 루틴은 여러 호출을 열거할 수 없습니다. 전달된 버퍼는 루틴이 성공하려면 모든 항목을 저장할 수 있을 만큼 커야 합니다. 이렇게 하면 API의 복잡성이 줄어들고 컴퓨터에 로드되는 프로토콜 수가 일반적으로 적기 때문에 문제가 되지 않아야 합니다.

반환 값

오류가 발생하지 않으면 WSAEnumProtocols 는 보고할 프로토콜 수를 반환합니다. 그렇지 않으면 SOCKET_ERROR 값이 반환되고 WSAGetLastError를 호출하여 특정 오류 코드를 검색할 수 있습니다.

오류 코드 의미
WSANOTINITIALISED
이 함수를 사용하기 전에 성공적인 WSAStartup 호출이 발생해야 합니다.
WSAENETDOWN
네트워크 하위 시스템이 실패했습니다.
WSAEINPROGRESS
차단 Windows 소켓 1.1 호출이 진행 중입니다.
WSAEINVAL
지정된 매개 변수 중 하나가 잘못되었음을 나타냅니다.
WSAENOBUFS
버퍼 길이가 너무 작아 관련 WSAPROTOCOL_INFO 구조 및 관련 정보를 모두 받을 수 없습니다. lpdwBufferLength에서 반환된 값만큼 큰 버퍼를 전달합니다.
WSAEFAULT
lpiProtocols, lpProtocolBuffer 또는 lpdwBufferLength 매개 변수 중 하나 이상이 사용자 주소 공간의 유효한 부분이 아닙니다.

설명

WSAEnumProtocols 함수는 로컬 컴퓨터에 설치된 전송 프로토콜 컬렉션에 대한 정보를 검색하는 데 사용됩니다. 계층화된 프로토콜은 프로토콜 체인에 설치된 경우에만 애플리케이션에서 사용할 수 있습니다. lpProtocolBuffer에 체인 길이가 0으로 설치된 더미 계층화된 LSP(서비스 공급자)를 제외하고 계층화된 프로토콜에 대한 정보는 반환되지 않습니다.

참고 계층화된 서비스 공급자는 더 이상 사용되지 않습니다. Windows 8 및 Windows Server 2012부터 Windows 필터링 플랫폼을 사용합니다.
 
lpiProtocols 매개 변수를 필터로 사용하여 제공된 정보의 양을 제한할 수 있습니다. 종종 lpiProtocols는 함수가 사용 가능한 모든 전송 프로토콜 및 프로토콜 체인에 대한 정보를 반환하도록 하는 NULL 포인터로 지정됩니다.

WSAEnumProtocols 함수는 WSAEnumProtocols 함수가 설치된 모든 프로토콜에 대한 WSAPROTOCOL_INFO 구조를 반환하지 않는다는 점에서 WSCEnumProtocols 및 WSCEnumProtocols32 함수와 다릅니다. WSAEnumProtocols 함수는 서비스 공급자가 WSAPROTOCOL_INFO 구조체의 dwProviderFlags 멤버에 PFL_HIDDEN 플래그를 사용하여 설정한 프로토콜을 제외하여 WSAEnumProtocols 함수에서 생성된 결과 버퍼에서 이 프로토콜을 반환해서는 안 됨을 Ws2_32.dll 나타냅니다. 또한 WSAEnumProtocols 함수는 체인 길이가 하나 이상인 WSAPROTOCOL_INFO 구조체(LSP 공급자)에 대한 데이터를 반환하지 않습니다. WSAEnumProtocolsPFL_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.1Windows 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

추가 정보

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

Winsock 함수

Winsock 참조