使用Native Wifi API查找無線網絡信息

微軟自XP SP2之後的系統提供了關於Wireless開發的API,

據MSDN描述,此SDK提供兩個主要功能,即:管理无线网络配置和管理无线网络连接。

 

使用這套API也很簡單,主要步驟如下:

  1. 使用WlanOpenHandle、WlanCloseHandle打開或關閉一個客戶端句柄。
  2. 使用WlanEnumInterfaces列舉系統中可用的Wireless設備接口,主要用到的就是它返回的每個無線網卡的GUID這個參數。
  3. 使用WlanGetInterfaceCapability獲取關於無線網卡的性能參數,(注意這個函數在XP SP2下是不被支持的)
  4. 使用WlanQueryInterface獲取關於無線網卡接口的某些參數。
  5. 使用WlanSetInterface設置無線網卡接口某些參數。
  6. 使用WlanScan列舉每個無線網卡接口上找到的可用無線AP。
  7. 使用WlanGetAvailableNetworkList獲取有效的無線網絡信息。
  8. 使用WlanGetProfile、WlanSetProfile、WlanDeleteProfile管理無線網絡配置信息。
  9. 使用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 INVOKE 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或更高時。

pReserved

這個參數設為NULL.

pdwNegotiatedVersion

此值可以設為NULL。

phClientHandle

一個句柄指針,用來接收獲得的客戶端句柄.

 

列舉系統中的網絡接口:

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 Return_Clean: 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 )

hClientHandle

使用WlanOpenHandle函數獲得的客戶端句柄。

pReserved

此值設為NULL。

ppInterfaceList

一個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 );

hClientHandle

使用WlanOpenHandle函數獲得的客戶端句柄。

pInterfaceGuid

使用WlanEnumInterfaces函數得到的網絡接口GUID,指針類型。

pDot11Ssid

一個DOT11_SSID結構指針,此函數將搜索此結構指定的網絡,如果設為NULL將會搜索所有網絡。

XP SP2:  必須設為NULL.
pIeData

一个WLAN_RAW_DATA结构指針,客户端配置可能包括提供信息和802.1X认证的要求,可以設為NULL。

XP SP2:  必須設為NULL.
pReserved

必須設為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 );

hClientHandle

使用WlanOpenHandle函數獲得的客戶端句柄。

pInterfaceGuid

使用WlanEnumInterfaces函數得到的網絡接口GUID,指針類型。

dwFlags
意思

WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES
0x00000001

包括所有可用的网络列表中特设的网络配置,包括配置文件不可见。

WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES
0x00000002

包括所有可用的网络列表中隐藏的网络配置,包括配置文件不可见。

pReserved

必須設為NULL.

ppAvailableNetworkList

一個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 Return_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

你可能感兴趣的:(汇编WIN32)