Я хочу работать с Wi-Fi с Delphi. Как?

В моей программе Delphi (в Windows Xp) я хочу проверить доступные сети Wi-Fi. У вас есть идеи, как это сделать? Лучше всего, вероятно, использовать функцию MS WlanScan API, но я не нашел примера. Кто-нибудь может мне помочь?

Ответ 1

Вы можете использовать Native Wifi API, доступный с Windows Vista и Windows XP. Старые версии Windows не поддерживаются.

В этой ссылке вы можете найти очень хороший перевод заголовков.

Я написал этот код, используя эти заголовки. Протестировано в Delphi 2007 и Windows Vista.

program DetectWifiUsingDelphi;

{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  //TypInfo,
  nduWlanAPI   in 'nduWlanAPI.pas',
  nduWlanTypes in 'nduWlanTypes.pas';


function DOT11_AUTH_ALGORITHM_To_String( Dummy :Tndu_DOT11_AUTH_ALGORITHM):String;
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):String;
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               : string;
begin
  ResultInt:=WlanOpenHandle(1, nil, @dwVersion, @hClient);
  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:=PChar(@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;

  WlanCloseHandle(hClient, nil);

end;
begin
  try
    Scan();
    Readln;
  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

alt text http://i33.tinypic.com/2z83ubt.jpg

Bye.

Ответ 2

Вы также можете получить этот запрос, выполнив запрос WMI:

SELECT * FROM MSNdis_80211_ServiceSetIdentifier

Если вы специально ищете реализацию delphi, есть библиотека WMI, доступная из Magenta Systems, которая включает полный источник и может быть свободно используемый. Доступная загрузка включает скомпилированный исполняемый файл, в котором вы можете попробовать этот запрос, чтобы узнать, содержит ли он все данные, которые вы ищете. Единственным недостатком такого подхода является то, что служба WMI должна работать (обычно это не так много проблем).