The Road to Delphi

Delphi – Free Pascal – Oxygene


9 Comments

Checking if a TCP port is Open using Delphi and Winsocks

Many times we need to know if a TCP port is open or not, here I leave a function to perform this task using winsock.

Code tested in Delphi 7, 2007 and 2010.


uses
  Winsock;

function PortTCP_IsOpen(dwPort : Word; ipAddressStr:AnsiString) : boolean;
var
  client : sockaddr_in;
  sock   : Integer;

  ret    : Integer;
  wsdata : WSAData;
begin
 Result:=False;
 ret := WSAStartup($0002, wsdata); //initiates use of the Winsock DLL
  if ret<>0 then exit;
  try
    client.sin_family      := AF_INET;  //Set the protocol to use , in this case (IPv4)
    client.sin_port        := htons(dwPort); //convert to TCP/IP network byte order (big-endian)
    client.sin_addr.s_addr := inet_addr(PAnsiChar(ipAddressStr));  //convert to IN_ADDR  structure
    sock  :=socket(AF_INET, SOCK_STREAM, 0);    //creates a socket
    Result:=connect(sock,client,SizeOf(client))=0;  //establishes a connection to a specified socket
  finally
  WSACleanup;
  end;
end;

see this sample of usage

begin
 if PortTCP_IsOpen(3306,'127.0.0.1') then 
  DoMyStuff();
end;


25 Comments

Detecting Wifi Networks Using Delphi and Native Wifi API

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.
ScanWifi Image

ScanWifi Image


13 Comments

Detecting Wifi Networks Using Delphi Prism.

The next code uses the Managed Wifi API, The library uses the Native Wifi API, available since Windows Vista and Windows XP SP2 (in a limited fashion, and only after applying a hotfix provided in KB article 918997). Older versions of Windows are not supported.

Before to compile the code you need to download the library from this location. Build the project “ManagedWifi.csproj” and then add the reference to the source code listed below.
namespace DelphiPrismWifidetection;
//Author : Rodrigo Ruz. 2009-09-29
//Shine Your crazy Diamond.

interface

uses
NativeWifi,//You must add the reference to the library ManagedWifi.dll
System.Text;

type
  ConsoleApp = class
  private
    class method GetStringForSSID(ssid : Wlan.Dot11Ssid ) : string;
    class method GetStringFornumberOfBssids (numberOfBssids : Int32 ) : string;
  public
    class method Main;
  end;

implementation

class method ConsoleApp.GetStringForSSID(ssid : Wlan.Dot11Ssid ) : string;
begin
    Result:= Encoding.ASCII.GetString( ssid.SSID, 0, Int32( ssid.SSIDLength) );
end;

class method ConsoleApp.GetStringFornumberOfBssids (numberOfBssids : Int32 ) : string;
begin
  case numberOfBssids of
  1: Result:='infrastructure';
  2: Result:='independent';
  3: Result:='any';
  else
  Result:='Unknow';
  end; // case
end;

class method ConsoleApp.Main;
begin
            var client : WlanClient  := new WlanClient();
            for each  wlanIface in client.Interfaces  do
            begin
                var networks : Array of  Wlan.WlanAvailableNetwork  := wlanIface.GetAvailableNetworkList(NativeWifi.Wlan.WlanGetAvailableNetworkFlags.IncludeAllAdhocProfiles);
                for each  network in networks  do
                begin
                    // for more info goto http://msdn.microsoft.com/en-us/library/ms707403%28VS.85%29.aspx
                    Console.WriteLine( "┌---------------------------------------------------------------¬");
                    Console.WriteLine( "|Network Detected      {0,-40} |", GetStringForSSID(network.dot11Ssid));
                    Console.WriteLine( "├---------------------------------------------------------------┤");
                    Console.WriteLine( "| CipherAlgorithm      {0,-40} |", network.dot11DefaultCipherAlgorithm.ToString());
                    Console.WriteLine( "| DefaultAuthAlgorithm {0,-40} |", network.dot11DefaultAuthAlgorithm.ToString());
                    Console.WriteLine( "| dot11Ssid            {0,-40} |", network.dot11Ssid.ToString());
                    Console.WriteLine( "| networkConnectable   {0,-40} |", network.networkConnectable.ToString());
                    if not network.networkConnectable then
                    Console.WriteLine( "| NotConnectableReason {0,-40} |", network.wlanNotConnectableReason.ToString());
                    Console.WriteLine( "| morePhyTypes         {0,-40} |", network.morePhyTypes.ToString());
                    Console.WriteLine( "| (BSS) network type   {0,-40} |", GetStringFornumberOfBssids(network.numberOfBssids));
                    Console.WriteLine( "| profileName          {0,-40} |", network.profileName.ToString());
                    Console.WriteLine( "| securityEnabled      {0,-40} |", network.securityEnabled.ToString());
                    Console.WriteLine( "| wlanSignalQuality    {0,-40} |", network.wlanSignalQuality.ToString());
                    Console.WriteLine( "└---------------------------------------------------------------┘");
                end;

            end;
            Console.ReadLine();
