You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WlanAPI WiFi连接问题:崩溃、SSID赋值及密码设置求助

Windows XP下MinGW编译WlanAPI WiFi连接问题解决方案

1. 修复PDOT11_SSID赋值崩溃问题

崩溃核心原因是内存未正确分配或SSID长度/内容拷贝逻辑错误。PDOT11_SSID是指向DOT11_SSID结构体的指针,不能直接赋值字符串,必须先初始化结构体、设置长度再拷贝内容:

// 正确的SSID赋值方式
DOT11_SSID ssid;
ZeroMemory(&ssid, sizeof(DOT11_SSID));
const char* target_ssid = "YourWiFiSSID";
ssid.uSSIDLength = strlen(target_ssid);
memcpy(ssid.ucSSID, target_ssid, ssid.uSSIDLength);
PDOT11_SSID pSsid = &ssid; // 直接取栈上结构体地址,无需动态分配

MinGW下需注意结构体对齐,可在头文件引入前添加:

#pragma pack(push, 1)
#include <wlanapi.h>
#pragma pack(pop)

2. 目标SSID密码的设置方法

Windows XP下连接加密WiFi(如WPA-PSK/WPA2-PSK),需通过XML配置文件传递密码,核心代码示例:

// 生成WPA2-PSK加密的配置文件内容
char profileXml[1024];
const char* wifi_password = "YourWiFiPassword";
snprintf(profileXml, sizeof(profileXml), 
    "<?xml version=\"1.0\"?>"
    "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"
    "<name>%s</name>"
    "<SSIDConfig>"
    "<SSID><name>%s</name></SSID>"
    "</SSIDConfig>"
    "<connectionType>ESS</connectionType>"
    "<connectionMode>auto</connectionMode>"
    "<MSM>"
    "<security>"
    "<authEncryption>"
    "<authentication>WPA2PSK</authentication>"
    "<encryption>AES</encryption>"
    "<useOneX>false</useOneX>"
    "</authEncryption>"
    "<sharedKey>"
    "<keyType>passPhrase</keyType>"
    "<protected>true</protected>"
    "<keyMaterial>%s</keyMaterial>"
    "</sharedKey>"
    "</security>"
    "</MSM>"
    "</WLANProfile>", target_ssid, target_ssid, wifi_password);

将该XML字符串传入WLAN_CONNECTION_PARAMETERS的strProfile字段即可。

3. 正确选择外接WiFi适配器接口

枚举所有WiFi适配器,通过接口描述筛选外接设备(如包含"Wireless"、"WiFi"关键词):

WLAN_INTERFACE_INFO_LIST* pIfList = NULL;
DWORD dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
if (dwResult != ERROR_SUCCESS) { /* 错误处理 */ }

// 遍历并筛选适配器
for (DWORD i = 0; i < pIfList->dwNumberOfItems; i++) {
    WLAN_INTERFACE_INFO ifInfo = pIfList->InterfaceInfo[i];
    printf("适配器%d: %s, GUID: %ws\n", i, ifInfo.strInterfaceDescription, ifInfo.InterfaceGuid);
    
    // 自动筛选外接WiFi适配器
    if (strstr(ifInfo.strInterfaceDescription, "Wireless") != NULL) {
        GUID targetInterfaceGuid = ifInfo.InterfaceGuid;
        break;
    }
}
WlanFreeMemory(pIfList);

若无法自动筛选,可手动打印所有适配器信息,选择对应外接设备的GUID。

完整可运行代码示例

#pragma pack(push, 1)
#include <windows.h>
#include <wlanapi.h>
#include <stdio.h>
#include <string.h>
#pragma pack(pop)

// MinGW编译命令:gcc wifi_connect.c -o wifi_connect.exe -lwlanapi

int main() {
    DWORD dwVersion = 0;
    HANDLE hClient = NULL;
    DWORD dwResult = WlanOpenHandle(2, NULL, &dwVersion, &hClient);
    if (dwResult != ERROR_SUCCESS) {
        printf("WlanOpenHandle失败,错误码: %d\n", dwResult);
        return 1;
    }

    // 枚举WiFi适配器
    WLAN_INTERFACE_INFO_LIST* pIfList = NULL;
    dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList);
    if (dwResult != ERROR_SUCCESS || pIfList->dwNumberOfItems == 0) {
        printf("未找到可用WiFi适配器,错误码: %d\n", dwResult);
        WlanCloseHandle(hClient, NULL);
        return 1;
    }

    // 选择第一个WiFi适配器(可根据需求修改筛选逻辑)
    GUID targetGuid = pIfList->InterfaceInfo[0].InterfaceGuid;
    printf("选中适配器: %s\n", pIfList->InterfaceInfo[0].strInterfaceDescription);
    WlanFreeMemory(pIfList);

    // 初始化SSID
    DOT11_SSID ssid;
    ZeroMemory(&ssid, sizeof(DOT11_SSID));
    const char* target_ssid = "TestWiFi";
    ssid.uSSIDLength = strlen(target_ssid);
    memcpy(ssid.ucSSID, target_ssid, ssid.uSSIDLength);

    // 生成加密配置文件
    char profileXml[1024];
    const char* wifi_password = "TestPassword123";
    snprintf(profileXml, sizeof(profileXml),
        "<?xml version=\"1.0\"?>"
        "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">"
        "<name>%s</name>"
        "<SSIDConfig>"
        "<SSID><name>%s</name></SSID>"
        "</SSIDConfig>"
        "<connectionType>ESS</connectionType>"
        "<connectionMode>auto</connectionMode>"
        "<MSM>"
        "<security>"
        "<authEncryption>"
        "<authentication>WPA2PSK</authentication>"
        "<encryption>AES</encryption>"
        "<useOneX>false</useOneX>"
        "</authEncryption>"
        "<sharedKey>"
        "<keyType>passPhrase</keyType>"
        "<protected>true</protected>"
        "<keyMaterial>%s</keyMaterial>"
        "</sharedKey>"
        "</security>"
        "</MSM>"
        "</WLANProfile>", target_ssid, target_ssid, wifi_password);

    // 配置连接参数
    WLAN_CONNECTION_PARAMETERS connParams;
    ZeroMemory(&connParams, sizeof(WLAN_CONNECTION_PARAMETERS));
    connParams.wlanConnectionMode = wlan_connection_mode_profile;
    connParams.strProfile = profileXml;
    connParams.pDot11Ssid = &ssid;
    connParams.dot11BssType = dot11_BSS_type_infrastructure;
    connParams.dwFlags = 0; // 连接隐藏SSID时改为WLAN_CONNECTION_HIDDEN_NETWORK

    // 发起连接
    dwResult = WlanConnect(hClient, &targetGuid, &connParams, NULL);
    if (dwResult == ERROR_SUCCESS) {
        printf("连接请求已发送,正在连接...\n");
    } else {
        printf("WlanConnect失败,错误码: %d\n", dwResult);
    }

    WlanCloseHandle(hClient, NULL);
    return 0;
}

编译与运行注意事项

  1. MinGW编译必须链接wlanapi库,命令:
    gcc wifi_connect.c -o wifi_connect.exe -lwlanapi
    
  2. 程序需以管理员权限运行,否则会出现权限不足错误。
  3. Windows XP需安装SP3补丁,以支持WPA2-PSK加密。

内容的提问来源于stack exchange,提问作者C.Unbay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:24:35