Delen via


Dual-STA query en configuratie

Notitie

Als u wilt ontwikkelen voor de functies die in dit onderwerp worden beschreven, is de Windows 11 SDK (10.0.22000.194) en hoger nodig.

Er zijn twee soorten interfaces gekoppeld aan adapters die ondersteuning bieden voor dual-stationverbindingen (dual-STA)-verbindingen: primaire STA-interfaces en secundaire STA-interfaces. Alle adapters maken een primaire STA-interface beschikbaar, maar alleen adapters die de dual-STA-functionaliteit ondersteunen, maken secundaire STA-interfaces beschikbaar.

Windows maakt standaard alleen verbinding op de primaire STA-interface. Windows maakt alleen verbinding op de secundaire STA-interface als aan alle volgende voorwaarden wordt voldaan:

  1. Het stuurprogramma geeft ondersteuning aan voor secundaire STA-interfaces in de mogelijkheden.
  2. Er is geen beleid dat secundaire STA-connectiviteit verhindert.
  3. Er is ten minste één toepassing die de WlanSetInterface- met de wlan_intf_opcode_secondary_sta_synchronized_connections opcode heeft aangeroepen met de parameter die is ingesteld op TRUE.

Query's uitvoeren op dual-STA-interfaces

Om te bepalen of een adapter is geconfigureerd voor dual-STA en om de lijst met secundaire STA-interface GUID-s op te halen, moet uw toepassing WlanQueryInterface (wlanapi.h) aanroepen met de wlan_intf_opcode_secondary_sta_interfaces opcode.

Deze opcode neemt als parameter de GUID- van de primaire sta-interface (sta) (die kan worden verkregen door een aanroep van WlanEnumInterfaces) en retourneert een lijst met secundaire STA-interfaces die zijn gekoppeld aan die primaire STA-interface.

Hier volgt een voorbeeld van het ophalen van de lijst met secundaire STA-interfaces.

#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;
}

Query's uitvoeren op de status van gesynchroniseerde dubbele STA-verbindingen

Om te bepalen of een adapter automatisch verbinding maakt via de secundaire STA-interface na een verbinding via de primaire STA-interface, kan uw toepassing de huidige status opvragen door WlanQueryInterface- aan te roepen met de wlan_intf_opcode_secondary_sta_synchronized_connections opcode.

Deze opcode retourneert een BOOL- waarde die aangeeft of de primaire en secundaire STA-verbindingen worden gesynchroniseerd.

Hier volgt een voorbeeld van het uitvoeren van een query op deze status.

#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;
}

Verbindingen inschakelen op de secundaire STA-interface

Windows maakt geen verbinding op de secundaire STA-interfaces, tenzij er een toepassing bestaat die gebruikmaakt van de secundaire STA-verbinding. Als u wilt bepalen of Windows verbinding maakt op de secundaire STA-interface, moet uw toepassing WlanSetInterface aanroepen met de wlan_intf_opcode_secondary_sta_synchronized_connections opcode, met een BOOL- parameter die aangeeft of verbindingen moeten worden ingeschakeld of uitgeschakeld op de secundaire STA-interface. Een waarde van TRUE geeft aan dat u secundaire STA-connectiviteit wilt inschakelen, terwijl een waarde van FALSE aangeeft dat u geen secundaire STA-connectiviteit meer nodig hebt.

Het aanroepen van de API met dezelfde waarde (TRUE of FALSE) is meerdere keren redundant en alleen het eerste exemplaar van een nieuwe waarde zorgt ervoor dat de functionaliteit wordt gewijzigd. Zodra uw toepassing secundaire STA-connectiviteit heeft ingeschakeld, moet u de ingang geopend houden voor de service gedurende de periode die u verwacht de secundaire STA-verbinding te gebruiken. Zodra uw toepassing de secundaire STA-connectiviteit expliciet uitschakelt (door WlanSetInterface aan te roepen met de opcode-wlan_intf_opcode_secondary_sta_synchronized_connections en parameterwaarde van FALSE, of door WlanCloseHandle-aan te roepen), of impliciet (door af te sluiten), schakelt Windows de connectiviteit via de secundaire STA-interface op een bepaald moment daarna uit.

De secundaire STA-connectiviteit blijft ingeschakeld zolang ten minste één toepassing deze aanvraagt.

Hier volgt een voorbeeld waarin wordt getoond hoe u secundaire STA-connectiviteit inschakelt of uitschakelt.

#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;
}