end;

end.

and the result is

Update

Download the full source code from here

Bye.


Leave a comment

Enumerating All Network resources using Delphi Prism.

The next code uses the windows library mrp.dll (mpr.dll is a module containing functions used to handle communication between the Windows operating system and the installed network providers) and call these functions :

  • WNetOpenEnum (starts an enumeration of network resources or existing connections)
namespace DelphiPrismNetworkScan;
//Author : Rodrigo Ruz. 2009-09-28
//Shine Your crazy Diamond.

interface

uses
System,
System.Runtime.InteropServices;

type
        RESOURCE_SCOPE_NET= enum
        (
        RESOURCE_CONNECTED  = $00000001,
        RESOURCE_GLOBALNET  = $00000002,
        RESOURCE_REMEMBERED = $00000003,
        RESOURCE_RECENT     = $00000004,
        RESOURCE_CONTEXT    = $00000005
        );

        RESOURCE_TYPE_NET = enum
        (
        RESOURCETYPE_ANY      = $00000000,
        RESOURCETYPE_DISK     = $00000001,
        RESOURCETYPE_PRINT    = $00000002,
        RESOURCETYPE_RESERVED = $00000008
        );

        RESOURCE_USAGE_NET = enum
        (
        RESOURCEUSAGE_CONNECTABLE   =$00000001,
        RESOURCEUSAGE_CONTAINER     =$00000002,
        RESOURCEUSAGE_NOLOCALDEVICE =$00000004,
        RESOURCEUSAGE_SIBLING       =$00000008,
        RESOURCEUSAGE_ATTACHED      =$00000010,
        RESOURCEUSAGE_ALL           =(RESOURCEUSAGE_CONNECTABLE OR RESOURCEUSAGE_CONTAINER OR RESOURCEUSAGE_ATTACHED)
        );

        RESOURCE_DISPLAYTYPE_NET = enum
        (
          RESOURCEDISPLAYTYPE_GENERIC       = $00000000,
          RESOURCEDISPLAYTYPE_DOMAIN        = $00000001,
          RESOURCEDISPLAYTYPE_SERVER        = $00000002,
          RESOURCEDISPLAYTYPE_SHARE         = $00000003,
          RESOURCEDISPLAYTYPE_FILE          = $00000004,
          RESOURCEDISPLAYTYPE_GROUP         = $00000005,
          RESOURCEDISPLAYTYPE_NETWORK       = $00000006,
          RESOURCEDISPLAYTYPE_ROOT          = $00000007,
          RESOURCEDISPLAYTYPE_SHAREADMIN    = $00000008,
          RESOURCEDISPLAYTYPE_DIRECTORY     = $00000009,
          RESOURCEDISPLAYTYPE_TREE          = $0000000A,
          RESOURCEDISPLAYTYPE_NDSCONTAINER  = $0000000B
        );

  NETRESOURCE  = public record
    var     dwScope         : RESOURCE_SCOPE_NET;
    var     dwType          : RESOURCE_TYPE_NET;
    var     dwDisplayType   : RESOURCE_DISPLAYTYPE_NET;
    var     dwUsage         : RESOURCE_USAGE_NET;
    var     [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]  lpLocalName : String;
    var     [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]  lpRemoteName: String;
    var     [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]  lpComment   : String;
    var     [MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPTStr)]  lpProvider  : String;
  end;

  ConsoleApp = class
  public
        [DllImport("mpr.dll", CharSet:=CharSet.Auto)]
        class method WNetEnumResource(hEnum: IntPtr; var lpcCount: Integer; lpBuffer: IntPtr; var lpBufferSize: Integer): Integer;external;
        [DllImport("mpr.dll", CharSet:=CharSet.Auto)]
        class method WNetOpenEnum( dwScope: RESOURCE_SCOPE_NET; dwType: RESOURCE_TYPE_NET; dwUsage: RESOURCE_USAGE_NET; [MarshalAs(UnmanagedType.AsAny)]  [&In()]  lpNetResource: Object; out lphEnum: IntPtr): Integer;external;
        [DllImport("mpr.dll", CharSet:=CharSet.Auto)]
        class method WNetCloseEnum(hEnum: IntPtr): Integer;external;
        class method InitScan(Dummy: Object);
        class method Main;
  end;

