Win NT/XP中,獲得網卡MAC地址,一般是通過netapi32.dll中的NetBIOS API發送NCBASTAT命令來獲取,但這樣做的前提是網絡連接啓用了TCP/IP協議,否則的話就不起作用,而且即使用ipconfig /all命令也看不到任何內容。
但MAC地址是固化在網卡硬件中的一個序列號,即使不安裝任何網絡協議也應該能讀取,最簡單的辦法是用Windows的wmic命令進行查詢:
- wmic nic where netconnectionid!=NULL get macaddress
很 多人比較關心如何從註冊表中獲取MAC地址,其實註冊表中的MountPoints2項中的確是保存有MAC地址,但很難從其它設備中查找出來,比較好的 辦法是先從註冊表中找到網卡的設備編號,再通過DeviceIoControl查找硬件的MAC地址,以下是Perl Win32的實現:
- #!/usr/bin/perl -w
- use strict;
- use Win32API::File qw(CreateFile DeviceIoControl :FILE_SHARE_ :Misc);
- use Win32::TieRegistry;
- #use Data::Dump qw(dump);
- sub IOCTL_NDIS_QUERY_GLOBAL_STATS () { 0x17 << 16 | 2 };
- sub OID_802_3_PERMANENT_ADDRESS () { 0x01010101 };
- sub OID_802_3_CURRENT_ADDRESS () { 0x01010102 };
- sub NDIS_Query
- {
- my ($handle, $oid) = @_;
- my $nBytes = 0;
- my $buf = "\0"x10;
- DeviceIoControl($handle,
- IOCTL_NDIS_QUERY_GLOBAL_STATS(),
- pack("L", $oid), 0,
- $buf, length($buf),
- $nBytes,
- [] );
- return join "-", unpack("(a2)*", unpack("H*", $buf) );
- }
- my $adapters = $Registry->Open("LMachine/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards", { Access => "KEY_READ", Delimiter => "/" } );
- #print dump($adapters);
- foreach(keys %$adapters)
- {
- my $adapterName = $adapters->{$_}->{ServiceName};
- print "Adapter name = $adapterName\n";
- my $hMAC = CreateFile("//./$adapterName", 0, FILE_SHARE_READ(), [], OPEN_EXISTING(), 0, []);
- for (
- [ "permanent" => OID_802_3_PERMANENT_ADDRESS() ],
- [ "current " => OID_802_3_CURRENT_ADDRESS() ],
- ) {
- my ($type, $oid) = @$_;
- my $mac = NDIS_Query($hMAC, $oid);
- print "MAC $type = $mac\n";
- }
- }