其函数原型如下:
__inout PULONG pOutBufLen
);
我们要从DLL中定位并使用这个函数,就必须申明其用到的结构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_DESCRIPTION_LENGTH 128
#define MAX_ADAPTER_ADDRESS_LENGTH 8
其中表示IP地址列表的结构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
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(这几个头文件和静态库网上有,可自己下载)