获得本地适配器信息

其函数原型如下:

DWORD GetAdaptersInfo(
__out    PIP_ADAPTER_INFO pAdapterInfo ,
__inout PULONG pOutBufLen
);

我们要从DLL中定位并使用这个函数,就必须申明其用到的结构IP_ADAPTER_INFO

这个结构体的原型

typedef struct _IP_ADAPTER_INFO {
struct _IP_ADAPTER_INFO * Next; //结构列表的下一个节点
DWORD                   ComboIndex; //保留
char                    AdapterName [ MAX_ADAPTER_NAME_LENGTH + 4 ]; //网卡名称
char                    Description [ MAX_ADAPTER_DESCRIPTION_LENGTH + 4 ]; //网卡描述
UINT                    AddressLength; //网卡地址长度
BYTE                    Address [ MAX_ADAPTER_ADDRESS_LENGTH ]; //MAC地址
DWORD                   Index; //网络接口索引号
UINT                    Type; //网络接口类型
UINT                    DhcpEnabled; //是否启用DHCP
PIP_ADDR_STRING         CurrentIpAddress; //当前IP地址(不知道为什么我输出错误--!)
IP_ADDR_STRING          IpAddressList; //IP地址列表
IP_ADDR_STRING          GatewayList; //网关地址列表
IP_ADDR_STRING          DhcpServer; //DHCP服务器地址
BOOL                    HaveWins; //是否启动了Wins服务
IP_ADDR_STRING          PrimaryWinsServer; //主Wins服务地址
IP_ADDR_STRING          SecondaryWinsServer; //次Wins服务
time_t                  LeaseObtained; //DHCP租赁时间
time_t                  LeaseExpires; //DHCP租赁失效时间
} IP_ADAPTER_INFO , * PIP_ADAPTER_INFO;


这个IP_ADAPTER_INFO结构体中,有几个宏,其定义如下

#define MAX_ADAPTER_NAME_LENGTH 256
#define MAX_ADAPTER_DESCRIPTION_LENGTH 128
#define MAX_ADAPTER_ADDRESS_LENGTH 8


其中表示IP地址列表的结构IP_ADDR_STRING

typedef struct _IP_ADDR_STRING {
    struct _IP_ADDR_STRING * Next; //下一个节点
    IP_ADDRESS_STRING IpAddress; //IP地址
    IP_MASK_STRING IpMask; //子网掩码
    DWORD Context;
} IP_ADDR_STRING , * PIP_ADDR_STRING;


表示IP的结构IP_ADDRESS_STRING

typedef struct {
char String [ 4 * 4 ];
} IP_ADDRESS_STRING , * PIP_ADDRESS_STRING , IP_MASK_STRING , * PIP_MASK_STRING;

最后是这个函数的压栈声明
//函数压栈申明
typedef DWORD ( __stdcall * pGetAdaptersInfo)( PIP_ADAPTER_INFO , PULONG);


以上就是用到的全部结构的声明

 

 

Managing Network Adapters Using GetAdaptersInfo
使用GetAdaptersInfo管理网卡

The GetAdaptersInfo function fills a pointer to an IP_ADAPTER_INFO structure with information about the network adapters associated with the system.
GetAdaptersInfo函数返回与当前系统关联的网卡信息填充一个IP_ADAPTER_INFO结构。

To use GetAdaptersInfo
使用GetAdaptersInfo函数

1. Declare a pointer to an IP_ADAPTER_INFO variable called pAdapterInfo, and a ULONG variable called ulOutBufLen. These variables are passed as parameters to the GetAdaptersInfo function. Also create a DWORD variable called dwRetVal (for error checking).
1. 声明一个IP_ADAPTER_INFO结构指针变量pAdapterInfo,一个ULONG变量ulOutBufLen。这些变量作为参数传递给GetAdaptersInfo函数。定义一个DWORD变量dwRetVal(用于检错)。

IP_ADAPTER_INFO *pAdapterInfo;
ULONG            ulOutBufLen;
DWORD            dwRetVal;

2. Allocate memory for the structures.
2. 为结构分配内存。

pAdapterInfo = (IP_ADAPTER_INFO *) malloc( sizeof(IP_ADAPTER_INFO) );
ulOutBufLen = sizeof(IP_ADAPTER_INFO);

3. Make an initial call to GetAdaptersInfo to get the size needed into the ulOutBufLen variable.
Note This call to the function is meant to fail, and is used to ensure that the ulOutBufLen variable specifies a size sufficient for holding all the information returned to pAdapterInfo. This is a common programming model for data structures and functions of this type.
3. 第一次调用GetAdaptersInfo获取适当的ulOutBufLen变量大小。
注:有意进行一次失败调用,以确定适当的ulOutBufLen变量(缓冲区)大小,以缓冲返回至pAdapterInfo的所有数据。这种方法是此类结构和函数的常用编程模式。

