'获取网卡MAC
'注意：多网卡时，笔记本用无线与有线时，返回的网卡将发生改变。
'有的
#Include Once "win/winbase.bi"
#Include Once "win/iphlpapi.bi"
Function GetWangKaMAC() as String
   Dim IPAA as IP_ADAPTER_ADDRESSES, pAdapterAddresses as UInteger
   Dim outBufLen as UInteger, Flags as UInteger, Family as UInteger
   Dim lRet as UInteger, dwIndex as UInteger, I as UInteger
   Dim outBuff() as String
   
   Flags = &H0010' %GAA_FLAG_INCLUDE_PREFIX
   Family = AF_UNSPEC
   outBufLen = 0
   
   pAdapterAddresses = HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, 32)
   
   lRet = GetAdaptersAddresses(Family, Flags, 0, pAdapterAddresses, @outBufLen) '第一次调用,如果缓冲区不够,会在outBufLen里返回所需要的缓冲区大小
   '原示例中使用一次性分配大量空间的做法,觉得不太爽:)
   
   If lRet = ERROR_BUFFER_OVERFLOW Then '如果返回溢出,则重分配足够的内存
      pAdapterAddresses = HeapReAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, pAdapterAddresses, outBufLen)
   End If
   
   lRet = GetAdaptersAddresses(Family, Flags, 0, pAdapterAddresses, @outBufLen) '这次是正式取了
   
   If lRet = NO_ERROR Then
      I = 0
      ReDim outBuff(I)
      memcpy VarPtr(IPAA.Length), pAdapterAddresses, Len(IPAA)
      'Call CopyMemory(VarPtr(IPAA.Length), pAdapterAddresses, Len(IPAA)) '复制第一个结构
      'outBuff(I) = GetHex(IPAA.PhysicalAddress())
      
      '? GetStrFromPtr(IPAA.lpFriendlyName); IPAA.OperStatus; IPAA.IfType   这里可以获取网卡类名等
      '将字节数据以十六进制字符串输出
      'Function= Hex(IPAA.PhysicalAddress(0),2) & "-" & Hex(IPAA.PhysicalAddress(1),2) & "-" & _
      'Hex(IPAA.PhysicalAddress(2),2) & "-" & Hex(IPAA.PhysicalAddress(3),2) & "-" & _
      'Hex(IPAA.PhysicalAddress(4),2) & "-" & Hex(IPAA.PhysicalAddress(5),2)
      Function = Hex(IPAA.PhysicalAddress(0), 2) & Hex(IPAA.PhysicalAddress(1), 2) & _
         Hex(IPAA.PhysicalAddress(2), 2) & Hex(IPAA.PhysicalAddress(3), 2) & _
         Hex(IPAA.PhysicalAddress(4), 2) & Hex(IPAA.PhysicalAddress(5), 2)
      'Print "AdapterName=" & ipaa.AdapterName
      ''下面是获取多个网卡的MAC ，我们这边只要一个就好
      'Do While IPAA.Next <> 0
      'Print "IPAA.Next=" & IPAA.Next
      'I = I + 1
      'ReDim Preserve outBuff(I)
      'memcpy VarPtr(IPAA.Length), IPAA.Next, Len(IPAA)
      'Print i ,  "AdapterName=" & ipaa.AdapterName
      ''复制下一个结构,pNext中保存的是指向下一个结构的指针
      ''    outBuff(I) =IPAA.PhysicalAddress' GetHex(IPAA.PhysicalAddress())
      ''    ? GetStrFromPtr(IPAA.lpFriendlyName); IPAA.OperStatus; IPAA.IfType
      'Print Hex(IPAA.PhysicalAddress(0),2) &  Hex(IPAA.PhysicalAddress(1),2) & _
      'Hex(IPAA.PhysicalAddress(2),2) & Hex(IPAA.PhysicalAddress(3),2) & _
      'Hex(IPAA.PhysicalAddress(4),2) & Hex(IPAA.PhysicalAddress(5),2)
      'Loop
   End If
   HeapFree GetProcessHeap, 0, pAdapterAddresses
   
End Function

'Type IP_ADAPTER_ADDRESSES
'Length as Long '原型里的联合体,直接拆开
'IfIndex as Long
'pNext as Long '指向下一个IP_ADAPTER_ADDRESSES结构的指针,类似单向链表了
'AdapterName as Long 'PCHAR
'FirstUnicastAddress as Long 'IP_ADAPTER_UNICAST_ADDRESS
'FirstAnycastAddress as Long 'IP_ADAPTER_ANYCAST_ADDRESS
'FirstMulticastAddress as Long 'IP_ADAPTER_MULTICAST_ADDRESS
'FirstDnsServerAddress as Long 'IP_ADAPTER_DNS_SERVER_ADDRESS
'lpDnsSuffix as Long 'PWCHAR
'lpDescription as Long 'PWCHAR
'lpFriendlyName as Long 'PWCHAR
'PhysicalAddress(7) as Byte
'PhysicalAddressLength as Long
'Flags as Long
'MTU as Long
'IfType as  Long 
'OperStatus as  Long 
'End Type