从Connection Manager获取Wi-Fi连接状态

时间:2017-06-02 15:43:39

标签: c++ authentication visual-studio-2013 wlan

我有一些代码可以成功迭代wi-fi网络列表,并提供有关可用网络的反馈。这里显示的基本要求......

WlanOpenHandle(WLAN_API_VERSION, NULL, &dwVersion, &hSession);

PWLAN_INTERFACE_INFO_LIST pInterfaceInfoList = NULL;
WlanEnumInterfaces(hSession, NULL, &pInterfaceInfoList);

for(int i ...)
{
    PWLAN_AVAILABLE_NETWORK_LIST pAvailableNetworkList = NULL;
    WlanGetAvailableNetworkList(hSession, &interfaceGUID,
           WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES |
           WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES,
           NULL, &pAvailableNetworkList);
    for(int j ...)
    {
        WLAN_AVAILABLE_NETWORK network = pAvailableNetworkList->Network[j];
        :
    }
}

这一切都运行正常,在内部循环中,我能够通过网络数据结构访问我需要的所有属性,例如信号强度,安全标志等。

我无法获得的一件事是关于连接状态的信息,例如AUTHENTICATING或AUTHENTICATION_FAILED等,所以我试图在循环中引入另一个调用,如下所示......

CM_CONNECTION_DETAILS connectionDetails;
memset(&connectionDetails, 0, sizeof(CM_CONNECTION_DETAILS));

connectionDetails.Version = CM_CURRENT_VERSION;
const char* ccp = reinterpret_cast<const char*>(network.dot11Ssid.ucSSID);
mbstowcs(connectionDetails.szName, &ccp[0], network.dot11Ssid.uSSIDLength);

DWORD dwCount = sizeof(CM_CONNECTION_DETAILS);

CM_RESULT cmr = CmGetConnectionDetailsByName(connectionDetails.szName, 
           &connectionDetails, &dwCount);

if (cmr == CMRE_SUCCESS)
{
    :
}

在调用CmGetConnectionDetailsByName()函数时,CM_CONNECTION_DETAILS结构中的详细信息看起来是正确的(名称和版本),但该函数返回CMRE_INVALID_CONNECTION并且未填充结构。

我无法找到此调用成功的任何示例(只有几个对该调用的引用返回相同的CMRE_INVALID_CONNECTION代码)。

有没有人有成功使用呼叫的经验,或者建议更好的方法来找出网络的连接状态(即如果AUTHENTICATION正在进行或者AUTHENTICATION失败等)?

[我正在使用Visual Studio 2013 C ++(本机Windows应用程序,而不是MFC),目标是32位和Unicode,在Windows Compact 2013上运行]

1 个答案:

答案 0 :(得分:0)

下面的功能并没有给我提供我正在寻找的精细控制,但它确实至少让我有机会找到特定界面的状态。这意味着我可以查看接口当前是在进程中还是在进行身份验证,并且根据最终状态是连接还是断开连接,我可以查看身份验证是否成功。

WLAN_INTERFACE_STATE getNetworkState(HANDLE hSession, GUID* pGUID, std::wstring& wsState, bool bReportState=true)
{
    WLAN_INTERFACE_STATE result = wlan_interface_state_not_ready;
    DWORD dwDataSize;
    void* pData;
    DWORD dwErrorCode = WlanQueryInterface(hSession, pGUID, wlan_intf_opcode_interface_state, NULL, &dwDataSize, &pData, NULL);
    if (dwErrorCode == ERROR_SUCCESS && pData != NULL)
    {
        WLAN_INTERFACE_STATE* pState = reinterpret_cast<WLAN_INTERFACE_STATE*>(pData);
        if (pState != NULL)
        {
            switch (*pState)
            {
            case wlan_interface_state_not_ready:                wsState = L"NOT_READY"; break;
            case wlan_interface_state_connected:                wsState = L"CONNECTED"; break;
            case wlan_interface_state_ad_hoc_network_formed:    wsState = L"AD_HOC_NETWORK_FORMED"; break;
            case wlan_interface_state_disconnecting:            wsState = L"DISCONNECTING"; break;
            case wlan_interface_state_disconnected:             wsState = L"DISCONNECTED";  break;
            case wlan_interface_state_associating:              wsState = L"ASSOCIATING";   break;
            case wlan_interface_state_discovering:              wsState = L"DISCOVERING";   break;
            case wlan_interface_state_authenticating:           wsState = L"AUTHENTICATING";    break;
            }
            result = *pState;
        }
        WlanFreeMemory(pData);
    }
    return result;
}

此检查的一个限制是它不容易支持同一接口上的多个连接。此查询不允许我们查询状态所指的连接。

如果我找到更好的解决方案,我会在此报告。