以下是我从MSDN中翻译过来的三个Delphi单元,调用任意一个单元中声明 的API都可以获取网卡的物理地址,但三个单元中的API函数的有效环境和功能各有不同,我把说明附于代码的注释中。
unit Lmwksta;
interface
uses
Windows,SysUtils,Dialogs;
type
_WKSTA_TRANSPORT_INFO_ 0 = packed record
wkti0_quality_ of _service:DWORD;
wkti0_number_ of _vcs:DWORD;
wkti0_transport_name:PWideChar; { 连接设备名称,这个名称是/DEVICE /NetBT_TcpIp……我也不知道如何理解,不过我们只想获取MAC地址就不必管它了! }
wkti0_transport_address:PWideChar; // MAC地址
wkti0_wan_ish:BOOL; // 是否是广域网连接
end ;
WKSTA_TRANSPORT_INFO_ 0 = _WKSTA_TRANSPORT_INFO_ 0 ;
PWKSTA_TRANSPORT_INFO_ 0 = ^WKSTA_TRANSPORT_INFO_ 0 ;
const
NERR_Success = 0 ;
MAX_PREFERRED_LENGTH = $FFFFFFFF;
// 当本计算机有可用的网卡,且已经连接上网络时,调用本函数才能成功,否则获取不到任何信息
function NetWkstaTransportEnum(
ServerName:PWideChar; // 主机名称,传递nil时表示本机
Level:DWORD; // 传 递0
BufPtr:PPointer; { 接受 _WKSTA_TRANSPORT_INFO_0记录数组的缓冲区,有此函数自行分配,但使用完后要用下面定义的NetApiBufferFree函数释 放内存 }
PrefMaxLen:DWORD; // 缓冲区最大长度,传递上面定义的MAX_PREFERRED_LENGTH常量即可
EntriesRead,TotalEntries,ResumeHandle:PDWORD):DWORD;stdcall;
{ EntriesRead为返回的_WKSTA_TRANSPORT_INFO_0记录数组的元素个数,至于TotalEntries和 ResumeHandle,可以传递nil,需要更深入的了解,请参见MSDN }
function NetApiBufferFree(Buffer:Pointer):DWORD;stdcall;
implementation
function NetWkstaTransportEnum;external ' netapi32.dll ' name ' NetWkstaTransportEnum ' ;
function NetApiBufferFree;external ' netapi32.dll ' name ' NetApiBufferFree ' ;
end .
unit Rpcdce;
interface
uses
Windows,SysUtils;
type
TUUID = packed record
Data1:ULONG;
Data2:Word;
Data3:Word;
Data4: array [ 0 .. 7 ] of Byte; // 此数组的后6个元素就是网卡的物理地址信息
end ;
TGUID = TUUID;
PUUID = ^TUUID;
const
{ 以下为UuidCreateSequential函数的可能返回值 }
RPC_S_UUID_LOCAL_ONLY:LongInt = 1824 ; // 函数生成的GUID只能保证在本计算机上是唯一的
RPC_S_UUID_NO_ADDRESS:LongInt = 1739 ; // 不 能获取以太网或令牌环网网卡设备
RPC_S_OK:LongInt = 0 ; // 函数调用成功,生成的GUID中包含了网卡的物理地址信息
function UuidCreateSequential( var uuid:TUUID):Cardinal;stdcall; // 此函数只使用于单网卡的机器
function GetMACAddress:string;
implementation
function UuidCreateSequential;external ' Rpcrt4.dll ' name ' UuidCreateSequential ' ;
// 引用此单元后,只需要调用GetMACAddress函数即可获得网卡物理地址
function GetMACAddress:string;
var
uuid:TUUID;
I:Integer;
begin
Result: = '' ;
if UuidCreateSequential(uuid) = RPC_S_OK then
for I: = 2 to 7 do
begin
if I > 2 then Result: = Result + ' - ' ;
Result: = Result + IntToHex(uuid.Data4[I], 2 );
end ;
end ;
end .
unit IPHlpAPI;
interface
uses
Windows,SysUtils,Classes;
const
MAX_ADAPTER_DESCRIPTION_LENGTH = 128 ;
MAX_ADAPTER_NAME_LENGTH = 256 ;
MAX_ADAPTER_ADDRESS_LENGTH = 8 ;
DEFAULT_MINIMUM_ENTITIES = 32 ;
MAX_HOSTNAME_LEN = 128 ;
MAX_DOMAIN_NAME_LEN = 128 ;
MAX_SCOPE_ID_LEN = 256 ;
ERROR_NO_DATA:LongInt = 232 ;
ERROR_NOT_SUPPORTED:LongInt = 50 ;
ERROR_INVALID_PARAMETER:LongInt = 87 ;
ERROR_BUFFER_OVERFLOW:LongInt = 111 ;
type
time_t = Integer;
IP_ADDRESS_STRING = packed record
Addr: array [ 0 .. 15 ] of Char;
end ;
PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
IP_MASK_STRING = IP_ADDRESS_STRING;
PIP_MASK_STRING = ^IP_MASK_STRING;
PIPAdapterInfo = ^TIPAdapterInfo;
TIPAdapterInfo = packed record
Next:PIPAdapterInfo; // 下一个节点的指针
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域的最大长度,传递 MAX_ADAPTER_ADDRESS_LENGTH常量即可
Address: array [ 0 ..MAX_ADAPTER_ADDRESS_LENGTH - 1 ] of Byte; // 适配器物理地址
Index:DWORD;
uType:UINT;
DhcpEnabled:UINT;
CurrentIpAddress:PIP_ADDRESS_STRING;
IpAddressList:IP_ADDRESS_STRING;
GatewayList:IP_ADDRESS_STRING;
DhcpServer:IP_ADDRESS_STRING;
HaveWins:BOOL;
PrimaryWinsServer:IP_ADDRESS_STRING;
SecondaryWinsServer:IP_ADDRESS_STRING;
LeaseObtained:time_t;
LeaseExpires:time_t;
end ;
// 此函数功能最强大,而且只要求网卡在系统 中可用,并不要求一定连接上网络
function GetAdaptersInfo(Buf:PIPAdapterInfo; var BufLen:ULONG):DWORD;stdcall;
implementation
function GetAdaptersInfo;external ' iphlpapi.dll ' name ' GetAdaptersInfo ' ;
end .
对于GetAdaptersInfo函数,Buf参数要求函数的调用者自行分配,如果分配的空间不足,函数返回 ERROR_BUFFER_OVERFLOW,BufLen变参的值被设置为实际需要的缓冲区大小,因此可以再行分配,以满足需
求,采用 链表遍历操作可以获取所有已安装网卡的物理地址。
Delphi代码获取网卡物理地址三种方法
最新推荐文章于 2022-09-06 07:43:57 发布