Share via


API 세트 가용성 검색

경우에 따라 지정된 API 집합 계약 이름이 일부 Windows 디바이스의 빈 모듈 이름에 의도적으로 매핑될 수 있습니다. 그 이유는 다양하지만 일반적인 예는 리소스가 제한된 디바이스에 대해 구성할 때 시스템 리소스 측면에서 비용이 많이 드는 기능을 Windows OS에서 제거할 수 있기 때문입니다. 이렇게 하면 애플리케이션이 API 수준에서 선택적 기능을 정상적으로 처리해야 하는 문제가 발생합니다.

Win32 API를 사용할 수 있는지 여부를 테스트하는 기존의 방법은 LoadLibrary 또는 GetProcAddress를 사용하는 것입니다. 그러나 이러한 방법은 Windows 10 이상에서 역방향 전달 지원으로 인해 API 집합을 테스트하기 위한 신뢰할 수 있는 수단이 아닙니다. 역방향 전달이 지정된 API에 적용되는 경우 LoadLibrary 또는 GetProcAddress는 내부 구현이 제거된 경우에도 유효한 함수 포인터에 resolve 수 있습니다. 이 경우 함수 포인터는 단순히 오류를 반환하는 스텁 함수를 가리킵니다.

이 경우를 감지하기 위해 IsApiSetImplemented 함수를 사용하여 지정된 API 구현의 기본 가용성을 쿼리할 수 있습니다. 이 테스트는 이 함수를 호출하면 API의 기능 구현이 실행되는지 확인합니다.

다음 코드 예제에서는 IsApiSetImplemented 를 사용하여 WTSEnumerateSessions 함수를 호출하기 전에 현재 디바이스에서 사용할 수 있는지 여부를 확인하는 방법을 보여 줍니다.

#include <windows.h>
#include <stdio.h>
#include <Wtsapi32.h>

int __cdecl wmain(int /* argc */, PCWSTR /* argv */ [])
{
    PWTS_SESSION_INFO pInfo = {};
    DWORD count = 0;

    if (!IsApiSetImplemented("ext-ms-win-session-wtsapi32-l1-1-0"))
    {
        wprintf(L"IsApiSetImplemented on ext-ms-win-session-wtsapi32-l1-1-0 returns FALSE\n");
    }
    else
    {
        if (WTSEnumerateSessionsW(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pInfo, &count))
        {
            wprintf(L"SessionCount = %d\n", count);

            for (ULONG i = 0; i < count; i++)
            {
                PWTS_SESSION_INFO pCurInfo = &pInfo[i];
                wprintf(L"    %s: ID = %d, state = %d\n", pCurInfo->pWinStationName, 
                    pCurInfo->SessionId, pCurInfo->State);
            }

            WTSFreeMemory(pInfo);
        }
        else
        {
            wprintf(L"WTSEnumerateSessions failure : %x\n", GetLastError());
        }
    }

    return 0;
}