首页  编辑  

IPHelper函数

Tags: /超级猛料/Network.网络通讯/TCP_IP/   Date Created:

Using the IP Helper API from Delphi

May 20, 2001

Borland Delphi 5Windows 2000

If you are building advanced Internet applications, you will often have the need to get information about the network configuration of the system on which your application is running. For example, you might need to retrieve the MAC address (sometimes called the physical address) of the network adapter or the IP address of the default DNS server. The IP Helper API allows you to retrieve such information on Windows 2000.

The IP Helper API <http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/rras/iphpport_7vz9.htm> (or IPHLPAPI or Internet Protocol Helper) is new to Windows 2000, and thus it is not directly usable from Delphi 5. Delphi 6 might contain the necessary header translations, but since Delphi 6 is not yet shipping (it has been announced <http://www.borland.com/about/press/2001/del6released.html> , though), it is impossible to confirm.

The sample application demonstrates using two IP Helper API functions, GetNetworkParams and GetAdaptersInfo. They are declared like this (translated from IPHLPAPI.H):

Function GetNetworkParams(FI : PFixedInfo; Var BufLen : Integer) : Integer;

        StdCall; External 'iphlpapi.dll' Name 'GetNetworkParams';

Function GetAdaptersInfo(AI : PIPAdapterInfo; Var BufLen : Integer) : Integer;

        StdCall; External 'iphlpapi.dll' Name 'GetAdaptersInfo';

As you can see, both of these functions are implemented in IPHLPAPI.DLL. The first function can be used to return overall information about the IP configuration of the system. The sample application uses the following procedure to demonstrate the usage of the function:

procedure TIPMainForm.GetNetworkParameters;

Var

 FI   : PFixedInfo;

 Size : Integer;

 Res  : Integer;

 I    : Integer;

 DNS  : PIPAddrString;

begin

 Size := 1024;

 GetMem(FI,Size);

 Res := GetNetworkParams(FI,Size);

 If (Res <> ERROR_SUCCESS) Then Begin

   SetLastError(Res);

   RaiseLastWin32Error;

 End;

 With Info,Lines do Begin

   Clear;

   Add('Host name: '+FI^.HostName);

   Add('Domain name: '+FI^.DomainName);

   If (FI^.CurrentDNSServer <> nil) Then

     Add('Current DNS Server: '+FI^.CurrentDNSServer^.IPAddress)

   Else Add('Current DNS Server: (none)');

   I := 1;

   DNS := @FI^.DNSServerList;

   Repeat

     Add('DNS '+IntToStr(I)+': '+DNS^.IPAddress);

     Inc(I);

     DNS := DNS^.Next;

   Until (DNS = nil);

   Add('Scope ID: '+FI^.ScopeId);

   Add('Routing: '+IntToStr(FI^.EnableRouting));

   Add('Proxy: '+IntToStr(FI^.EnableProxy));

   Add('DNS: '+IntToStr(FI^.EnableDNS));

 End;

 FreeMem(FI);

end;

Similarly, the GetAdaptersInfo function can be used like this:

procedure TIPMainForm.GetAdapterInformation;

Var

 AI,Work : PIPAdapterInfo;

 Size    : Integer;

 Res     : Integer;

 I       : Integer;

begin

 Size := 5120;

 GetMem(AI,Size);

 Res := GetAdaptersInfo(AI,Size);

 If (Res <> ERROR_SUCCESS) Then Begin

   SetLastError(Res);

   RaiseLastWin32Error;

 End;

 With Info,Lines do Begin

   Work := AI;

   I := 1;

   Repeat

     Add('');

     Add('Adapter '+IntToStr(I));

     Add('  ComboIndex: '+IntToStr(Work^.ComboIndex));

     Add('  Adapter name: '+Work^.AdapterName);

     Add('  Description: '+Work^.Description);

     Add('  Adapter address: '+MACToStr(@Work^.Address,Work^.AddressLength));

     Add('  Index: '+IntToStr(Work^.Index));

     Add('  Type: '+IntToStr(Work^._Type));

     Add('  DHCP: '+IntToStr(Work^.DHCPEnabled));

     Add('  Current IP: '+GetAddrString(Work^.CurrentIPAddress));

     Add('  IP addresses: '+GetAddrString(@Work^.IPAddressList));

     Add('  Gateways: '+GetAddrString(@Work^.GatewayList));

     Add('  DHCP servers: '+GetAddrString(@Work^.DHCPServer));

     Add('  Has WINS: '+IntToStr(Integer(Work^.HaveWINS)));

     Add('  Primary WINS: '+GetAddrString(@Work^.PrimaryWINSServer));

     Add('  Secondary WINS: '+GetAddrString(@Work^.SecondaryWINSServer));

     Add('  Lease obtained: '+TimeTToDateTimeStr(Work^.LeaseObtained));

     Add('  Lease expires: '+TimeTToDateTimeStr(Work^.LeaseExpires));

     Inc(I);

     Work := Work^.Next;

   Until (Work = nil);

 End;

 FreeMem(AI);

end;

Since GetAdaptersInfo is able to return complex information about the network adapters installed to the system, you need to be extra-careful when converting the information to the display. The sample application uses the following three helper functions:

Function MACToStr(ByteArr : PByte; Len : Integer) : String;

Begin

 Result := '';

 While (Len > 0) do Begin

   Result := Result+IntToHex(ByteArr^,2)+'-';

   ByteArr := Pointer(Integer(ByteArr)+SizeOf(Byte));

   Dec(Len);

 End;

 SetLength(Result,Length(Result)-1); { remove last dash }

End;

Function GetAddrString(Addr : PIPAddrString) : String;

Begin

 Result := '';

 While (Addr <> nil) do Begin

   Result := Result+'A: '+Addr^.IPAddress+' M: '+Addr^.IPMask+#13;

   Addr := Addr^.Next;

 End;

End;

Function TimeTToDateTimeStr(TimeT : Integer) : String;

Const UnixDateDelta = 25569; { days between 12/31/1899 and 1/1/1970 }

Var

 DT  : TDateTime;

 TZ  : TTimeZoneInformation;

 Res : DWord;

Begin

 If (TimeT = 0) Then Result := ''

 Else Begin

   { Unix TIME_T is secs since 1/1/1970 }

   DT := UnixDateDelta+(TimeT / (24*60*60)); { in UTC }

   { calculate bias }

   Res := GetTimeZoneInformation(TZ);

   If (Res = TIME_ZONE_ID_INVALID) Then RaiseLastWin32Error;

   If (Res = TIME_ZONE_ID_STANDARD) Then Begin

     DT := DT-((TZ.Bias+TZ.StandardBias) / (24*60));

     Result := DateTimeToStr(DT)+' '+WideCharToString(TZ.StandardName);

   End

   Else Begin { daylight saving time }

     DT := DT-((TZ.Bias+TZ.DaylightBias) / (24*60));

     Result := DateTimeToStr(DT)+' '+WideCharToString(TZ.DaylightName);

   End;

 End;

End;

The last function, TimeTToDateTimeStr, is particularly interesting because it is able to convert a Unix Time_T type to a TDateTime, and also take into account local time zone and daylight savings time (DST).

        Testing the sample application

Once you have downloaded the sample application (see below), and compiled it, you are ready to run the application. The main user interface is really quite trivial, but nonetheless the following information is displayed on screen:

Host name: emerald

Domain name: pp.htv.fi

Current DNS Server: (none)

DNS 1: 212.93.64.18

DNS 2: 212.93.64.16

Scope ID:

Routing: 0

Proxy: 0

DNS: 0

Adapter 1

 ComboIndex: 0

 Adapter name: {F2B85B21-4E6F-4EDB-AE3E-87BB6B5CAD73}

 Description: 3Com 3C90x Ethernet Adapter

 Adapter address: 00-60-08-10-28-79

 Index: 0

 Type: 6

 DHCP: 1

 Current IP:

 IP addresses: A: 212.93.92.191 M: 255.255.255.0

 Gateways: A: 212.93.92.1 M: 0.0.0.0

 DHCP servers: A: 212.93.64.98 M:

 Has WINS: 0

 Primary WINS: A: 0.0.0.0 M: 0.0.0.0

 Secondary WINS: A: 0.0.0.0 M: 0.0.0.0

 Lease obtained: 20.5.2001 14:31:49 FLE Daylight Time

 Lease expires: 20.5.2001 19:31:49 FLE Daylight Time

In case you are interested, the main screen looks like this:

Certainly, the information will be quite different on your computer, but you get the idea. For more details about the IP Helper API library, see the Platform SDK documentation, available from http://msdn.microsoft.com .

        Download the example code

Download usingtheiphelperapi.zip <http://www.whirlwater.com/downloads/2001/usingtheiphelperapi.zip> (167 kB) which contains the sample application IP Helper Demo that uses the IP Helper API available in Windows 2000. Please note that the sample application requires Delphi 5 or later and Windows 2000 or later.

img_18743.bmp (385.7KB)
usingtheiphelperapi.zip (166.4KB)