implementation

class method ConsoleApp.InitScan(Dummy: Object);
  var
  iRet     : Integer;
  ptrHandle: IntPtr  := new IntPtr();
  entries  : Integer;
  buffer   : Integer := 16384;
  nr       : NETRESOURCE;
  ptrBuffer: IntPtr:=Marshal.AllocHGlobal(buffer);
begin
try
    //Init the enumeration , you can change the paremeters to filter.
    iRet := WNetOpenEnum(RESOURCE_SCOPE_NET.RESOURCE_GLOBALNET, RESOURCE_TYPE_NET.RESOURCETYPE_ANY, RESOURCE_USAGE_NET.RESOURCEUSAGE_ALL, Dummy, out ptrHandle);
    if iRet <> 0 then
    begin
      exit;
    end;

        while true do //infinite loop
        Begin
                entries := -1;
                buffer  := 16384;
                iRet    := WNetEnumResource(ptrHandle, var entries, ptrBuffer, var buffer); //Load the next resource

                if ((iRet <> 0)) OR ((entries < 1)) then //if fails or non exist any entries then exit
                begin
                Break;
                end;

            var ptr: Int32 := ptrBuffer.ToInt32();
            var i  : Int32 :=0;
            while i< entries do
            Begin
                nr := NETRESOURCE(Marshal.PtrToStructure(new IntPtr(ptr), typeOf(NETRESOURCE)));
                if RESOURCE_USAGE_NET.RESOURCEUSAGE_CONTAINER = (nr.dwUsage and RESOURCE_USAGE_NET.RESOURCEUSAGE_CONTAINER) then //if is a contanier the function scan the resource again.
                begin
                  InitScan(nr); //recursive call to the function
                end;

                ptr :=ptr+ Marshal.SizeOf( nr );
                Console.WriteLine("{0}", nr.dwDisplayType.ToString());
                Console.WriteLine(" Type       ={0}", nr.dwType.ToString());
                Console.WriteLine(" Usage      ={0}", nr.dwUsage.ToString());
                Console.WriteLine(" Scope      ={0}", nr.dwScope.ToString());
                Console.WriteLine(" LocalName  ={0}", nr.lpLocalName);
                Console.WriteLine(" RemoteName ={0}", nr.lpRemoteName);
                Console.WriteLine(" Description={0}", nr.lpComment);
                Console.WriteLine(" Provider   ={0}", nr.lpProvider);
                Console.WriteLine();

                inc(i);
            End;

        End;

  except
    on e: Exception do
    begin
      Console.WriteLine('Error ** ' + e.Message + ' ** Trace ' + e.StackTrace)
    end;
end;
end;

class method ConsoleApp.Main;
begin
      Console.WriteLine('Scannig Network....Wait a moment , be patient please');
      Console.WriteLine();
      InitScan(nil);
      Console.WriteLine('Scan Network Finish');
      Console.Read();
end;

end.

When you run this code you’ll get something like this

Bye.