Delphi代码获取网卡物理地址三种方法
2010-05-03 00:06
906 查看
以下是我从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变参的值被设置为实际需要的缓冲区大小,因此可以再行分配,以满足需
求,采用
链表遍历操作可以获取所有已安装网卡的物理地址。
的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代码获取网卡物理地址
- JS获取客户端网卡物理地址(MAC) 代码
- delphi技术专题---获取网卡物理地址之NB30.pas单元TNCB详解以及源代码分享
- delphi技术专题---获取网卡物理地址之TLanaENum结构步骤学习分享
- delphi技术专题---获取网卡物理地址之内存获取方式函数源码
- delphi技术专题---获取网卡物理地址之NetBios网络编程接口LANA介绍
- DOS命令下的三种获取远程主机MAC地址的方法
- Linux下C语言获取所有网卡MAC地址的代码
- 多种方法修改网卡MAC物理地址(转载)
- 多种方法“通透”网卡物理地址
- 取得系统中网卡MAC地址的三种方法
- PHP获取网卡MAC地址的方法
- 在html界面获取地址栏内传过来的值的三种方法
- 获取网卡的MAC地址原码;目前支持WIN/LINUX系统 获取机器网卡的物理(MAC)地址
- Java/JSP获得客户端网卡MAC地址的三种方法解析
- 在JAVA中如何获取本机的网卡物理地址
- 获取机器网卡的物理(MAC)地址
- 【功能代码】---4用JS获取地址栏参数方法
- 那有什么办法可以获取网卡的真实的物理地址呢?