原文: http://hi.baidu.com/cdutboy/blog/item/9c8bd030f1b49e10eac4af51.html
IPHELP库里的函数,可惜我的VS2005没了。又不想去下SDK(要是SDK是一个文件还好,偏偏那么多)
于是想到,直接从DLL里获得函数地址
GetAdaptersInfo 存在于iphlpapi.dll 这个文件中
其函数原型如下:
DWORD
GetAdaptersInfo (
我们要从DLL中定位并使用这个函数,就必须申明其用到的结构
IP_ADAPTER_INFO
__out
PIP_ADAPTER_INFO
pAdapterInfo
,
__inout PULONG pOutBufLen
);
__inout PULONG pOutBufLen
);
这个结构体的原型
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 ;
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
#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 ;
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 );
char String [ 4 * 4 ];
} IP_ADDRESS_STRING , * PIP_ADDRESS_STRING , IP_MASK_STRING , * PIP_MASK_STRING ;
最后是这个函数的压栈声明
//函数压栈申明
typedef DWORD ( __stdcall * pGetAdaptersInfo )( PIP_ADAPTER_INFO , PULONG );
以上就是用到的全部结构的声明
在 iphlpapi.dll 这个dll中定位 GetAdaptersInfo
HMODULE hInst = LoadLibrary ( "iphlpapi.dll" );
if ( ! hInst )
{
MessageBox ( "无法加载iphlpapi.dll!" , "错误" , MB_OK + MB_ICONSTOP );
}
pGetAdaptersInfo GetAdaptersInfo = ( pGetAdaptersInfo ) GetProcAddress ( hInst , "GetAdaptersInfo" );
if ( GetAdaptersInfo == NULL )
{
MessageBox ( "无法定位到函数GetAdaptersInfo地址!" , "错误" , MB_OK + MB_ICONSTOP );
exit ( 0 );
}
else
{
//
int nIndex = 0 ;
ULONG uOutBufLen = 0 ; //存放网卡信息的缓冲区大小
pIPAdapterInfo = ( PIP_ADAPTER_INFO ) malloc ( sizeof ( IP_ADAPTER_INFO ));
//第一次调用GetAdapterInfo获取ulOutBufLen大小
if (( GetAdaptersInfo ( pIPAdapterInfo , & uOutBufLen )) == ERROR_BUFFER_OVERFLOW )
{
//获取需要的缓冲区大小
free ( pIPAdapterInfo );
pIPAdapterInfo = ( PIP_ADAPTER_INFO ) malloc ( uOutBufLen ); //分配所需要的内存
}
if (( GetAdaptersInfo ( pIPAdapterInfo , & uOutBufLen )) == NO_ERROR ) //获取网卡信息
{
//保存网卡信息
//...........
}
}
程序运行界面
由于文件不大,我就把程序直接 压制 到下面的图片里了
另存图片到本地,改图片扩展名为rar,解压就可以看到程序了
以太网网卡
ADSL拨号网卡
微软一直给我们提供头文件,把大家都惯坏了。用起dll定位来,真麻烦