[FUNC][DLLCALL]获取网卡信息

一台机器上可能不只有一个网卡,但每一个网卡只有一个MAC地址,而每一个网卡可能配置有多个IP地址;如平常的笔记本电脑中,就会有无线网卡和有线网卡(网线接口)两种;因此,如果要获得本机所有网卡的IP和MAC地址信息,则必须顺序获得每个网卡,再依次获取其信息等;在windows sdk中,用IP_ADAPTER_INFO结构体存储网卡信息,包括网卡名、网卡描述、网卡MAC地址、网卡IP等,该结构体的主要描述如下所示:

 

typedef struct _IP_ADAPTER_INFO {
  struct _IP_ADAPTER_INFO* Next;//指向链表中下一个适配器信息的指针
  DWORD ComboIndex;//预留值
  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];//使用ANSI字符串表示的适配器名称
  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];//使用ANSI字符串表示的适配器描述
  UINT AddressLength;//适配器硬件地址以字节计算的长度
  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];//硬件地址以BYTE数组所表示
  DWORD Index;//适配器索引
    UINT Type;//适配器类型,主要有以下几种:
    /*
     *   MIB_IF_TYPE_OTHER     1
     *   MIB_IF_TYPE_ETHERNET     6
     *   MIB_IF_TYPE_TOKENRING     9
     *   MIB_IF_TYPE_FDDI     15
     *   MIB_IF_TYPE_PPP     23
     *   MIB_IF_TYPE_LOOPBACK      24
     *   MIB_IF_TYPE_SLIP      28
     */
  UINT DhcpEnabled;//指定这个适配器是否开启DHCP
  PIP_ADDR_STRING CurrentIpAddress;//预留值
  IP_ADDR_STRING IpAddressList;//该适配器的IPv4地址链表
  IP_ADDR_STRING GatewayList;//该适配器的网关IPv4地址链表
  IP_ADDR_STRING DhcpServer;//该适配器的DHCP服务器的IPv4 地址链表
  BOOL HaveWins;
  IP_ADDR_STRING PrimaryWinsServer;
  IP_ADDR_STRING SecondaryWinsServer;
  time_t LeaseObtained;
  time_t LeaseExpires;
  } IP_ADAPTER_INFO,*PIP_ADAPTER_INFO;

 

由于可能有多个网卡,因此struct _IP_ADAPTER_INFO* Next字段为一个链表结构指针,由于一个网卡可能有多个IP,因此IP_ADDR_STRING字段应该也是一个链表结构,其信息如下所示:

 

typedef struct _IP_ADDR_STRING
{
    struct _IP_ADDR_STRING* Next;  //指向同类型节点,即下一个IP(如果有多IP的话)
    IP_ADDRESS_STRING IpAddress;  //IP地址信息
    IP_MASK_STRING IpMask; //IP子网掩码
    DWORD Context;// 网络表入口。这个值对应着AddIPAddredd和DeleteIPAddress函数中的NTEContext参数
} IP_ADDR_STRING;

 

在基本了解以上信息后,就可以调用GetAdaptersInfo函数来获取相关网卡信息了,其通用的代码如下所示:

ahk 兼容A32 U32 U64

;转自 https://www.autohotkey.com/boards/viewtopic.php?f=9&t=18768&p=91413&hilit=GetAdaptersInfo#p91413

OutPut := GetAdaptersInfo()
PrintArr(OutPut)

