이중 STA 쿼리 및 구성
참고
이 항목에 설명된 기능을 개발하려면 Windows 11 SDK(10.0.22000.194) 이상이 필요합니다.
이중 스테이션(이중 STA) 연결을 지원하는 어댑터와 연결된 두 가지 유형의 인터페이스(기본 STA 인터페이스 및 보조 STA 인터페이스)가 있습니다. 모든 어댑터는 기본 STA 인터페이스를 노출하지만 이중 STA 기능을 지원하는 어댑터만 보조 STA 인터페이스를 노출합니다.
기본적으로 Windows는 기본 STA 인터페이스에서만 연결됩니다. Windows는 다음 조건이 모두 충족되는 경우에만 보조 STA 인터페이스에 연결됩니다.
- 드라이버는 해당 기능에서 보조 STA 인터페이스에 대한 지원을 나타냅니다.
- 보조 STA 연결을 방지하는 정책은 없습니다.
- 매개 변수가 로 설정된
TRUE
wlan_intf_opcode_secondary_sta_synchronized_connections opcode를 사용하여 WlanSetInterface를 호출한 애플리케이션이 하나 이상 있습니다.
이중 STA 인터페이스 쿼리
어댑터가 이중 STA에 대해 구성되었는지 여부를 확인하고 보조 STA 인터페이스 GUID목록을 얻으려면 애플리케이션이 wlan_intf_opcode_secondary_sta_interfaces opcode를 사용하여 WlanQueryInterface(wlanapi.h)를 호출해야 합니다.
이 opcode는 기본 스테이션(STA) 인터페이스의 GUID ( WlanEnumInterfaces 호출로 얻을 수 있음)를 매개 변수로 사용하고 해당 기본 STA 인터페이스와 연결된 보조 STA 인터페이스 목록을 반환합니다.
보조 STA 인터페이스 목록을 가져오는 방법의 예는 다음과 같습니다.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <Windot11.h> // for DOT11_SSID struct
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
DWORD QueryDualStaInterfaces()
{
HANDLE hClient;
DWORD version;
DWORD dwResult = WlanOpenHandle(WLAN_API_VERSION_2_0, nullptr, &version, &hClient);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
return dwResult;
}
PWLAN_INTERFACE_INFO_LIST pPrimaryIntfList = nullptr;
dwResult = WlanEnumInterfaces(hClient, nullptr, &pPrimaryIntfList);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanEnumInterfaces FAILed, error = %u\n", dwResult);
WlanCloseHandle(hClient, NULL);
return dwResult;
}
wprintf(L"There are %u primary interfaces in the system\n", pPrimaryIntfList->dwNumberOfItems);
for (UINT i = 0; i < pPrimaryIntfList->dwNumberOfItems; i++)
{
WCHAR* strPrimaryUuid = nullptr;
if (UuidToStringW(&pPrimaryIntfList->InterfaceInfo[i].InterfaceGuid, reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid)) != RPC_S_OK)
{
strPrimaryUuid = nullptr;
}
DWORD dwDataSize = 0;
PWLAN_INTERFACE_INFO_LIST pSecondaryIntfList = nullptr;
dwResult = WlanQueryInterface(
hClient,
&pPrimaryIntfList->InterfaceInfo[i].InterfaceGuid,
wlan_intf_opcode_secondary_sta_interfaces,
NULL,
&dwDataSize,
reinterpret_cast<PVOID*>(&pSecondaryIntfList),
NULL);
if (dwResult == ERROR_SUCCESS)
{
wprintf(
L"\t[%d]\tInterface %ws (State = %d) has %u Secondary interfaces\n",
i,
strPrimaryUuid ? strPrimaryUuid : L"Unknown",
pPrimaryIntfList->InterfaceInfo[i].isState,
pSecondaryIntfList->dwNumberOfItems);
for (UINT j = 0; j < pSecondaryIntfList->dwNumberOfItems; j++)
{
WCHAR* strSecondaryUuid = nullptr;
if (UuidToStringW(&pSecondaryIntfList->InterfaceInfo[j].InterfaceGuid, reinterpret_cast<RPC_WSTR*>(&strSecondaryUuid)) == RPC_S_OK)
{
wprintf(
L"\t\t[%d]\tSecondary Interface GUID: %ws, (State = %d)\n",
j,
strSecondaryUuid,
pSecondaryIntfList->InterfaceInfo[j].isState);
RpcStringFreeW(reinterpret_cast<RPC_WSTR*>(&strSecondaryUuid));
}
}
WlanFreeMemory(pSecondaryIntfList);
}
else
{
wprintf(L"\t[%d]\tInterface %ws has 0 Secondary interfaces, error = %u\n", i, strPrimaryUuid ? strPrimaryUuid : L"Unknown", dwResult);
}
if (strPrimaryUuid)
{
RpcStringFreeW(reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid));
}
}
WlanFreeMemory(pPrimaryIntfList);
WlanCloseHandle(hClient, NULL);
return dwResult;
}
이중 STA 동기화 연결 상태 쿼리
어댑터가 기본 STA 인터페이스를 통해 연결한 후 보조 STA 인터페이스를 통해 자동으로 연결할지 여부를 확인하기 위해 애플리케이션은 wlan_intf_opcode_secondary_sta_synchronized_connections opcode를 사용하여 WlanQueryInterface를 호출하여 현재 상태를 쿼리할 수 있습니다.
해당 opcode는 기본 및 보조 STA 연결이 동기화되는지 여부를 나타내는 BOOL 값을 반환합니다.
다음은 이 상태를 쿼리하는 방법의 예입니다.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <Windot11.h> // for DOT11_SSID struct
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
DWORD QueryDualStaConnectivity()
{
HANDLE hClient;
DWORD version;
DWORD dwResult = WlanOpenHandle(WLAN_API_VERSION_2_0, nullptr, &version, &hClient);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
return dwResult;
}
PWLAN_INTERFACE_INFO_LIST pPrimaryIntfList = nullptr;
dwResult = WlanEnumInterfaces(hClient, nullptr, &pPrimaryIntfList);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanEnumInterfaces FAILed, error = %u\n", dwResult);
WlanCloseHandle(hClient, NULL);
return dwResult;
}
//
// Need to call the API only once to query/change the state.
//
if (pPrimaryIntfList->dwNumberOfItems)
{
WCHAR* strPrimaryUuid = nullptr;
if (UuidToStringW(&pPrimaryIntfList->InterfaceInfo[0].InterfaceGuid, reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid)) != RPC_S_OK)
{
strPrimaryUuid = nullptr;
}
DWORD dwDataSize = 0;
PBOOL bQueriedValue = NULL;
dwResult = WlanQueryInterface(
hClient,
&pPrimaryIntfList->InterfaceInfo[0].InterfaceGuid,
wlan_intf_opcode_secondary_sta_synchronized_connections,
NULL,
&dwDataSize,
(PVOID*)&bQueriedValue,
NULL);
if (dwResult == ERROR_SUCCESS)
{
wprintf(L"Secondary Sta Synchronized connections is currently %ws\n", *bQueriedValue ? L"Enabled" : L"Disabled");
WlanFreeMemory(bQueriedValue);
}
else
{
wprintf(L"Failed to query Secondary Sta Synchronized connections - error = %u\n", dwResult);
}
if (strPrimaryUuid)
{
RpcStringFreeW(reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid));
}
}
WlanFreeMemory(pPrimaryIntfList);
WlanCloseHandle(hClient, NULL);
return dwResult;
}
보조 STA 인터페이스에서 연결 사용
보조 STA 연결을 사용할 애플리케이션이 없는 한 Windows는 보조 STA 인터페이스에 연결되지 않습니다. Windows가 보조 STA 인터페이스에 연결하는지 여부를 제어하려면 애플리케이션이 보조 STA 인터페이스에서 연결을 사용하거나 사용하지 않도록 설정할지 여부를 지정하는 BOOL 매개 변수를 사용하여 wlan_intf_opcode_secondary_sta_synchronized_connections opcode를 사용하여 WlanSetInterface를 호출해야 합니다. 값은 TRUE
보조 STA 연결을 사용하도록 설정하려는 것을 나타내고 값은 FALSE
더 이상 보조 STA 연결이 필요하지 않음을 나타냅니다.
동일한 값(TRUE
또는 FALSE
)을 여러 번 사용하여 API를 호출하는 것은 중복되며, 새 값의 첫 번째 instance 기능만 변경됩니다.
애플리케이션에서 보조 STA 연결을 사용하도록 설정하면 보조 STA 연결을 사용할 것으로 예상되는 기간 동안 서비스에 대한 핸들을 열어 두어야 합니다. 애플리케이션이 명시적으로 보조 STA 연결을 사용하지 않도록 설정하면(opcode wlan_intf_opcode_secondary_sta_synchronized_connections 및 매개 변수 값을 FALSE
사용하여 WlanSetInterface를 호출하거나, WlanCloseHandle을 호출하여) 암시적으로(종료) Windows는 이후 특정 시점에 보조 STA 인터페이스에 대한 연결을 사용하지 않도록 설정합니다.
보조 STA 연결은 애플리케이션이 요청하면 한 번 이상 사용하도록 설정된 상태로 유지됩니다.
보조 STA 연결을 사용하거나 사용하지 않도록 설정하는 방법을 보여 주는 예제는 다음과 같습니다.
#ifndef UNICODE
#define UNICODE
#endif
#include <windows.h>
#include <wlanapi.h>
#include <Windot11.h> // for DOT11_SSID struct
#include <objbase.h>
#include <wtypes.h>
#include <stdio.h>
#include <stdlib.h>
// Need to link with Wlanapi.lib and Ole32.lib
#pragma comment(lib, "wlanapi.lib")
#pragma comment(lib, "ole32.lib")
DWORD SetDualStaConnectivity(BOOL bEnable)
{
HANDLE hClient;
DWORD version;
DWORD dwResult = WlanOpenHandle(WLAN_API_VERSION_2_0, nullptr, &version, &hClient);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanOpenHandle failed with error: %u\n", dwResult);
return dwResult;
}
PWLAN_INTERFACE_INFO_LIST pPrimaryIntfList = nullptr;
dwResult = WlanEnumInterfaces(hClient, nullptr, &pPrimaryIntfList);
if (dwResult != ERROR_SUCCESS)
{
wprintf(L"WlanEnumInterfaces FAILed, error = %u\n", dwResult);
WlanCloseHandle(hClient, NULL);
return dwResult;
}
//
// Only need to call the API once to query/change the state
//
if (pPrimaryIntfList->dwNumberOfItems)
{
WCHAR* strPrimaryUuid = nullptr;
if (UuidToStringW(&pPrimaryIntfList->InterfaceInfo[0].InterfaceGuid, reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid)) != RPC_S_OK)
{
strPrimaryUuid = nullptr;
}
dwResult = WlanSetInterface(
hClient,
&pPrimaryIntfList->InterfaceInfo[0].InterfaceGuid,
wlan_intf_opcode_secondary_sta_synchronized_connections,
sizeof(bEnable),
reinterpret_cast<PBYTE>(&bEnable),
NULL);
if (dwResult == ERROR_SUCCESS)
{
wprintf(L"Successfully set Sec Sta opcode = %x on Primary Interface %ws\n", bEnable, strPrimaryUuid);
}
else
{
wprintf(L"FAILed set Sec Sta opcode = %x on Primary Interface %ws -- error = %u\n", bEnable, strPrimaryUuid, dwResult);
}
if (strPrimaryUuid)
{
RpcStringFreeW(reinterpret_cast<RPC_WSTR*>(&strPrimaryUuid));
}
}
WlanFreeMemory(pPrimaryIntfList);
// Close the handle only when the app no longer needs the dual-sta connection
//
WlanCloseHandle(hClient, NULL);
return dwResult;
}