unit uGetMacAddr;

interface 
  uses
    Windows,SysUtils, Classes;

function GetMacAddress: TStringList;

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 AnsiChar;

 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 AnsiChar;
   DomainName       : Array[0..MAX_DOMAIN_NAME_LEN+3] of AnsiChar;
   CurrentDNSServer : PIPAddrString; 
   DNSServerList    : TIPAddrString; 
   NodeType         : Integer; 
   ScopeId          : Array[0..MAX_SCOPE_ID_LEN+3] of AnsiChar;
   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 AnsiChar;
   Description         : Array[0..MAX_ADAPTER_DESCRIPTION_LENGTH+3] of AnsiChar;
   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 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';

function GetMacAddress: TStringList;
Var
 AI,Work : PIPAdapterInfo;
 Size    : Integer; 
 Res     : Integer; 
// I       : Integer;

 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));
 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; 

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

   Work := AI;
   //I := 1;
   Result := TStringList.Create;
   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));
     Result.Add(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);

   //Result:= Copy(Result, 1, 12);
 FreeMem(AI); 
end;

end.