GetAdaptersInfo()
{
    ; initial call to GetAdaptersInfo to get the necessary size
    if (DllCall("iphlpapi.dll\GetAdaptersInfo", "ptr", 0, "UIntP", size) = 111) ; ERROR_BUFFER_OVERFLOW
        if !(VarSetCapacity(buf, size, 0))  ; size ==>  1x = 704  |  2x = 1408  |  3x = 2112
            return "Memory allocation failed for IP_ADAPTER_INFO struct"

    ; second call to GetAdapters Addresses to get the actual data we want
    if (DllCall("iphlpapi.dll\GetAdaptersInfo", "ptr", &buf, "UIntP", size) != 0) ; NO_ERROR / ERROR_SUCCESS
        return "Call to GetAdaptersInfo failed with error: " A_LastError

    ; get some information from the data we received
    addr := &buf, IP_ADAPTER_INFO := {}
    while (addr)
    {
        IP_ADAPTER_INFO[A_Index, "ComboIndex"]          := NumGet(addr+0, o := A_PtrSize, "UInt")   , o += 4
        IP_ADAPTER_INFO[A_Index, "AdapterName"]         := StrGet(addr+0 + o, 260, "CP0")           , o += 260
        IP_ADAPTER_INFO[A_Index, "Description"]         := StrGet(addr+0 + o, 132, "CP0")           , o += 132
        IP_ADAPTER_INFO[A_Index, "AddressLength"]       := NumGet(addr+0, o, "UInt")                , o += 4
        loop % IP_ADAPTER_INFO[A_Index].AddressLength
            mac .= Format("{:02X}",                        NumGet(addr+0, o + A_Index - 1, "UChar")) "-"
        IP_ADAPTER_INFO[A_Index, "Address"]             := SubStr(mac, 1, -1), mac := ""            , o += 8
        IP_ADAPTER_INFO[A_Index, "Index"]               := NumGet(addr+0, o, "UInt")                , o += 4
        IP_ADAPTER_INFO[A_Index, "Type"]                := NumGet(addr+0, o, "UInt")                , o += 4
        IP_ADAPTER_INFO[A_Index, "DhcpEnabled"]         := NumGet(addr+0, o, "UInt")                , o += A_PtrSize
                                                    Ptr := NumGet(addr+0, o, "UPtr")                , o += A_PtrSize
        IP_ADAPTER_INFO[A_Index, "CurrentIpAddress"]    := Ptr ? StrGet(Ptr + A_PtrSize, "CP0") : ""
        IP_ADAPTER_INFO[A_Index, "IpAddressList"]       := StrGet(addr + o + A_PtrSize, "CP0")
        ;~ IP_ADAPTER_INFO[A_Index, "IpMaskList"]          := StrGet(addr + o + A_PtrSize + 16, "CP0") , o += A_PtrSize + 32 + A_PtrSize
        IP_ADAPTER_INFO[A_Index, "IpMaskList"]          := StrGet(addr + o + A_PtrSize * 3, "CP0") , o += A_PtrSize + 32 + A_PtrSize
		
        IP_ADAPTER_INFO[A_Index, "GatewayList"]         := StrGet(addr + o + A_PtrSize, "CP0")      , o += A_PtrSize + 32 + A_PtrSize
        IP_ADAPTER_INFO[A_Index, "DhcpServer"]          := StrGet(addr + o + A_PtrSize, "CP0")      , o += A_PtrSize + 32 + A_PtrSize
        IP_ADAPTER_INFO[A_Index, "HaveWins"]            := NumGet(addr+0, o, "Int")                 , o += A_PtrSize
        IP_ADAPTER_INFO[A_Index, "PrimaryWinsServer"]   := StrGet(addr + o + A_PtrSize, "CP0")      , o += A_PtrSize + 32 + A_PtrSize
        IP_ADAPTER_INFO[A_Index, "SecondaryWinsServer"] := StrGet(addr + o + A_PtrSize, "CP0")      , o += A_PtrSize + 32 + A_PtrSize
        IP_ADAPTER_INFO[A_Index, "LeaseObtained"]       := DateAdd(NumGet(addr+0, o, "Int"))        , o += A_PtrSize
        IP_ADAPTER_INFO[A_Index, "LeaseExpires"]        := DateAdd(NumGet(addr+0, o, "Int"))
        addr := NumGet(addr+0, "UPtr")
    }

    ; output the data we received and free the buffer
    return IP_ADAPTER_INFO, VarSetCapacity(buf, 0), VarSetCapacity(addr, 0)
}

DateAdd(time)
{
    if (time = 0)
        return 0
    datetime := 19700101
    datetime += time, s
    FormatTime, OutputVar, datetime, yyyy-MM-dd HH:mm:ss
    return OutputVar
}


PrintArr(Arr, Option := "w800 h200", GuiNum := 90)
{
    for index, obj in Arr {
        if (A_Index = 1) {
            for k, v in obj {
                Columns .= k "|"    
                cnt++
            }
            Gui, %GuiNum%: Margin, 5, 5
            Gui, %GuiNum%: Add, ListView, %Option%, % Columns
        }
        RowNum := A_Index        
        Gui, %GuiNum%: default
        LV_Add("")
        for k, v in obj {
            LV_GetText(Header, 0, A_Index)
            if (k <> Header) {    
                FoundHeader := False
                loop % LV_GetCount("Column") {
                    LV_GetText(Header, 0, A_Index)
                    if (k <> Header)
                        continue
                    else {
                        FoundHeader := A_Index
                        break
                    }
                }
                if !(FoundHeader) {
                    LV_InsertCol(cnt + 1, "", k)
                    cnt++
                    ColNum := "Col" cnt
                } else
                    ColNum := "Col" FoundHeader
            } else
                ColNum := "Col" A_Index
            LV_Modify(RowNum, ColNum, (IsObject(v) ? "Object()" : v))
        }
    }
    loop % LV_GetCount("Column")
        LV_ModifyCol(A_Index, "AutoHdr")
    Gui, %GuiNum%: Show,, Array
}

au3


#include <ButtonConstants.au3> 
#include <GUIConstantsEx.au3> 
#include <ListViewConstants.au3> 
#include <WindowsConstants.au3> 
#include <GuiListView.au3> 
#region ### START Koda GUI section ### Form= 
$Form1 = GUICreate("Form1", 634, 246) 
$ListView1 = GUICtrlCreateListView("网卡名称|MAC地址|IP地址|链路速度", 8, 40, 618, 198) 
_GUICtrlListView_SetColumnWidth($ListView1, 0, 290) 
$Button1 = GUICtrlCreateButton("Exit", 552, 8, 75, 25) 
GUISetState(@SW_SHOW) 
#endregion ### END Koda GUI section ### 
SetListView() 
While 1 
$nMsg = GUIGetMsg() 
Switch $nMsg 
Case $GUI_EVENT_CLOSE, $Button1 
Exit 

