微軟自XP SP2之後的系統提供了關於Wireless開發的API,
據MSDN描述,此SDK提供兩個主要功能,即:管理无线网络配置和管理无线网络连接。
使用這套API也很簡單,主要步驟如下:
- 使用WlanOpenHandle、WlanCloseHandle打開或關閉一個客戶端句柄。
- 使用WlanEnumInterfaces列舉系統中可用的Wireless設備接口,主要用到的就是它返回的每個無線網卡的GUID這個參數。
- 使用WlanGetInterfaceCapability獲取關於無線網卡的性能參數,(注意這個函數在XP SP2下是不被支持的)
- 使用WlanQueryInterface獲取關於無線網卡接口的某些參數。
- 使用WlanSetInterface設置無線網卡接口某些參數。
- 使用WlanScan列舉每個無線網卡接口上找到的可用無線AP。
- 使用WlanGetAvailableNetworkList獲取有效的無線網絡信息。
- 使用WlanGetProfile、WlanSetProfile、WlanDeleteProfile管理無線網絡配置信息。
- 使用WlanConnect、WlanDisconnect連接或斷開某個無線網絡。
在我的這個程式中隻用到WlanOpenHandle、WlanCloseHandle、WlanEnumInterfaces、WlanScan、WlanGetAvailableNetworkList就可以搜索附近的無線網絡信息。
首先,要確保Wireless Zero Configuration服務是開啟狀態。
如果它被關閉就使用StartService啟動此服務:
首先先判斷服務是否以經啟動:
- INVOKE OpenSCManager, NULL, NULL, SC_MANAGER_ALL_ACCESS
- cmp eax, NULL
- je Return_Clean
- mov @hSCM, eax
- INVOKE OpenService, @hSCM, pszServiceName, SERVICE_ALL_ACCESS
- cmp eax, NULL
- je Return_Clean
- mov @hSvr, eax
- INVOKE RtlZeroMemory, addr @qss, sizeof QSS
- INVOKE QueryServiceStatus, @hSvr, addr @qss
- cmp eax, NULL
- je Return_Clean
- mov eax, @qss.dwCurrentState
- cmp eax, 4h
- jne @F
- mov @ret, 0h
- jmp Return_Clean
- @@:
啟動服務:
- INVOKE StartService, @hSvr, 0h, NULL
- cmp eax, NULL
- je Return_Clean
注意:有時候Wireless Zero Configuration服務有可能被Disable掉,這時需要將它設為自動啟動或手動啟動才能調用StartService。
加入以下代碼:
- INVOKE QueryServiceConfig, @hSvr, NULL, 0h, addr dwBytesX
- INVOKE HeapAlloc, hHeap, HEAP_ZERO_MEMORY, dwBytesX
- mov @qsc, eax
- INVOKE QueryServiceConfig, @hSvr, @qsc, dwBytesX, addr dwBytesX
- cmp eax, NULL
- je Return_Clean
- assume ebx: PQSC
- mov ebx, @qsc
- mov eax, [ebx].dwStartType
- assume ebx: nothing
- cmp eax, 4h
- jne Return_Clean
- INVOKE ChangeServiceConfig, @hSvr, 0ffffffffh, 2h, 0ffffffffh, NULL, NULL, NULL, NULL, NULL, NULL, NULL
- @@:
獲得一個客戶端句柄:
- mov @ret, 1h
- mov @pil, NULL
- mov @hCli, NULL
- VOKE GetClientVersion
- cmp eax, 0h
- je Return_Clean
- mov ebx, eax
- mov dwReturned, 0h
- lea eax, @hCli
- push eax
- lea eax, dwReturned
- push eax
- push NULL
- push ebx
- call WlanOpenHandle
- cmp eax, 0h
- jne Return_Clean
- cmp @hCli, NULL
- je Return_Clean
其中WlanOpenHandle函數參數如下(MSDN):
- DWORD WINAPI WlanOpenHandle(
- __in DWORD dwClientVersion,
- PVOID pReserved,
- __out PDWORD pdwNegotiatedVersion,
- __out PHANDLE phClientHandle
- );
dwClientVersion
值 | 意思 |
---|---|
1 | 當系統版本為Windows XP SP2時。 |
2 | 當系統版本為Vista and Windows Server 2008或更高時。 |
這個參數設為NULL.
此值可以設為NULL。
一個句柄指針,用來接收獲得的客戶端句柄.
列舉系統中的網絡接口:
- lea eax, @pil
- push eax
- push NULL
- push @hCli
- call WlanEnumInterfaces
- cmp eax, 0h
- jne Return_Clean
- mov ebx, @pil
- mov ecx, [ebx]
- add ebx, 8h
- @@:
- dec ecx
- push ecx
- push ebx
- push pszAPName
- mov eax, ebx
- add eax, sizeof GUID
- push eax
- push ebx
- push @hCli
- call pfnEnumProc
- cmp eax, 0h
- je @F
- pop ebx
- add ebx, 214h
- pop ecx
- cmp ecx, 0h
- jg @B
- jmp Return_Clean
- @@:
- mov @ret, 0h
- lean:
- cmp @pil, NULL
- je @F
- push @pil
- call WlanFreeMemory
- @@:
- cmp @hCli, NULL
- je @F
- push @hCli
- call WlanCloseHandle
- @@:
- mov eax, @ret
- ret
其中WlanEnumInterfaces函數參數如下(MSDN):
- DWORD WINAPI WlanEnumInterfaces(
- __in HANDLE hClientHandle,
- __in PVOID pReserved,
- __out PWLAN_INTERFACE_INFO_LIST* ppInterfaceList
- )
使用WlanOpenHandle函數獲得的客戶端句柄。
此值設為NULL。
一個WLAN_INTERFACE_INFO_LIST結構指針的地址,你隻需要給它一個空指針就可以,用完後調用WlanFreeMemory釋放它。
掃描周圍的無線網絡:
- push NULL
- push NULL
- push NULL
- push pGuid
- push hWlanClient
- call WlanScan
- cmp eax, 0h
- jne Return_Clean
其中WlanScan函數參數如下(MSDN):
- DWORD WINAPI WlanScan(
- __in HANDLE hClientHandle,
- __in const GUID* pInterfaceGuid,
- __in_opt const PDOT11_SSID pDot11Ssid,
- __in_opt const PWLAN_RAW_DATA pIeData,
- PVOID pReserved
- );
使用WlanOpenHandle函數獲得的客戶端句柄。
使用WlanEnumInterfaces函數得到的網絡接口GUID,指針類型。
一個DOT11_SSID結構指針,此函數將搜索此結構指定的網絡,如果設為NULL將會搜索所有網絡。
XP SP2: 必須設為NULL.
一个WLAN_RAW_DATA结构指針,客户端配置可能包括提供信息和802.1X认证的要求,可以設為NULL。
XP SP2: 必須設為NULL.
必須設為NULL.
獲取搜索到的無線網絡列表:
- lea eax, @pil
- push eax
- push NULL
- push 1h
- push pGuid
- push hWlanClient
- call WlanGetAvailableNetworkList
- cmp eax, 0h
- jne Return_Clean
- mov ebx, @pil
- mov ecx, [ebx]
- add ebx, 8h
- @@:
- dec ecx
- push ecx
- push ebx
- mov edx, ebx
- add ebx, 516
- add edx, 25ch
- .if pszAPName == NULL
- push ebx
- push edx
- INVOKE lstrlen, ebx
- pop edx
- pop ebx
- .if eax > 0h
- INVOKE WlanPrintInfo, pszAdapterName, ebx, edx
- mov @ret, 0h
- .endif
- .else
- push ebx
- push edx
- INVOKE lstrcmpi, pszAPName, ebx
- pop edx
- pop ebx
- .if eax == 0h
- INVOKE WlanPrintInfo, pszAdapterName, ebx, edx
- mov @ret, 0h
- .endif
- .endif
- ;offset 604 is wlanSignalQuality
- pop ebx
- add ebx, 274h
- pop ecx
- cmp ecx, 0h
- jg @B
- jmp Return_Clean
- @@:
- Return_Clean:
- cmp @pil, NULL
- je @F
- push @pil
- call WlanFreeMemory
- @@:
- mov eax, @ret
- ret
其中WlanGetAvailableNetworkList函數參數如下(MSDN):
- DWORD WINAPI WlanGetAvailableNetworkList(
- __in HANDLE hClientHandle,
- __in const GUID* pInterfaceGuid,
- __in DWORD dwFlags,
- PVOID pReserved,
- __out PWLAN_AVAILABLE_NETWORK_LIST* ppAvailableNetworkList
- );
使用WlanOpenHandle函數獲得的客戶端句柄。
使用WlanEnumInterfaces函數得到的網絡接口GUID,指針類型。
值 | 意思 |
---|---|
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES | 包括所有可用的网络列表中特设的网络配置,包括配置文件不可见。 |
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES | 包括所有可用的网络列表中隐藏的网络配置,包括配置文件不可见。 |
必須設為NULL.
一個WLAN_AVAILABLE_NETWORK_LIST結構指針的地址,用來接收找到的網絡信息列表,你隻需要給它一個空指針就可以,用完後調用WlanFreeMemory釋放它。
最後,設用WlanPrintInfo打印搜索到的信息:
- WlanPrintInfo proc pszAdapterName:DWORD, pszAPName:DWORD, dwSignalQuality:DWORD
- LOCAL @arry[100h]: BYTE
- LOCAL @float: DWORD
- mov @float, 0h
- INVOKE RtlZeroMemory, addr @arry, 100h
- INVOKE WideCharToMultiByte, 0h, 0h, pszAdapterName, 100h, addr @arry, 100h, 0h, 0h
- mov ebx, dwSignalQuality
- mov eax, [ebx]
- and eax, 7fh
- mov ecx, [ebx]
- and ecx, 7fh
- mov edx, -100
- test eax, 1h
- jz @F
- mov @float, 352eh
- @@:
- shr eax, 1h
- add edx, eax
- INVOKE wsprintf, addr szPrintBuffer, addr szPrintFormat, addr @arry, pszAPName, ecx, edx, addr @float
- INVOKE lstrlen, addr szPrintBuffer
- mov edx, eax
- INVOKE WriteFile, hStdOut, addr szPrintBuffer, edx, addr dwBytesX, NULL
- ret
- WlanPrintInfo endp
初始化WlanAPI,本例中我是使用LoadLibrary和GetProcAddress調用Wlan API的。所以需要以下步驟:
- WlanInitialize proc
- LOCAL @ret: DWORD
- mov @ret, 1h
- INVOKE LoadLibrary, addr szWlanLibrary
- cmp eax, NULL
- je Return_Code
- mov hWlanModule, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanAllocateMemory
- cmp eax, NULL
- je Return_Code
- mov WlanAllocateMemory, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanFreeMemory
- cmp eax, NULL
- je Return_Code
- mov WlanFreeMemory, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanOpenHandle
- cmp eax, NULL
- je Return_Code
- mov WlanOpenHandle, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanCloseHandle
- cmp eax, NULL
- je Return_Code
- mov WlanCloseHandle, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanEnumInterfaces
- cmp eax, NULL
- je Return_Code
- mov WlanEnumInterfaces, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanGetInterfaceCapability
- mov WlanGetInterfaceCapability, eax
- ;and @val, eax ;This function is not supported for Windows XP SP2.
- INVOKE GetProcAddress, hWlanModule, addr szWlanQueryInterface
- cmp eax, NULL
- je Return_Code
- mov WlanQueryInterface, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanSetInterface
- cmp eax, NULL
- je Return_Code
- mov WlanSetInterface, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanScan
- cmp eax, NULL
- je Return_Code
- mov WlanScan, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanGetAvailableNetworkList
- cmp eax, NULL
- je Return_Code
- mov WlanGetAvailableNetworkList, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanGetProfile
- cmp eax, NULL
- je Return_Code
- mov WlanGetProfile, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanSetProfile
- cmp eax, NULL
- je Return_Code
- mov WlanSetProfile, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanDeleteProfile
- cmp eax, NULL
- je Return_Code
- mov WlanDeleteProfile, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanConnect
- cmp eax, NULL
- je Return_Code
- mov WlanConnect, eax
- INVOKE GetProcAddress, hWlanModule, addr szWlanDisconnect
- cmp eax, NULL
- je Return_Code
- mov WlanDisconnect, eax
- mov @ret, 0h
- turn_Code:
- mov eax, @ret
- ret
- WlanInitialize endp
- WlanUninitialize proc
- cmp hWlanModule, NULL
- je @F
- INVOKE FreeLibrary, hWlanModule
- @@:
- mov WlanAllocateMemory, NULL
- mov WlanFreeMemory, NULL
- mov WlanOpenHandle, NULL
- mov WlanCloseHandle, NULL
- mov WlanEnumInterfaces, NULL
- mov WlanGetInterfaceCapability, NULL
- mov WlanQueryInterface, NULL
- mov WlanSetInterface, NULL
- mov WlanScan, NULL
- mov WlanGetAvailableNetworkList, NULL
- mov WlanGetProfile, NULL
- mov WlanSetProfile, NULL
- mov WlanDeleteProfile, NULL
- mov WlanConnect, NULL
- mov WlanDisconnect, NULL
- mov eax, 0h
- ret
- WlanUninitialize endp