找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 5845|回复: 2

【分享】马大哈系列功能模块----取本机所有网卡MAC地址(VB6代码)

[复制链接]

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2011-1-5 18:41:21 | 显示全部楼层 |阅读模式
下午在群里有人问到这个问题,说是网上流传的那个代码(类似这个:  取本机网卡MAC地址)无法在多网卡情况下正常工作.

于是试了一下,果然如此.而系统的ipconfig.exe却能正确取得每个网卡(网络连接)的物理地址.

马上查看了一下ipconfig.exe都调用了些什么API,发现了一个GetAdaptersAddresses(仅支持XP及以上)函数....

然后在网上一翻,居然没有VB6调用的例子,只有一个MSDN里C语言的示例,汗

没办法,翻译吧....

原MSDN内容如下:

http://msdn.microsoft.com/en-us/library/aa365915(VS.85).aspx

折腾了一会儿,封装得比较简单,调用只需要:
  1. msgbox GetPhysicalAddress()(0)      '第一个网卡的MAC地址函数会把所有网络连接的MAC地址放到数组里返回.
复制代码
以后就方便了

不过要注意的是,这个API只支持XP及以上系统.所以2000啥的就免了吧

在XP以下肯定也有办法,不过现在就不搞了 ,毕竟现在少有人还用2000吧.....