EndSwitch 
WEnd 

Func SetListView() 
$a = _GetAdaptersInfo() 
$index = ($a[1][3]) 
For $i = 1 To $a[0][0] 
GUICtrlCreateListViewItem($a[$i][1] & '|' & _ 
StringLeft(Hex($a[$i][2]), 12) & '|' & _ 
$a[$i][6] & '|' & _ 
GetIfEntry($a[$i][3]) & ' MB', $ListView1) 
Next 
EndFunc ;==>SetListView 

Func GetIfEntry($ifIndex) 
Local $tagBuffer, $tBuffer, $pBuffer, $iResult, $iSpeed, $sDescr 

$tagBuffer = "wchar[256];dword[5];byte[8];dword[16];char[256]" 
$tBuffer = DllStructCreate($tagBuffer) 
$pBuffer = DllStructGetPtr($tBuffer) 
DllStructSetData($tBuffer, 2, $ifIndex, 1) 

$iResult = DllCall("iphlpapi.dll", "long", "GetIfEntry", "ptr", $pBuffer) 
$iSpeed = DllStructGetData($tBuffer, 2, 4) / 1000 / 1000 
$sDescr = DllStructGetData($tBuffer, 5) 
$tBuffer = 0 
Return SetError($iResult[0], $iSpeed, $iSpeed) 
EndFunc ;==>GetIfEntry 


Func _GetAdaptersInfo() 
Local $iResult, $tBuffer, $pBuffer, $aResult[1][9], $tagADPTINFO, $tAdpt 

; 第一次调用传递空值,pOutBufLen ( $iResult[2] ) 设为结构所需大小,单位byte。 
$iResult = DllCall("iphlpapi.dll", "dword", "GetAdaptersInfo", "ptr", 0, "ulong*", 0) 
$tBuffer = DllStructCreate("byte[" & $iResult[2] & "]") ; 定义$iResult[2] 字节的缓存区域 (分配内存空间)。 
$pBuffer = DllStructGetPtr($tBuffer) ; 获取内存指针。 

; 第二次调用,GetAdaptersInfo把网卡信息复制到指定的内存空间 ($tBuffer) 中。 
$iResult = DllCall("iphlpapi.dll", "dword", "GetAdaptersInfo", "ptr", $pBuffer, "ulong*", $iResult[2]) 
; $iResult[0]值为0则调用成功,否则为系统错误号。 

; 数据转换, byte --> IP_ADAPTER_INFO 
$tagADPTINFO = "ptr NextAdpt; dword ComboIndex; char AdptName[260]; char AdptDescr[132];uint AddrLength;byte MacAddr[8];dword Index;uint Type; uint DhcpEnabled;ptr CurrentIpAddr;ptr NextIpAddr; char IpAddr[16];char IpAddrMask[16]; dword IpAddrCxt; ptr NextGateway; char GatewayAddr[16]; char GatewayAddrMask[16];dword GatewayCxt; ptr NextDhcp; char DhcpAddr[16]; char DhcpAddrMask[16];dword DhcpCxt; int HaveWins; ptr NextPriWinsServer; char PriWinsServerAddr[16]; char PriWinsServerAddrMask[16]; dword PriWinsServerCxt; ptr NextSecWinsServer; char SecWinsServerAddr[16]; char SecWinsServerAddrMask[16]; dword LeaseObtained; dword LeaseExpires" 

While $pBuffer 
$tAdpt = DllStructCreate($tagADPTINFO, $pBuffer) 
$aResult[0][0] += 1 
ReDim $aResult[$aResult[0][0] + 1][9] 
$aResult[$aResult[0][0]][0] = DllStructGetData($tAdpt, "AdptName") ; 网卡名称 
$aResult[$aResult[0][0]][1] = DllStructGetData($tAdpt, "AdptDescr") ; 网卡描述 
$aResult[$aResult[0][0]][2] = DllStructGetData($tAdpt, "MacAddr") ; 网卡MAC 
$aResult[$aResult[0][0]][3] = DllStructGetData($tAdpt, "Index") ; 网卡索引号 
$aResult[$aResult[0][0]][4] = DllStructGetData($tAdpt, "Type") ; 类型 
$aResult[$aResult[0][0]][5] = DllStructGetData($tAdpt, "DhcpEnabled") ; DHCP是否启用 true = 启用, false = 禁用 
$aResult[$aResult[0][0]][6] = DllStructGetData($tAdpt, "IpAddr") ; IP 地址 
$aResult[$aResult[0][0]][7] = DllStructGetData($tAdpt, "GatewayAddr") ; 网关地址 
$aResult[$aResult[0][0]][8] = DllStructGetData($tAdpt, "DhcpAddr") ; DHCP地址, 只有DhcpEnabled为true时,此值才有效。 
$pBuffer = DllStructGetData($tAdpt, "NextAdpt") ; [下一张网卡信息的内存地址。] 
$tAdpt = 0 
WEnd 
$tBuffer = 0 
Return SetError($iResult[0], 0, $aResult) 
EndFunc ;==>_GetAdaptersInfo 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值