做项目有些授权需要网卡硬件信息进行检测,网上可以搜到很多解决方案(copy很多,我也copy一份)。
主要有两种:
1、使用WinSock单元
2、引用Iphlpapi.dll动态库的模式
很多方案都是Char 默认是 AnsiChar的(delphi7)代码,需要修改定义。
测试环境:
1、delphi 2010
2、win7 sp1 x64 (VBox 虚拟机)
3、网卡:桥接 x 2,NAT x 1, 内部地址 x 1 共设置了4个网卡
重点函数
iphlpapi.dll 是windows下一个IP的帮助API功能强大,具体可以到MSDN查看。用C的可以直接引用 IPTYPES.H 单元头,delphi的只能自己定义。
如果出现加载失败等问题,可以查一下DLL是否正常。
function GetAdaptersInfo(AI: PIPAdapterInfo; var BufLen: Integer): Integer;
stdcall; external 'iphlpapi.dll' Name 'GetAdaptersInfo';
function SendArp(ipaddr: ulong; temp: dword; ulmacaddr: pointer; ulmacaddrleng: pointer): dword;
stdcall; external 'Iphlpapi.dll' Name 'SendARP';
获取MAC的代码
unit uNetFuncs;
interface
uses
classes, Windows;
function GetAdapterInformation(AStrs: TStrings): Integer;
function GetAdapterInformation2: string;
function GetLocalMac(var AID: string): integer;
implementation
uses
SysUtils,
WinSock; // inet_addr
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 GetAdaptersInfo(AI: PIPAdapterInfo; var BufLen: Integer): Integer;
stdcall; external 'iphlpapi.dll' Name 'GetAdaptersInfo';
function SendArp(ipaddr: ulong; temp: dword; ulmacaddr: pointer; ulmacaddrleng: pointer): dword;
stdcall; external 'Iphlpapi.dll' Name 'SendARP';
function GetAdapterInformation(AStrs: TStrings): Integer;
var
pAI, pWork: PIPAdapterInfo;
Size: Integer;
iIdx: 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) - 1); { remove last dash }
end;
function GetAddrString(Addr: PIPAddrString): string;
begin
Result := '';
while (Addr <> nil) do begin
Result := Result + 'A: ' + String(Addr^.IPAddress )+ ' M: ' + String(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
Result := '';
if TimeT = 0 then
Exit;
{ 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 RaiseLastOSError;
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;
begin
Size := 5120;
GetMem(pAI, Size);
try
if (GetAdaptersInfo(pAI, Size) <> ERROR_SUCCESS) then
RaiseLastOSError;
pWork := pAI;
iIdx := 1;
repeat
AStrs.Add('');
AStrs.Add('Adapter ' + IntToStr(iIdx));
AStrs.Add(' ComboIndex: ' + IntToStr(pWork^.ComboIndex));
AStrs.Add(' Adapter name: ' + pWork^.AdapterName);
AStrs.Add(' Description: ' + pWork^.Description);
AStrs.Add(' Adapter address: ' + MACToStr(@pWork^.Address, pWork^.AddressLength));
AStrs.Add(' Index: ' + IntToStr(pWork^.Index));
AStrs.Add(' Type: ' + IntToStr(pWork^._Type));
AStrs.Add(' DHCP: ' + IntToStr(pWork^.DHCPEnabled));
AStrs.Add(' Current IP: ' + GetAddrString(pWork^.CurrentIPAddress));
AStrs.Add(' IP addresses: ' + GetAddrString(@pWork^.IPAddressList));
AStrs.Add(' Gateways: ' + GetAddrString(@pWork^.GatewayList));
AStrs.Add(' DHCP servers: ' + GetAddrString(@pWork^.DHCPServer));
AStrs.Add(' Has WINS: ' + IntToStr(Integer(pWork^.HaveWINS)));
AStrs.Add(' Primary WINS: ' + GetAddrString(@pWork^.PrimaryWINSServer));
AStrs.Add(' Secondary WINS: ' + GetAddrString(@pWork^.SecondaryWINSServer));
AStrs.Add(' Lease obtained: ' + TimeTToDateTimeStr(pWork^.LeaseObtained));
AStrs.Add(' Lease expires: ' + TimeTToDateTimeStr(pWork^.LeaseExpires));
Inc(iIdx);
pWork := pWork^.Next;
until (pWork = nil);
finally
FreeMem(pAI);
end;
Result := iIdx - 1;
end;
function GetAdapterInformation2: string;
var
pAI, pWork: PIPAdapterInfo;
iSize: Integer;
Res: 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) - 1); { remove last dash }
end;
begin
iSize := 5120;
GetMem(pAI, iSize);
try
Res := GetAdaptersInfo(pAI, iSize);
if (Res <> ERROR_SUCCESS) then
RaiseLastOSError;
pWork := pAI;
Result := pWork^.Description + ' ' + MACToStr(@pWork^.Address, pWork^.AddressLength);
finally
FreeMem(pAI);
end;
end;
function GetLocalMac(var AID: string): integer;
var
iLocalIP: ulong;
rLocalMAC: array[0..5] of Byte;
iLen: ulong;
begin
iLocalIP := inet_addr(PAnsiChar('localhost'));
iLen := Length(rLocalMAC);
Result := SendArp(iLocalIP, 0, @rLocalMAC, @iLen);
AID := format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x', [
rLocalMAC[0], rLocalMAC[1], rLocalMAC[2],
rLocalMAC[3], rLocalMAC[4], rLocalMAC[5]]);
end;
end.