在Windows中取得多个网卡的MAC地址及多个IP地址

在网上看到有网友问如何获取系统中多个网卡的MAC地址,我之前写过一个库,其中一个作用就是读取网卡的MAC地址,当然还可以读取这个网卡的IP地址,即便是绑定了多个地址也可以读出来,不过这个类有点长。哈哈。~~

先说说用法

uses

  FlexNetUtils

.......

......

function TForm1.getMAC(const ip : string) : string;
var
  al : TFlexAdapterList;
  i,j : integer;
begin
  AL := TFlexAdapterList.Create; //建一个对像
  result := '';
  for i := 0 to al.Count - 1 do  //遍历系统中的所有网卡,包括LoopBack Adapter
    begin
      for j := 0 to al.Items[i].IP.Count - 1 do //某个网卡中有几多个IP地址
        begin
          if al.Items[i].IP.Items[j].Address = ip then
            begin
              result := al.Items[i].Mac; //取得这个网卡的MAC
              break;
            end;
        end;
      if result <> '' then break;
    end;
  al.Free;
end;

 

完整的单元代码----------------------------------------

 

unit FlexNetUtils;

interface
uses
  Classes, Windows, SysUtils, WinSock;

type
  TFlexIPAddress = class(TObject)
  Address : string;
  Mask : string;
 end;

  TFlexIPAddressList = class(TObject)
  private
    FList: TList;
    FOwnObject: Boolean;
    function GetItems(idx : integer): TFlexIPAddress;
    procedure SetItems(idx : integer; aItem: TFlexIPAddress);
  protected
    function Add: TFlexIPAddress; overload;
    function Add(aItem : TFlexIPAddress): Integer; overload;
    procedure Clear;
    procedure Delete(i : integer); overload;
    procedure Delete(aItem : TFlexIPAddress); overload;
    property OwnObject: Boolean read FOwnObject write FOwnObject;
    function Find(aItem : TFlexIPAddress): Integer;
  public
    constructor Create;
    destructor Destroy; override;
    function Count: Integer;
    property Items[idx : integer]: TFlexIPAddress read GetItems write SetItems; default;
  end;

 TFlexAdapter = class
  public
    ComboIndex : integer;
  AdapterName : string;
  Description : string;
  Mac : string;
  AdapterIndex : integer;
  AdapterType : integer;
  DHCP : boolean;
  IP : TFlexIPAddressList;
  Gateways : TFlexIPAddressList;
  DHCPServer : TFlexIPAddressList;
  HaveWINS   : Boolean;
    PrimaryWINSServer   : TFlexIPAddressList;
    SecondaryWINSServer : TFlexIPAddressList;
    constructor Create;
    destructor Destroy; override;
 end;

  TFlexAdapterList = class(TObject)
  private
    FList: TList;
    FOwnObject: Boolean;
  protected
    function GetItems(idx : integer): TFlexAdapter;
    procedure SetItems(idx : integer; aItem: TFlexAdapter);
    function Add: TFlexAdapter; overload;
    function Add(aItem : TFlexAdapter): Integer; overload;
    procedure Clear;
    procedure Delete(i : integer); overload;
    procedure Delete(aItem : TFlexAdapter); overload;
    function Find(aItem : TFlexAdapter): Integer;
    property OwnObject: Boolean read FOwnObject write FOwnObject;
    procedure GetAdapterInfo;
  public
    constructor Create;
    destructor Destroy; override;
    function Count: Integer;
    property Items[idx : integer]: TFlexAdapter read GetItems write SetItems; default;
  end;

implementation
Const
  MAX_HOSTNAME_LEN               = 128; { from IPTYPES.H }
  MAX_DOMAIN_NAME_LEN            = 128;
  MAX_SCOPE_ID_LEN               = 256;
  MAX_ADAPTER_NAME_LENGTH        = 256;
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
  MAX_ADAPTER_ADDRESS_LENGTH     = 8;

