写于博客园,自己迁过来:
一.WlanOpenHandle打开一个客户端句柄
DWORD WINAPI
WlanOpenHandle(
__in DWORD dwClientVersion,
__reserved PVOID pReserved,
__out PDWORD pdwNegotiatedVersion,
__out PHANDLE phClientHandle
);
其取值如下:
1:Windows XP SP2
2:Windows Vista and Windows Server 2008
pReserved:保留值,设为NULL
pdwNegotiatedVersion:Specifies the version of the WLAN API that will be used in this session(out值,返回当前使用的version,比如你在xpsp2下它就返回1)
phClientHandle:Specifies a handle for the client to use in this session. This handle is used by other functions throughout the session(返回的客户端句柄,用于其他wifi函数调用)
MSDN上表示:
WlanOpenHandle will return an error message if the Wireless Zero Configuration (WZC) service has not been started or if the WZC service is not responsive.(必须启动WZC服务,不然WlanOpenHandle 返回失败)
附上启动WZC服务的方法:
1.开始菜单--运行--输入services.msc 2.双击启动Wireless Zero Configuration这个服务,点击“启动”3.改启动类型为自动,确定
二.WlanEnumInterfaces列出无线网卡设备
DWORD WINAPI
WlanEnumInterfaces(
__in HANDLE hClientHandle,
__reserved PVOID pReserved,
__deref_out PWLAN_INTERFACE_INFO_LIST *ppInterfaceList
);
hClientHandle:The client's session handle, obtained by a previous call to the WlanOpenHandle function.(WlanOpenHandle返回的那个客户端句柄)
pReserved:保留值,设为NULL
ppInterfaceList:Pointer to a WLAN_INTERFACE_INFO_LIST structure that contains the list of NIC interfaces.(网卡接口信息列表结构的指针,NIC:Network
Interface Card,也就是网络适配器/网卡),This function will allocate memory for the list of returned interfaces. The caller is responsible for freeing this memory using the WlanFreeMemory function(意思就是你传一个空指针的地址进去就行了,系统自动分配,你记得用完后用WlanFreeMemory释放)
typedef struct _WLAN_INTERFACE_INFO_LIST{
DWORD dwNumberOfItems;
DWORD dwIndex;
WLAN_INTERFACE_INFO InterfaceInfo[];} WLAN_INTERFACE_INFO_LIST, *PWLAN_INTERFACE_INFO_LIST;
dwNumberOfItems:Contains the number of items in the InterfaceInfo member(InterfaceInfo[ ] 中包含的单元的个数)
dwIndex:0到dwNumberOfItems-1, 一般用于在 WLAN_INTERFACE_INFO_LIST 作为参数传递时的一个传递偏移量。这个参数在用之前必须要进行初始化
InterfaceInfo[]:An array of WLAN_INTERFACE_INFO structures containing interface information.(包含WLAN_INTERFACE_INFO
结构体的阵列,用于记录接口信息)
typedef struct _WLAN_INTERFACE_INFO {
GUID InterfaceGuid;
WCHAR strInterfaceDescription[256];
WLAN_INTERFACE_STATE isState;
} WLAN_INTERFACE_INFO, *PWLAN_INTERFACE_INFO;
InterfaceGuid:Contains the GUID of the interface.(接口的GUID,GUID:Globally Unique Identifier(全球唯一标识符),据称是根椐时间,网卡,机器名等结合算法生成的,所以唯一,所以调用者在某些函数中可以通过GUID来指定特定网卡)
strInterfaceDescription[256]:Contains the description of the interface(接口的描绘信息,打开设备管理器-无线网卡属性可以看到描述)
isState:Contains a WLAN_INTERFACE_STATE value that indicates the current state of the interface.(包含一个 WLAN_INTERFACE_STATE值,标示这个NIC接口的当前状态)
typedef enum _WLAN_INTERFACE_STATE {
wlan_interface_state_not_ready = 0,
wlan_interface_state_connected,
wlan_interface_state_ad_hoc_network_formed,
wlan_interface_state_disconnecting,
wlan_interface_state_disconnected,
wlan_interface_state_associating,
wlan_interface_state_discovering,
wlan_interface_state_authenticating
} WLAN_INTERFACE_STATE, *PWLAN_INTERFACE_STATE;
WirelessLAN API for Windows XP SP2:
Only the wlan_interface_state_connected, wlan_interface_state_disconnected, and wlan_interface_state_authenticating values are supported.(xpsp2下仅支持已连接,已断开,生效中这三种状态)
三.WlanGetAvailableNetworkList获得有效的无线网络信息
DWORD WINAPI WlanGetAvailableNetworkList(
__in HANDLE hClientHandle,
__in const GUID* pInterfaceGuid,
__in DWORD dwFlags,
PVOID pReserved,
__out PWLAN_AVAILABLE_NETWORK_LIST* ppAvailableNetworkList
);
hClientHandle:The client's session handle, obtained by a previous call to the WlanOpenHandle function.(WlanOpenHandle返回的那个客户端句柄)
pInterfaceGuid:The GUID of the interface to be queried.(上面 WLAN_INTERFACE_INFO 的GUID,也就是网卡的GUID)
dwFlags:Controls the type of networks returned in the list(控制ppAvailableNetworkList中获得的网络类型),其值为0,1,2,3(1和2组合)四种选择
1:Include all ad-hoc network profiles in the available network list, including profiles that are not visible.(ad-hoc network :即点对点方式的无线网络,包括profiles name(配置文件名称)不可见(获得profiles name字符为空)的所有点对对无线网络)
2:Include all hidden network profiles in the available network list, including profiles that are not visible.(包括profiles name(配置文件名称)不可见(获得profiles name字符为空)的所有隐藏网络配置)
3:前二者的组合
ppAvailableNetworkList:Pointer to a WLAN_AVAILABLE_NETWORK_LIST to receive the returned list of visible
networks.(无线网络列表)This function will allocate memory for the list of returned interfaces. The caller is responsible for freeing this memory using the WlanFreeMemory function(传一个空指针的地址进去就行了,系统自动分配,调用者负责用WlanFreeMemory释放)
这个结构和WLAN_INTERFACE_INFO_LIST 相仿.
typedef struct _WLAN_AVAILABLE_NETWORK_LIST {
DWORD dwNumberOfItems;
DWORD dwIndex;
WLAN_AVAILABLE_NETWORK Network[1];
} WLAN_AVAILABLE_NETWORK_LIST,
*PWLAN_AVAILABLE_NETWORK_LIST;
dwNumberOfItems:Contains the number of items in the Network member(网络数目)
dwIndex:0到dwNumberOfItems-1,一般用于在WLAN_AVAILABLE_NETWORK_LIST 作为参数传递时的一个传递偏移量。这个参数在用之前必须要进行初始化
Network[1]:An array of WLAN_AVAILABLE_NETWORK structures containing interface information.(包含WLAN_AVAILABLE_NETWORK 的阵列,用于记录网络信息)
typedef struct _WLAN_AVAILABLE_NETWORK {
WCHAR strProfileName[256];
DOT11_SSID dot11Ssid;
DOT11_BSS_TYPE dot11BssType;
ULONG uNumberOfBssids;
BOOL bNetworkConnectable;
WLAN_REASON_CODE wlanNotConnectableReason;
ULONG uNumberOfPhyTypes;
DOT11_PHY_TYPE dot11PhyTypes[WLAN_MAX_PHY_TYPE_NUMBER];
BOOL bMorePhyTypes;
WLAN_SIGNAL_QUALITY wlanSignalQuality;
BOOL bSecurityEnabled;
DOT11_AUTH_ALGORITHM dot11DefaultAuthAlgorithm;
DOT11_CIPHER_ALGORITHM dot11DefaultCipherAlgorithm;
DWORD dwFlags;
DWORD dwReserved;
} WLAN_AVAILABLE_NETWORK, *PWLAN_AVAILABLE_NETWORK;
strProfileName:Contains the profile name associated with the network. If the network doesn't have a profile, this member will be empty. If multiple profiles are associated with the network, there will be multiple entries
with the same SSID in the visible network list. Profile names are case-sensitive. This string must be NULL-terminated(配置文件名,没有就为空,大小写敏感)
dot11Ssid:A DOT11_SSID structure that contains the SSID of the visible wireless network(网络的SSID,网络名,
SSID是Service Set Identifier的缩写,意思是:服务集标识。SSID技术可以将一个无线局域网分为几个需要不同身份验证的子网络,每一个子网络都需要独立的身份验证,只有通过身份验证的用户才可以进入相应的子网络,防止未被授权的用户进入本网络.
通俗地说,SSID便是你给自己的无线网络所取的名字)
typedef struct _DOT11_SSID {
ULONG uSSIDLength;
UCHAR ucSSID[DOT11_SSID_MAX_LENGTH];
} DOT11_SSID,
*PDOT11_SSID;
uSSIDLength:实际长度(byte单位)
ucSSID:SSID字符串,注意typedef unsigned char UCHAR;所以在Unicode环境下,要做字符转换再打印显示
dot11BssType:A DOT11_BSS_TYPE value that specifies whether the network is infrastructure or ad hoc.(指明网络是集中控制式还是点对点式)
typedef enum _DOT11_BSS_TYPE{ dot11_BSS_type_infrastructure//BSS dot11_BSS_type_infrastructure//IBSS dot11_BSS_type_any//other }DOT11_BSS_TYPE, *PDOT11_BSS_TYPE;
集中控制式(Infrastructure)也称独立无线网络,简称BSS,是在一种整合有线与无线局域网架构的应用模式,与ad- hoc不同的是配备无线网卡的电脑必须通过ap来进行无线通讯,设置后,无线网络设备就必须有AP(Access
Pointer)来沟通,一般有多个有线客户端和无线客户端围绕一个AP或无线路由器组成的服务集,所有客户端通过一个AP或无线路由器进行通信,客户端之间不直接进行通信,与对等(Ad Hoc)无线网络相比有更多的安全性和扩展能力
uNumberOfBssids: Indicates the number of BSSIDs in the network
ssid 是一个无线AP的名称。bssid 是这个无线AP的MAC地址
bNetworkConnectable:Indicates whether the network is connectable or not(是否可连接)
wlanNotConnectableReason :indicates why a network cannot be connected to. This member is only valid when bNetworkConnectable is FALSE(如果网络是不可连接的,这里返回原因)
wlanSignalQuality:A percentage value that represents the signal quality of the network(0-100网络信号)
bSecurityEnabled:Indicates whether security is enabled on the network(有没有安全锁)
dot11DefaultAuthAlgorithm:A DOT11_AUTH_ALGORITHM value that indicates the default authentication algorithm
used to join this network for the first time(首次加入该网络使用的默认认证算法,个人理解是和无线网络的安全认证算法(协议s)有关)
typedef enum _DOT11_AUTH_ALGORITHM {
DOT11_AUTH_ALGO_80211_OPEN = 1,//80211开放系统认证算法
DOT11_AUTH_ALGO_80211_SHARED_KEY = 2,//80211共享密钥认证算法
DOT11_AUTH_ALGO_WPA = 3,//wifi保护访问(WPA)
DOT11_AUTH_ALGO_WPA_PSK = 4,//WPA的简化版――WPA-PSK(预共享密钥)
DOT11_AUTH_ALGO_WPA_NONE = 5, DOT11_AUTH_ALGO_RSNA = 6,
DOT11_AUTH_ALGO_RSNA_PSK = 7,
DOT11_AUTH_ALGO_IHV_START = 0x80000000,
DOT11_AUTH_ALGO_IHV_END = 0xffffffff
} DOT11_AUTH_ALGORITHM, * PDOT11_AUTH_ALGORITHM;
dot11DefaultCipherAlgorithm:A DOT11_CIPHER_ALGORITHM value
that indicates the default cipher algorithm to be used when joining this network(DOT11_CIPHER_ALGORITHM 值表明了加入这个网络要使用的默认加密算法,个人理解是破解了这个加密算法后,咱就可免费蹭网了)
typedef enum _DOT11_CIPHER_ALGORITHM {
DOT11_CIPHER_ALGO_NONE = 0x00,//无加密算法可用或支持
DOT11_CIPHER_ALGO_WEP40 = 0x01,//有线对等协议(WEP)算法
DOT11_CIPHER_ALGO_TKIP = 0x02,// DOT11_CIPHER_ALGO_CCMP = 0x04,//TKIP由WEP使用的同样的加密引擎和RC4算法组成
DOT11_CIPHER_ALGO_WEP104 = 0x05,
DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100,
DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100,
DOT11_CIPHER_ALGO_WEP = 0x101,
DOT11_CIPHER_ALGO_IHV_START = 0x80000000,
DOT11_CIPHER_ALGO_IHV_END = 0xffffffff
} DOT11_CIPHER_ALGORITHM, * PDOT11_CIPHER_ALGORITHM;
四.WlanConnect连接某个网络
DWORD WINAPI WlanConnect(
__in HANDLE hClientHandle,
__in const GUID* pInterfaceGuid,
__in const PWLAN_CONNECTION_PARAMETERS pConnectionParameters,
PVOID pReserved
);
hClientHandle:The client's session handle, returned by a previous call to the WlanOpenHandle function
pInterfaceGuid:The GUID of the interface to use for the connection.(网卡的GUID,不是要连接的网络的ssid!)
pConnectionParameters:Pointer to a WLAN_CONNECTION_PARAMETERS structure that specifies the connection
type, mode, network profile, SSID that identfies the network, and other parameters(简言之,指出要连接的网络)
typedef struct _WLAN_CONNECTION_PARAMETERS {
WLAN_CONNECTION_MODE wlanConnectionMode;
LPCWSTR strProfile;
PDOT11_SSID pDot11Ssid;
PDOT11_BSSID_LIST pDesiredBssidList;
DOT11_BSS_TYPE dot11BssType;
DWORD dwFlags;
} WLAN_CONNECTION_PARAMETERS, *PWLAN_CONNECTION_PARAMETERS;
wlanConnectionMode:A WLAN_CONNECTION_MODE value
that specifies the mode of connection.Wireless LAN API for Windows XP SP2:Only the wlan_connection_mode_profile
value is supported(连接模式,xpsp2下只能使用配置文件连接)
typedef enum _WLAN_CONNECTION_MODE {
wlan_connection_mode_profile = 0,//使用配置文件连接
wlan_connection_mode_temporary_profile,//使用临时配置文件连接
wlan_connection_mode_discovery_secure,//使用发现的安全网络连接
wlan_connection_mode_discovery_unsecure,//使用发现的不安全网络连接
wlan_connection_mode_auto,//自动连接
wlan_connection_mode_invalid//...无效的
} WLAN_CONNECTION_MODE, *PWLAN_CONNECTION_MODE;
strProfile:Specifies the profile being used for the connection.If wlanConnectionMode is set to wlan_connection_mode_profile, then strProfile specifies the name of the profile used for
the connection. If wlanConnectionMode is set to wlan_connection_mode_temporary_profile, then strProfile specifies the XML representation of the profile used for the connection. If wlanConnectionMode is set
to wlan_connection_mode_discovery_secure, wlan_connection_mode_discovery_unsecure, or wlan_connection_mode_auto, then strProfile should be set to NULL(配置文件名)
pDot11Ssid:pointer to a DOT11_SSID structure that specifies the SSID of the network to connect to. This
parameter is optional. When set to NULL, all SSIDs in the profile will be tried. This parameter must not be NULL ifWLAN_CONNECTION_MODE is set to wlan_connection_mode_discovery_secure or wlan_connection_mode_discovery_unsecure.(对应WLAN_AVAILABLE_NETWORK 中的DOT11_SSID ,如设为NULL,配置文件的所有SSID都会被尝试,如果为wlan_connection_mode_discovery_secure
、wlan_connection_mode_discovery_unsecure不能设为NULL)
pDesiredBssidList:Pointer to a DOT11_BSSID_LISTstructure that contains the list of basic service set
(BSS) identifiers desired for the connection.Wireless LAN API for Windows XP SP2: This member must be NULL(xpsp2设为NULL就行了)
dot11BssType:A DOT11_BSS_TYPE value that indicates the BSS type of the network. If a
profile is provided, this BSS type must be the same as the one in the profile.(对应WLAN_AVAILABLE_NETWORK的 DOT11_BSS_TYPE)
结合前四个步骤,扫描NIC,获得可连接网络属性,再连接,我们可以实现网络属性显示和无密码的网络连接
下面介绍有密码的网络连接:
有密码的网络连接必须设置网络配置文件(WlanSetProfile,WlanGetProfile)
将密码写入配置xml中,再调用WlanConnect,因此理解xml的元素是关键.
五.配置xml文件
先给个完整的例子:这是从我笔记本上直接WlanGetProfile得到的,key部分已变成密文,不影响理解就行了
<?xml version="1.0"?>
<WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1">
<name>FAST_1797A2</name>
<SSIDConfig>
<SSID>
<hex>464153545F313739374132</hex>
<name>FAST_1797A2</name>
</SSID>
</SSIDConfig>
<connectionType>ESS</connectionType>
<MSM>
<security>
<authEncryption>
<authentication>WPA2PSK</authentication>
<encryption>AES</encryption>
<useOneX>false</useOneX>
</authEncryption>
<sharedKey>
<keyType>networkKey</keyType>
<protected>false</protected>
<keyMaterial>8C7AC8A03F13838846AA180B7F1B65A61D46FAB64743FFCA0E86F6EEB6DDC8AE</keyMaterial>
</sharedKey>
</security>
</MSM>
</WLANProfile>
一般要生成一个这样的xml,我们只需一个WLAN_AVAILABLE_NETWORK(前面ENUM的可用网络结构体)
Xml 的namespace一般都是 http://www.microsoft.com/networking/WLAN/profile/v1
FIPSMode使用http://www.microsoft.com/networking/WLAN/profile/v2
<name>:wlan的名称,和ssid名字一样就行了(个人测试)
<SSIDConfig>:contains one or more SSIDs(包含SSID的域,但MSDN也有这样的说明:
Windows XP with SP3 and Wireless LAN API for WindowsXP with SP2:At most one SSID element
can appear in a profile.(所以仅能传一个SSID元素进去就行了)
<SSID>:传WLAN_AVAILABLE_NETWORK的ssid名字进去
<connectionType>:WLAN_AVAILABLE_NETWORK的DOT11_BSS_TYPE:ESS和IBSS
<connectionMode>:auto/manual, If connectionType is
set to ESS, this value can be either auto or manual. The default value is auto if this element is absent.If connectionType is
set to IBSS, this value must be manual.(如果connectionType为ESS,可设自动或手动,默认为自动,IBSS必须为手动,上面XML为没有设置的ESS,默认为自动)
<autoSwitch>:WindowsXP with SP3 and Wireless LAN API for WindowsXP with SP2:This element is not supported.
<authEncryption>:specifies the authentication and encryption pair to be used for this profile,指定了认证和加密element.
<authentication>:DOT11_AUTH_ALGORITHM之间存在以下对应关系:
tenum _DOT11_AUTH_ALGORITHM {
DOT11_AUTH_ALGO_80211_OPEN = 1, //open
DOT11_AUTH_ALGO_80211_SHARED_KEY = 2, //shared
DOT11_AUTH_ALGO_WPA = 3, //WPA
DOT11_AUTH_ALGO_WPA_PSK = 4, //WPAPSK
DOT11_AUTH_ALGO_WPA_NONE = 5, //WPA
DOT11_AUTH_ALGO_RSNA = 6, //WPA2
DOT11_AUTH_ALGO_RSNA_PSK = 7, //WPA2PSK
DOT11_AUTH_ALGO_IHV_START = 0x80000000, //open
DOT11_AUTH_ALGO_IHV_END = 0xffffffff //open
} DOT11_AUTH_ALGORITHM, * PDOT11_AUTH_ALGORITHM;
<encryption>:DOT11_CIPHER_ALGORITHM之间存在以下对应关系:
typedef enum _DOT11_CIPHER_ALGORITHM {
DOT11_CIPHER_ALGO_NONE = 0x00, //none
DOT11_CIPHER_ALGO_WEP40 = 0x01, //WEP
DOT11_CIPHER_ALGO_TKIP = 0x02, //TKIP
DOT11_CIPHER_ALGO_CCMP = 0x04, //AES
DOT11_CIPHER_ALGO_WEP104 = 0x05, //AES
DOT11_CIPHER_ALGO_WPA_USE_GROUP = 0x100, //AES
DOT11_CIPHER_ALGO_RSN_USE_GROUP = 0x100, //AES
DOT11_CIPHER_ALGO_WEP = 0x101, //WEP
DOT11_CIPHER_ALGO_IHV_START = 0x80000000, //none
DOT11_CIPHER_ALGO_IHV_END = 0xffffffff //none
} DOT11_CIPHER_ALGORITHM, * PDOT11_CIPHER_ALGORITHM;
The AES encryption method is as specified in the 802.1X and 802.11i specifications.
<keyType>:When the encryption element has a value of WEP, keyType must
be set to networkKey.(当encryption是WEP时,必须为networkKey,看了MSDN的profile,其余全部用passPhrase)
<protected>: For profiles intended for use on Windows XP with Service Pack 3 (SP3) or Wireless LAN API for Windows XP with Service Pack 2 (SP2), protectedmust have a value of FALSE. (必须设为FALSE以支持xp)
<keyMaterial>:密码明文放入即可,如果使用了加密算法,再取出来就是密文了
六.WlanSetProfile写入配置文件
DWORD WINAPI WlanSetProfile(
__in HANDLE hClientHandle,//不解释
__in const GUID* pInterfaceGuid, //不解释
__in DWORD dwFlags,//0表示全部用户
__in LPCWSTR strProfileXml,//前面的XML
__in_opt LPCWSTR strAllUserProfileSecurity,//xp下必须为NULL
__in BOOL bOverwrite,//如已存在profile,是否覆盖
__in PVOID pReserved,
七. WlanDisconnect断开连接
DWORD WINAPI
WlanDisconnect(
__in HANDLE hClientHandle, //不解释
__in CONST GUID *pInterfaceGuid, //不解释
__reserved PVOID pReserved
);
附录
xml元素我主要参考:http://msdn.microsoft.com/en-us/library/ms706965(v=vs.85).asp