if (GetAdaptersInfo( pAdapterInfo, &ulOutBufLen) != ERROR_SUCCESS) {
    free (pAdapterInfo);
    pAdapterInfo = (IP_ADAPTER_INFO *) malloc ( ulOutBufLen );
}

4. Make a second call to GetAdaptersInfo, passing pAdapterInfo and ulOutBufLen as parameters and doing general error checking. Return its value to the DWORD variable dwRetVal (for more extensive error checking).
4. 进行第二次GetAdaptersInfo调用,传递pAdapterInfo、ulOutBufLen参数并进行一般的错误检查。错误信息返回至dwRetVal(用于更多的错误检查)。

if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) != ERROR_SUCCESS) {
    printf("GetAdaptersInfo call failed with %d/n", dwRetVal);
}

5. If the call was successful, access some of the data in the pAdapterInfo structure.
5. 如果调用成功,通过pAdapterInfo结构访问数据。

PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
while (pAdapter) {
    printf("Adapter Name: %s/n", pAdapter->AdapterName);
    printf("Adapter Desc: %s/n", pAdapter->Description);
    printf("/tAdapter Addr: /t");
    for (UINT i = 0; i < pAdapter->AddressLength; i++) {
        if (i == (pAdapter->AddressLength - 1))
            printf("%.2X/n",(int)pAdapter->Address);
        else
            printf("%.2X-",(int)pAdapter->Address);
    }
    printf("IP Address: %s/n", pAdapter->IpAddressList.IpAddress.String);
    printf("IP Mask: %s/n", pAdapter->IpAddressList.IpMask.String);
    printf("/tGateway: /t%s/n", pAdapter->GatewayList.IpAddress.String);
    printf("/t***/n");
    if (pAdapter->DhcpEnabled) {
        printf("/tDHCP Enabled: Yes/n");
        printf("/t/tDHCP Server: /t%s/n", pAdapter->DhcpServer.IpAddress.String);
    }
    else
      printf("/tDHCP Enabled: No/n");
pAdapter = pAdapter->Next;
}

6. Free any memory allocated for the pAdapterInfo structure.
6. 释放为pFixedInfo结构分配的内存。

if (pAdapterInfo)
        free(pAdapterInfo);

 

 

源码:

#include <winsock2.h>
#include <Iphlpapi.h>
#include <stdio.h>

int main()
{
  /* 定义两个结构变量 */
  PIP_ADAPTER_INFO pAdapterInfo;
  PIP_ADAPTER_INFO pAdapter = NULL;
 
  /* 用来检错 */
  DWORD dwRetVal = 0;

  ULONG ulOutBufLen;

  /* 为结构分配内存 */
  pAdapterInfo = (PIP_ADAPTER_INFO)malloc(sizeof(IP_ADAPTER_INFO));
  ulOutBufLen = sizeof(IP_ADAPTER_INFO);

  /* 第一次调用函数GetAdaptersInfo获得适当的ulOutBufLen */
  if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW)
  {
    free(pAdapterInfo);
    pAdapterInfo = (PIP_ADAPTER_INFO)malloc(ulOutBufLen);
  }

  if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
  {
    pAdapter = pAdapterInfo;

    while (pAdapter)
    {
      printf("MAC Address: /t%02x-%02x-%02x-%02x-%02x-%02x/n",
      pAdapter->Address[0],
      pAdapter->Address[1],
      pAdapter->Address[2],
      pAdapter->Address[3],
      pAdapter->Address[4],
      pAdapter->Address[5]);
      printf("IP Address: /t%s/n", pAdapter->IpAddressList.IpAddress.String);
      printf("IP Mask: /t%s/n", pAdapter->IpAddressList.IpMask.String);
      printf("Gateway: /t%s/n", pAdapter->GatewayList.IpAddress.String);
      printf("Adapter Name: /t%s/n", pAdapter->AdapterName);
      printf("Adapter Desc: /t%s/n", pAdapter->Description);
      pAdapter = pAdapter->Next;
    }
  }
  else
  {
    printf("Get Adapter Info error!/n");
  }
}

 

Makefile:

 

 

CC = gcc
CFLAGS = -g

%.o: %.c
 $(CC) $(CFLAGS) -c $<

all: test.exe

test.exe: getadapterinfo.c winsock2.h Iphlpapi.h
 $(CC) $(CFLAGS) -o test.exe getadapterinfo.c IPHLPAPI.LIB WS2_32.LIB

clean:
 rm -f test.o test.exe *.bak

 

注意:需要用到Iphlpapi.h  IPTYPES.H IPEXPORT.H WINSOCK2.H  及两个静态库 IPHLPAPI.LIB 和 WS2_32.LIB(这几个头文件和静态库网上有,可自己下载)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值