unit cl_machine_id;

interface

  function GetMachineID(SupposedID: AnsiString): AnsiString;

implementation
  uses SysUtils, md5 {$ifdef unix} , un_process {$else} , Windows {$endif} ;


const
  HexChars: set of AnsiChar = ['0'..'9', 'A'..'F'];

  function IsValidMACAddr(a: ansistring): boolean;
  var i, m: integer;
  begin
    if length(a) <> 17 then Exit(false);
    for i:= 1 to 5 do
      if a[i * 3] <> ':' then Exit(false);
    for i:=0 to 5 do
      for m:=1 to 2 do
        if not a[i * 3 + m] in HexChars then Exit(false);
    Result:= true;
  end;

  {$ifdef unix}
{
cheb@linux-45wx:~> /sbin/ifconfig | grep HWaddr
eth0      Link encap:Ethernet  HWaddr 00:24:8C:62:9F:31
eth1      Link encap:Ethernet  HWaddr 00:50:22:94:CB:EA
eth2      Link encap:Ethernet  HWaddr 00:E0:50:C3:00:95}

    function GetMachineID(SupposedID: AnsiString): AnsiString;
    var
      L: TLoggedProcess;
      i, k: integer;
      s: AnsiString;
    begin
      Result:= '00:00:00:00:00:00';
      SupposedId:= UpperCase(SupposedId);
      if not IsValidMacAddr(SupposedID) then SupposedId:= Result;
      L:= TLoggedProcess.Create('/sbin/ifconfig | grep HWaddr');
      for i:= 0 to L.log.Count - 1 do begin
        k:= Pos('HWaddr', L.log[k]);
        if k = 0 then continue;
        s:= Trim(UpperCase(Copy(L.log[k], k + 7, length(L.log[k] - (k + 7 - 1)))));
        if not IsValidMacAddr(s) then continue;
        Result:= s;
        if s = SupposedID then break;
      end;
    end;

  {$else}
    const
      MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
      MAX_ADAPTER_NAME_LENGTH        = 256; // arb.
      MAX_ADAPTER_ADDRESS_LENGTH     = 8; // arb.

    type
      PIP_ADDR_STRING = ^IP_ADDR_STRING;
      _IP_ADDR_STRING = record
        Next: PIP_ADDR_STRING;
        IpAddress: IP_ADDRESS_STRING;
        IpMask: IP_MASK_STRING;
        Context: DWORD;
      end;
      IP_ADDR_STRING = _IP_ADDR_STRING;
      TIpAddrString = IP_ADDR_STRING;
      PIpAddrString = PIP_ADDR_STRING;
      PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
      _IP_ADAPTER_INFO = record
        Next: PIP_ADAPTER_INFO;
        ComboIndex: DWORD;
        AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;
        Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;
        AddressLength: UINT;
        Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
        Index: DWORD;
        Type_: UINT;
        DhcpEnabled: UINT;
        CurrentIpAddress: PIP_ADDR_STRING;
        IpAddressList: IP_ADDR_STRING;
        GatewayList: IP_ADDR_STRING;
        DhcpServer: IP_ADDR_STRING;
        HaveWins: BOOL;
        PrimaryWinsServer: IP_ADDR_STRING;
        SecondaryWinsServer: IP_ADDR_STRING;
        LeaseObtained: time_t;
        LeaseExpires: time_t;
      end;
      IP_ADAPTER_INFO = _IP_ADAPTER_INFO;

    var
      GetAdaptersInfo: function(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall;

    function GetMachineID(SupposedID: AnsiString): AnsiString;
    var
      i, k: integer;
      L: THandle;
      Ai: array[0..50] of IP_ADAPTER_INFO;
      bz: ULONG;
    begin
      Result:= '00:00:00:00:00:00';
      SupposedId:= UpperCase(SupposedId);
      if not IsValidMacAddr(SupposedID) then SupposedId:= Result;

      try
        L:= LoadLibrary('iphlpapi.dll');
        if L <> 0 then begin
          GetAdaptersInfo:= GetProcAddress(L, PChar('GetAdaptersInfo'));
          if Assigned(@GetAdaptersInfo) then begin
            bz:= sizeof(Ai);
            if NO_ERROR = GetAdaptersInfo(@Ai[0], bz) then begin






            end;
          end;
          FreeLibrary(L);
        end;
      except
      end;
    end;
  {$endif}
end.