Type
  TIPAddressString = Array[0..4*4-1] of Char;

  PIPAddrString = ^TIPAddrString;
  TIPAddrString = Record
    Next      : PIPAddrString;
    IPAddress : TIPAddressString;
    IPMask    : TIPAddressString;
    Context   : Integer;
  End;

  PFixedInfo = ^TFixedInfo;
  TFixedInfo = Record { FIXED_INFO }
    HostName         : Array[0..MAX_HOSTNAME_LEN+3] of Char;
    DomainName       : Array[0..MAX_DOMAIN_NAME_LEN+3] of Char;
    CurrentDNSServer : PIPAddrString;
    DNSServerList    : TIPAddrString;
    NodeType         : Integer;
    ScopeId          : Array[0..MAX_SCOPE_ID_LEN+3] of Char;
    EnableRouting    : Integer;
    EnableProxy      : Integer;
    EnableDNS        : Integer;
  End;

  PIPAdapterInfo = ^TIPAdapterInfo;
  TIPAdapterInfo = Record { IP_ADAPTER_INFO }
    Next                : PIPAdapterInfo;
    ComboIndex          : Integer;
    AdapterName         : Array[0..MAX_ADAPTER_NAME_LENGTH+3] of Char;
    Description         : Array[0..MAX_ADAPTER_DESCRIPTION_LENGTH+3] of Char;
    AddressLength       : Integer;
    Address             : Array[1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
    Index               : Integer;
    _Type               : Integer;
    DHCPEnabled         : Integer;
    CurrentIPAddress    : PIPAddrString;
    IPAddressList       : TIPAddrString;
    GatewayList         : TIPAddrString;
    DHCPServer          : TIPAddrString;
    HaveWINS            : Bool;
    PrimaryWINSServer   : TIPAddrString;
    SecondaryWINSServer : TIPAddrString;
    LeaseObtained       : Integer;
    LeaseExpires        : Integer;
  End;

Function GetAdaptersInfo(AI : PIPAdapterInfo; Var BufLen : Integer) : Integer;
         StdCall; External 'iphlpapi.dll' Name 'GetAdaptersInfo';

{
************************** TFlexIPAddressList **************************
}
constructor TFlexIPAddressList.Create;
begin
  FList := TList.Create;
  FOwnObject := true;
end;

destructor TFlexIPAddressList.Destroy;
begin
  Clear;
  FList.Free;
  inherited;
end;

function TFlexIPAddressList.Add: TFlexIPAddress;
begin
  result := TFlexIPAddress.Create;
  FList.Add(result);
end;

function TFlexIPAddressList.Add(aItem : TFlexIPAddress): Integer;
begin
  FList.Add(aitem);
  result := FList.Count - 1;
end;

procedure TFlexIPAddressList.Clear;
var
  i: Integer;
begin
  if FOwnObject then
    for i := 0 to FList.Count - 1 do
      begin
        Items[i].Free;
      end;
  FList.Clear;
end;

function TFlexIPAddressList.Count: Integer;
begin
  result := FList.Count;
end;

procedure TFlexIPAddressList.Delete(i : integer);
begin
  if FOwnObject then Items[i].Free;
  FList.Delete(i);
end;

procedure TFlexIPAddressList.Delete(aItem : TFlexIPAddress);
var
  i: Integer;
begin
  i := Find(aItem);
  if i > -1 then FList.Delete(i);
end;

function TFlexIPAddressList.Find(aItem : TFlexIPAddress): Integer;
var
  i: Integer;
begin
  result := - 1;
  for i := 0 to FList.Count - 1 do
    begin
      if Items[i] = aItem then
        begin
          result := i;
          break;
        end;
    end;
end;

function TFlexIPAddressList.GetItems(idx : integer): TFlexIPAddress;
begin
  result := TFlexIPAddress (FList.Items[idx]);
end;

procedure TFlexIPAddressList.SetItems(idx : integer; aItem: TFlexIPAddress);
begin
  FList.Items[idx] := aItem;
end;

{
************************** TFlexAdapterList **************************
}
constructor TFlexAdapterList.Create;
begin
  FList := TList.Create;
  FOwnObject := true;
  GetAdapterInfo;
end;

destructor TFlexAdapterList.Destroy;
begin
  Clear;
  FList.Free;
  inherited;
end;

function TFlexAdapterList.Add: TFlexAdapter;
begin
  result := TFlexAdapter.Create;
  FList.Add(result);
end;

function TFlexAdapterList.Add(aItem : TFlexAdapter): Integer;
begin
  FList.Add(aitem);
  result := FList.Count - 1;
end;

procedure TFlexAdapterList.Clear;
var
  i: Integer;
begin
  if FOwnObject then
    for i := 0 to FList.Count - 1 do
      begin
        Items[i].Free;
      end;
  FList.Clear;
end;

function TFlexAdapterList.Count: Integer;
begin
  result := FList.Count;
end;

procedure TFlexAdapterList.Delete(i : integer);
begin
  if FOwnObject then Items[i].Free;
  FList.Delete(i);
end;

procedure TFlexAdapterList.Delete(aItem : TFlexAdapter);
var
  i: Integer;
begin
  i := Find(aItem);
  if i > -1 then FList.Delete(i);
end;

function TFlexAdapterList.Find(aItem : TFlexAdapter): Integer;
var
  i: Integer;
begin
  result := - 1;
  for i := 0 to FList.Count - 1 do
    begin
      if Items[i] = aItem then
        begin
          result := i;
          break;
        end;
    end;
end;

procedure TFlexAdapterList.GetAdapterInfo;
Var
  AI,Work : PIPAdapterInfo;
  Size    : Integer;
  Res     : Integer;
  adapter : TFlexAdapter;

  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;

  procedure TransAddrString(AddList : TFlexIPAddressList; Addr : PIPAddrString );
  var
    fia : TFlexIPAddress;
  begin
    While (Addr <> nil) do Begin
      fia := AddList.Add;
      fia.Address := Addr^.IPAddress;
      fia.Mask := Addr^.IPMask;
      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;

begin
  Size := 5120;
  GetMem(AI,Size);
  Res := GetAdaptersInfo(AI,Size);
  If (Res <> ERROR_SUCCESS) Then Begin
    SetLastError(Res);
    RaiseLastWin32Error;
  End;
  Work := AI;

  repeat
     adapter := self.Add;
     adapter.ComboIndex := Work^.ComboIndex;
     adapter.AdapterName := Work^.AdapterName;
     adapter.Description := Work^.Description;
     adapter.Mac := MACToStr(@Work^.Address,Work^.AddressLength);
     adapter.AdapterIndex := Work^.Index;
     adapter.AdapterType := Work^._Type;
     adapter.DHCP := (Work^.DHCPEnabled <> 0);
     adapter.HaveWINS := Work^.HaveWINS;
     TransAddrString(adapter.IP, @Work^.IPAddressList);
     TransAddrString(adapter.Gateways, @Work^.GatewayList);
     TransAddrString(adapter.DHCPServer, @Work^.DHCPServer);
     TransAddrString(adapter.PrimaryWINSServer, @Work^.PrimaryWINSServer);
     TransAddrString(adapter.SecondaryWINSServer, @Work^.SecondaryWINSServer);
     Work := Work^.Next;
  Until (Work = nil);

  FreeMem(AI);
end;

function TFlexAdapterList.GetItems(idx : integer): TFlexAdapter;
begin
  result := TFlexAdapter (FList.Items[idx]);
end;

procedure TFlexAdapterList.SetItems(idx : integer; aItem: TFlexAdapter);
begin
  FList.Items[idx] := aItem;
end;

{
**********************************************************************************************
}

{ TFlexAdapter }

constructor TFlexAdapter.Create;
begin
 IP := TFlexIPAddressList.Create;
 Gateways := TFlexIPAddressList.Create;
 DHCPServer := TFlexIPAddressList.Create;
  PrimaryWINSServer   := TFlexIPAddressList.Create;
  SecondaryWINSServer := TFlexIPAddressList.Create;
end;

destructor TFlexAdapter.Destroy;
begin
  IP.Free;
 Gateways.Free;
 DHCPServer.Free;
  PrimaryWINSServer.Free;
  SecondaryWINSServer.Free;
  inherited;
end;

end.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值