具体代码如下:
  1. Option Explicit
  2. '*************************************************************************
  3. '**模 块 名:ModGetPhysicalAddress
  4. '**说    明:取得本机所有网卡的MAC地址
  5. '**创 建 人:嗷嗷叫的老马
  6. '**日    期:2010年09月28日
  7. '**备    注: 紫水晶工作室 版权所有
  8. '**          更多模块/类模块请访问我站:  http://www.m5home.com
  9. '**版    本:V1.0
  10. '*************************************************************************

  11. Private Const HEAP_ZERO_MEMORY  As Long = &H8&
  12. Private Const ERROR_BUFFER_OVERFLOW As Long = &H6F&
  13. Private Const GAA_FLAG_INCLUDE_PREFIX As Long = &H10&
  14. Private Const MAX_ADAPTER_ADDRESS_LENGTH As Long = &H8&
  15. Private Const MAX_ADAPTER_NAME_LENGTH As Long = &H100&
  16. Private Const AF_UNSPEC As Long = &H0&
  17. Private Const NO_ERROR As Long = &H0&

  18. Private Enum IF_TYPE
  19.     IF_TYPE_OTHER = 1
  20.     IF_TYPE_ETHERNET_CSMACD = 6
  21.     IF_TYPE_ISO88025_TOKENRING = 9
  22.     IF_TYPE_PPP = 23
  23.     IF_TYPE_SOFTWARE_LOOPBACK = 24
  24.     IF_TYPE_ATM = 37
  25.     IF_TYPE_IEEE80211 = 71
  26.     IF_TYPE_TUNNEL = 131
  27.     IF_TYPE_IEEE1394 = 144
  28. End Enum

  29. Private Enum IF_OPER_STATUS
  30.     IfOperStatusUp = 1
  31.     IfOperStatusDown = 2
  32.     IfOperStatusTesting = 3
  33.     IfOperStatusUnknown = 4
  34.     IfOperStatusDormant = 5
  35.     IfOperStatusNotPresent = 6
  36.     IfOperStatusLowerLayerDown = 7
  37. End Enum

  38. Private Type IP_ADAPTER_ADDRESSES
  39.     Length As Long                      '原型里的联合体,直接拆开
  40.     IfIndex As Long
  41.     pNext As Long                       '指向下一个IP_ADAPTER_ADDRESSES结构的指针,类似单向链表了
  42.     AdapterName As Long                 'PCHAR
  43.     FirstUnicastAddress As Long         'IP_ADAPTER_UNICAST_ADDRESS
  44.     FirstAnycastAddress As Long         'IP_ADAPTER_ANYCAST_ADDRESS
  45.     FirstMulticastAddress As Long       'IP_ADAPTER_MULTICAST_ADDRESS
  46.     FirstDnsServerAddress As Long       'IP_ADAPTER_DNS_SERVER_ADDRESS
  47.     lpDnsSuffix As Long                 'PWCHAR
  48.     lpDescription As Long               'PWCHAR
  49.     lpFriendlyName As Long              'PWCHAR
  50.     PhysicalAddress(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
  51.     PhysicalAddressLength As Long
  52.     Flags As Long
  53.     MTU As Long
  54.     IfType As IF_TYPE
  55.     OperStatus As IF_OPER_STATUS
  56. End Type

  57. Private Declare Function GetAdaptersAddresses Lib "iphlpapi" ( _
  58.         ByVal Family As Long, _
  59.         ByVal Flags As Long, _
  60.         ByVal Reserved As Long, _
  61.         ByVal AdapterAddresses As Long, _
  62.         ByRef SizePointer As Long) As Long

  63. Private Declare Function GetProcessHeap Lib "Kernel32" ( _
  64.         ) As Long
  65.    
  66. Private Declare Function HeapAlloc Lib "Kernel32" ( _
  67.         ByVal hHeap As Long, _
  68.         ByVal dwFlags As Long, _
  69.         ByVal dwBytes As Long) As Long

  70. Private Declare Function HeapReAlloc Lib "Kernel32" ( _
  71.         ByVal hHeap As Long, _
  72.         ByVal dwFlags As Long, _
  73.         ByVal lpMem As Long, _
  74.         ByVal dwBytes As Long) As Long

  75. Private Declare Function HeapFree Lib "Kernel32" ( _
  76.         ByVal hHeap As Long, _
  77.         ByVal dwFlags As Long, _
  78.         ByVal lpMem As Long) As Long
  79.    
  80. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" ( _
  81.      ByVal Destination As Long, _
  82.      ByVal Source As Long, _
  83.      ByVal Length As Long)

  84. Private Declare Function lstrlenW Lib "Kernel32" ( _
  85.                         ByVal ptr As Long) As Long

  86. Private Function GetStrFromPtr(ByVal ptr As Long) As String
  87.     '从指针得到字符串
  88.     Dim Buffer() As Byte
  89.     Dim lpSize As Long
  90.    
  91.     lpSize = lstrlenW(ptr) * 2
  92.     If lpSize <> 0 Then
  93.         ReDim Buffer(lpSize)
  94.         CopyMemory VarPtr(Buffer(0)), ptr, lpSize
  95.         GetStrFromPtr = Buffer
  96.     End If
  97. End Function

  98. Private Function GetHex(ByRef inByte() As Byte) As String
  99.     '将字节数据以十六进制字符串输出
  100.     Dim I As Long, J() As String, K As Long
  101.    
  102.     ReDim J(UBound(inByte))
  103.    
  104.     For I = 0 To UBound(J)
  105.         J(I) = "00"
  106.         RSet J(I) = CStr(Hex(inByte(I)))
  107.     Next
  108.    
  109.     GetHex = Replace(Join(J(), "-"), " ", "0")
  110. End Function

  111. Public Function GetPhysicalAddress() As String()
  112.     '取网卡MAC地址
  113.     '
  114.     '无输入参数.
  115.     '返回值:
  116.     '       字符串数组,包含本机所有网络连接的MAC地址.
  117.     '备注:
  118.     '       每个网络连接并不一定对应一个物理网卡,但仍然可以拥有MAC地址
  119.     Dim IPAA As IP_ADAPTER_ADDRESSES, pAdapterAddresses As Long
  120.     Dim outBufLen As Long, Flags As Long, Family As Long
  121.     Dim lRet As Long, dwIndex As Long, I As Long
  122.     Dim outBuff() As String
  123.    
  124.     Flags = GAA_FLAG_INCLUDE_PREFIX
  125.     Family = AF_UNSPEC
  126.     outBufLen = 0
  127.    
  128.     pAdapterAddresses = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, 32)
  129.    
  130.     lRet = GetAdaptersAddresses(Family, Flags, 0, pAdapterAddresses, outBufLen)       '第一次调用,如果缓冲区不够,会在outBufLen里返回所需要的缓冲区大小
  131.                         '原示例中使用一次性分配大量空间的做法,觉得不太爽:)
  132.                         
  133.     If lRet = ERROR_BUFFER_OVERFLOW Then      '如果返回溢出,则重分配足够的内存
  134.         pAdapterAddresses = HeapReAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, pAdapterAddresses, outBufLen)
  135.     End If
  136.    
  137.     lRet = GetAdaptersAddresses(Family, Flags, 0, pAdapterAddresses, outBufLen)     '这次是正式取了
  138.    
  139.     If lRet = NO_ERROR Then
  140.         I = 0
  141.         ReDim outBuff(I)
  142.         
  143.         Call CopyMemory(VarPtr(IPAA.Length), pAdapterAddresses, LenB(IPAA))         '复制第一个结构
  144.         outBuff(I) = GetHex(IPAA.PhysicalAddress())
  145.         
  146.         Debug.Print GetStrFromPtr(IPAA.lpFriendlyName); IPAA.OperStatus; IPAA.IfType
  147.         Debug.Print outBuff(I)
  148.         Debug.Print
  149.         
  150.         Do While IPAA.pNext <> 0
  151.             I = I + 1
  152.             ReDim Preserve outBuff(I)
  153.             
  154.             Call CopyMemory(VarPtr(IPAA.Length), ByVal IPAA.pNext, Len(IPAA))       '复制下一个结构,pNext中保存的是指向下一个结构的指针
  155.             outBuff(I) = GetHex(IPAA.PhysicalAddress())
  156.             
  157.             Debug.Print GetStrFromPtr(IPAA.lpFriendlyName); IPAA.OperStatus; IPAA.IfType
  158.             Debug.Print outBuff(I)
  159.             Debug.Print
  160.         Loop
  161.     End If
  162.     HeapFree GetProcessHeap, 0, pAdapterAddresses
  163.     GetPhysicalAddress = outBuff
  164. End Function
复制代码
为了方便,打个包上传吧:

http://www.m5home.com/blog/article.asp?id=510
我就是嗷嗷叫的老马了......

0

主题

7

回帖

0

精华

初来乍到

积分
4
发表于 2011-3-17 22:19:30 | 显示全部楼层
好东东。。。顶。。不顶都不行。。

30

主题

693

回帖

0

精华

钻石会员

积分
2815
发表于 2015-9-6 10:18:05 | 显示全部楼层
谢谢马总 支持一下
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表