Today we will use the Native Wifi API and Delphi to enumerate all Wifi Networks availables. In this link you can find a translation of the headers.
I wrote this code using these headers. Tested in Delphi 2007 and Windows Vista.
Try this link for a fixed and updated version of the Native Wifi Delphi headers.
{$APPTYPE CONSOLE} uses Windows, SysUtils, nduWlanAPI in 'nduWlanAPI.pas', nduWlanTypes in 'nduWlanTypes.pas'; function DOT11_AUTH_ALGORITHM_To_String( Dummy :Tndu_DOT11_AUTH_ALGORITHM):AnsiString; begin Result:=''; case Dummy of DOT11_AUTH_ALGO_80211_OPEN : Result:= '80211_OPEN'; DOT11_AUTH_ALGO_80211_SHARED_KEY : Result:= '80211_SHARED_KEY'; DOT11_AUTH_ALGO_WPA : Result:= 'WPA'; DOT11_AUTH_ALGO_WPA_PSK : Result:= 'WPA_PSK'; DOT11_AUTH_ALGO_WPA_NONE : Result:= 'WPA_NONE'; DOT11_AUTH_ALGO_RSNA : Result:= 'RSNA'; DOT11_AUTH_ALGO_RSNA_PSK : Result:= 'RSNA_PSK'; DOT11_AUTH_ALGO_IHV_START : Result:= 'IHV_START'; DOT11_AUTH_ALGO_IHV_END : Result:= 'IHV_END'; end; end; function DOT11_CIPHER_ALGORITHM_To_String( Dummy :Tndu_DOT11_CIPHER_ALGORITHM):AnsiString; begin Result:=''; case Dummy of DOT11_CIPHER_ALGO_NONE : Result:= 'NONE'; DOT11_CIPHER_ALGO_WEP40 : Result:= 'WEP40'; DOT11_CIPHER_ALGO_TKIP : Result:= 'TKIP'; DOT11_CIPHER_ALGO_CCMP : Result:= 'CCMP'; DOT11_CIPHER_ALGO_WEP104 : Result:= 'WEP104'; DOT11_CIPHER_ALGO_WPA_USE_GROUP : Result:= 'WPA_USE_GROUP OR RSN_USE_GROUP'; //DOT11_CIPHER_ALGO_RSN_USE_GROUP : Result:= 'RSN_USE_GROUP'; DOT11_CIPHER_ALGO_WEP : Result:= 'WEP'; DOT11_CIPHER_ALGO_IHV_START : Result:= 'IHV_START'; DOT11_CIPHER_ALGO_IHV_END : Result:= 'IHV_END'; end; end; procedure Scan(); const WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES =$00000001; var hClient : THandle; dwVersion : DWORD; ResultInt : DWORD; pInterface : Pndu_WLAN_INTERFACE_INFO_LIST; i : Integer; j : Integer; pAvailableNetworkList: Pndu_WLAN_AVAILABLE_NETWORK_LIST; pInterfaceGuid : PGUID; SDummy : AnsiString; begin ResultInt:=WlanOpenHandle(1, nil, @dwVersion, @hClient); try if ResultInt<> ERROR_SUCCESS then begin WriteLn('Error Open CLient'+IntToStr(ResultInt)); Exit; end; ResultInt:=WlanEnumInterfaces(hClient, nil, @pInterface); if ResultInt<> ERROR_SUCCESS then begin WriteLn('Error Enum Interfaces '+IntToStr(ResultInt)); exit; end; for i := 0 to pInterface^.dwNumberOfItems - 1 do begin Writeln('Interface ' + pInterface^.InterfaceInfo[i].strInterfaceDescription); WriteLn('GUID ' + GUIDToString(pInterface^.InterfaceInfo[i].InterfaceGuid)); Writeln(''); pInterfaceGuid:= @pInterface^.InterfaceInfo[pInterface^.dwIndex].InterfaceGuid; ResultInt:=WlanGetAvailableNetworkList(hClient,pInterfaceGuid,WLAN_AVAILABLE_NETWORK_INCLUDE_ALL_ADHOC_PROFILES,nil,pAvailableNetworkList); if ResultInt<> ERROR_SUCCESS then begin WriteLn('Error WlanGetAvailableNetworkList '+IntToStr(ResultInt)); Exit; end; for j := 0 to pAvailableNetworkList^.dwNumberOfItems - 1 do Begin WriteLn(Format('Profile %s',[WideCharToString(pAvailableNetworkList^.Network[j].strProfileName)])); SDummy:=PAnsiChar(@pAvailableNetworkList^.Network[j].dot11Ssid.ucSSID); WriteLn(Format('NetworkName %s',[SDummy])); WriteLn(Format('Signal Quality %d ',[pAvailableNetworkList^.Network[j].wlanSignalQuality])+'%'); //SDummy := GetEnumName(TypeInfo(Tndu_DOT11_AUTH_ALGORITHM),integer(pAvailableNetworkList^.Network[j].dot11DefaultAuthAlgorithm)) ; SDummy:=DOT11_AUTH_ALGORITHM_To_String(pAvailableNetworkList^.Network[j].dot11DefaultAuthAlgorithm); WriteLn(Format('Auth Algorithm %s ',[SDummy])); SDummy:=DOT11_CIPHER_ALGORITHM_To_String(pAvailableNetworkList^.Network[j].dot11DefaultCipherAlgorithm); WriteLn(Format('Auth Algorithm %s ',[SDummy])); Writeln(''); End; end; finally WlanCloseHandle(hClient, nil); end; end; begin try Scan(); Readln; except on E:Exception do Writeln(E.Classname, ': ', E.Message); end; end.
December 12, 2009 at 1:53 pm
Two of us tested this code on 2 different pc’s with Delphi 2007 and Delphi 2010. One pc was in Norway, the other in the United States.
The code compiles and functions well on both systems… except Delphi 2010 reports 6 warnings:
[DCC Warning] nduWlanTypes.pas(38): W1012 Constant expression violates subrange bounds
[DCC Warning] nduWlanTypes.pas(39): W1012 Constant expression violates subrange bounds
[DCC Warning] nduWlanTypes.pas(62): W1012 Constant expression violates subrange bounds
[DCC Warning] nduWlanTypes.pas(63): W1012 Constant expression violates subrange bounds
[DCC Warning] nduWinDot11.pas(32): W1012 Constant expression violates subrange bounds
[DCC Warning] nduWinDot11.pas(33): W1012 Constant expression violates subrange bounds
Thank-you for writing the post.
February 17, 2010 at 3:54 pm
Works fine under Delphi 7 in France XP SP3 / INTEL 5300 AGN
Would be nice to also get channel number !
Pingback: All about WiFi Networks and WiFi Adapters using the WMI and Delphi « The Road to Delphi – a Blog about programming
May 30, 2012 at 6:31 am
Hi,
I’m trying to download the headers but link is broken… Where can i download it?
Thank you, and great job!!!
May 30, 2012 at 11:22 am
Try this link https://dl.dropbox.com/u/12733424/Blog/WlanAPI.rar
December 3, 2012 at 9:31 am
Nice example!!!
But how to use a WlanGetNetworkBssList???? Dont’t work… help me, please…
January 15, 2013 at 9:39 am
What are you tried so far?
March 5, 2013 at 7:06 pm
Hi, great work, but the SSID returns non readable on Windows 7 64bit, I dont have an XP machine to test at the moment, I found an article relating to this issue in VB but the header translation needs updating http://www.vbforums.com/showthread.php?547916-List-available-wireless-networks-(using-WMI)-Help-pls
Hope you can help
March 6, 2013 at 6:12 pm
Hi, great work on the API however there seems to be an issue with the headers I think MS changed the output!, the SSID returns unreadable on windows 7 64bit, I understand this is due to a change in the format of the returned value, I found this related article http://www.vbforums.com/showthread.php?547916-List-available-wireless-networks-(using-WMI)-Help-pls hopefully you will be able to update the header conversation.
I am using windows 7 64bit and delphi 2010
Many thanks
March 6, 2013 at 6:45 pm
Hi, thought I provide an update I changed line 88 to
SDummy:=AnsiChar(@pAvailableNetworkList^.Network[j].dot11Ssid.ucSSID);
And it is now returning the correct SSID name.
March 6, 2013 at 9:18 pm
The problem was related to the UNICODE strings, the original post was made using Delphi 2007 which is not UNICODE. I just fix the sample code. Thanks for the report.
March 7, 2013 at 1:27 pm
Hi Again, is there a method to display the AP MAC Address in the output?
January 29, 2015 at 9:53 am
Is there a way to check if one of the connections is active?
January 29, 2015 at 11:24 am
You must use the WlanQueryInterface method and check if the value of the iState field is wlan_interface_state_connected. for a sample check the MSDN documentation.
January 30, 2015 at 9:58 am
Hey, Rodrigo.
It’s working.
Here is how I used it
ResultInt := WlanQueryInterface(hClient, pInterfaceGuid,
wlan_intf_opcode_interface_state, nil, @pdwDataSize,
@ppData, nil);if (ResultInt = ERROR_SUCCESS) then
if ResultInt = ERROR_SUCESS then
WriteLn(Format(‘Status: %s’, [
WLAN_INTERFACE_STATE_To_String(ppData^.isState)]))
the function WLAN_INTERFACE_STATE_To_String is simple as:
function WLAN_INTERFACE_STATE_To_String(
Dummy: Tndu_WLAN_INTERFACE_STATE): string;
var
s: string;
begin
s := ”;
case Dummy of
wlan_interface_state_not_ready: s :=’Not ready’;
wlan_interface_state_connected: s := ‘Connected’;
wlan_interface_state_ad_hoc_network_formed: s := ‘ad hoc network’;
wlan_interface_state_disconnecting: s := ‘Disconnecting’;
wlan_interface_state_disconnected: s := ‘Disconnected’;
wlan_interface_state_associating: s := ‘Associating’;
wlan_interface_state_discovering: s := ‘Discovering’;
wlan_interface_state_authenticating: s := ‘Authenticating’;
end;
Result := s;
end;
That’s it.
Thank you.
December 30, 2015 at 5:37 pm
Hello !
I’m desperately looking for a good sample using right headers and use of WlanGetNetworkBssList !
The first Tndu_WLAN_BSS_ENTRY item return seems correct but the following ones are completely scrambled….
I’m unable to download the “fixed” header you provided (broken Dropbox link).
Would you please post again a full package ?
Thanks for this excellent site !
December 30, 2015 at 8:24 pm
Hi the updated headers of the Native Wifi API are hosted on github.
January 1, 2016 at 9:40 am
Then there is a bug in the Tndu_WLAN_BSS_ENTRY definition
dot11Ssid: Tndu_DOT11_SSID;
uPhyId: ulong;
dot11Bssid: Tndu_DOT11_MAC_ADDRESS;
dot11BssType: Tndu_DOT11_BSS_TYPE;
//dot11BssPhyType: Tndu_DOT11_PHY_TYPE;
lRssi: long;
uLinkQuality: ulong;
bInRegDomain: Boolean;
should be replaced by
dot11Ssid: Tndu_DOT11_SSID;
uPhyId: ulong;
dot11Bssid: Tndu_DOT11_MAC_ADDRESS;
dot11BssType: Tndu_DOT11_BSS_TYPE;
dot11BssPhyType: ulonglong;
lRssi: long;
uLinkQuality: ulong;
bInRegDomain: Boolean;
otherwise, data are “shifted” in the record, causing the problem I faced with initial headers.
With my modification, function works fine.
January 2, 2016 at 6:18 pm
When using WlanQueryInterface to retrieve stats about my adapter, could you explain to me why multiple PHY are reported for a single adapter ? Where can i find the “description” of these PHY interfaces ?
January 2, 2016 at 6:41 pm
Another comment, in Tndu_DOT11_PHY_TYPE, there are 2 types missing :
dot11_phy_type_ht = 7,
dot11_phy_type_vht = 8,
as per https://msdn.microsoft.com/en-us/library/windows/desktop/ms706015%28v=vs.85%29.aspx
required for 802.11n and 802.11ac
January 3, 2016 at 10:58 pm
Thanks for your comments. I will check and update the repository ASAP. Also you can make a pull request with your changes.
January 7, 2016 at 4:58 pm
I’m not familiar with GitHub… i’d prefer that you do the fix :)
I’ll post values for 802.11ad as soon as possible
January 17, 2016 at 1:34 pm
Hello,
Final definition of the currently incorrect nduWlanAPI :
Tndu_WLAN_BSS_ENTRY = record
dot11Ssid: Tndu_DOT11_SSID;
uPhyId: ulong;
dot11Bssid: Tndu_DOT11_MAC_ADDRESS;
filler1:array[0..1]of byte;
dot11BssType: Tndu_DOT11_BSS_TYPE;
filler2:array[0..2]of byte;
dot11BssPhyType: ulong;
lRssi: long;
uLinkQuality: ulong;
bInRegDomain: Boolean;
usBeaconPeriod: ushort;
ullTimestamp: ulonglong;
ullHostTimestamp: ulonglong;
usCapabilityInformation: ushort;
ulChCenterFrequency: ulong;
wlanRateSet: Tndu_WLAN_RATE_SET;
ulIeOffset: ulong;
ulIeSize: ulong;
end;
November 3, 2019 at 1:06 pm
Any update of these source code files ?
November 3, 2019 at 1:07 pm
(Try this link for a fixed and updated version of the Native Wifi Delphi headers => Error 404)