微軟自XP SP2之後的系統提供了關於Wireless開發的API,
據MSDN描述,此SDK提供兩個主要功能,即:管理无线网络配置和管理无线网络连接。
使用這套API也很簡單,主要步驟如下:
在我的這個程式中隻用到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或更高時。 |
這個參數設為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 |
包括所有可用的网络列表中特设的网络配置,包括配置文件不可见。 |
WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_MANUAL_HIDDEN_PROFILES |
包括所有可用的网络列表中隐藏的网络配置,包括配置文件不可见。 |
必須設為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