通过GetAdaptersInfo获取网卡配置和Ip地址信息
文章转自王牌软件
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)
只回答业务咨询
站长推荐:NSetup一键部署软件
一键式完成美化安装包制作,自动增量升级,数据统计,数字签名。应对各种复杂场景,脚本模块化拆分,常规复杂的脚本代码,图形化设置。无需专业的研发经验,轻松完成项目部署。(www.nsetup.cn)
一台机器上可能不只有一个网卡,但每一个网卡只有一个MAC地址,而每一个网卡可能配置有多个IP地址;如平常的笔记本电脑中,就会有无线网卡和有线网卡(网线接口)两种;因此,如果要获得本机所有网卡的IP和MAC地址信息,则必须顺序获得每个网卡,再依次获取其信息等;在windows sdk中,用IP_ADAPTER_INFO结构体存储网卡信息,包括网卡名、网卡描述、网卡MAC地址、网卡IP等,该结构体的主要描述如下所示: 由于可能有多个网卡,因此struct _IP_ADAPTER_INFO* Next字段为一个链表结构指针,由于一个网卡可能有多个IP,因此IP_ADDR_STRING字段应该也是一个链表结构,其信息如下所示:
在基本了解以上信息后,就可以调用GetAdaptersInfo函数来获取相关网卡信息了,其通用的代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
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; 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; #include <WinSock2.h> #include <Iphlpapi.h> #include <iostream> using namespace std; #pragma comment(lib,"Iphlpapi.lib") //需要添加Iphlpapi.lib库 int main(int argc, char* argv[]) { //PIP_ADAPTER_INFO结构体指针存储本机网卡信息 PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO(); //得到结构体大小,用于GetAdaptersInfo参数 unsigned long stSize = sizeof(IP_ADAPTER_INFO); //调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量;其中stSize参数既是一个输入量也是一个输出量 int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize); //记录网卡数量 int netCardNum = 0; //记录每张网卡上的IP地址数量 int IPnumPerNetCard = 0; if (ERROR_BUFFER_OVERFLOW == nRel) { //如果函数返回的是ERROR_BUFFER_OVERFLOW //则说明GetAdaptersInfo参数传递的内存空间不够,同时其传出stSize,表示需要的空间大小 //这也是说明为什么stSize既是一个输入量也是一个输出量 //释放原来的内存空间 delete pIpAdapterInfo; //重新申请内存空间用来存储所有网卡信息 pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[stSize]; //再次调用GetAdaptersInfo函数,填充pIpAdapterInfo指针变量 nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize); } if (ERROR_SUCCESS == nRel) { //输出网卡信息 //可能有多网卡,因此通过循环去判断 while (pIpAdapterInfo) { cout<<"网卡数量:"<<++netCardNum<<endl; cout<<"网卡名称:"<<pIpAdapterInfo->AdapterName<<endl; cout<<"网卡描述:"<<pIpAdapterInfo->Description<<endl; switch(pIpAdapterInfo->Type) { case MIB_IF_TYPE_OTHER: cout<<"网卡类型:"<<"OTHER"<<endl; break; case MIB_IF_TYPE_ETHERNET: cout<<"网卡类型:"<<"ETHERNET"<<endl; break; case MIB_IF_TYPE_TOKENRING: cout<<"网卡类型:"<<"TOKENRING"<<endl; break; case MIB_IF_TYPE_FDDI: cout<<"网卡类型:"<<"FDDI"<<endl; break; case MIB_IF_TYPE_PPP: printf("PP\n"); cout<<"网卡类型:"<<"PPP"<<endl; break; case MIB_IF_TYPE_LOOPBACK: cout<<"网卡类型:"<<"LOOPBACK"<<endl; break; case MIB_IF_TYPE_SLIP: cout<<"网卡类型:"<<"SLIP"<<endl; break; default: break; } cout<<"网卡MAC地址:"; for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++) if (i < pIpAdapterInfo->AddressLength-1) { printf("%02X-", pIpAdapterInfo->Address[i]); } else { printf("%02X\n", pIpAdapterInfo->Address[i]); } cout<<"网卡IP地址如下:"<<endl; //可能网卡有多IP,因此通过循环去判断 IP_ADDR_STRING *pIpAddrString =&(pIpAdapterInfo->IpAddressList); do { cout<<"该网卡上的IP数量:"<<++IPnumPerNetCard<<endl; cout<<"IP 地址:"<<pIpAddrString->IpAddress.String<<endl; cout<<"子网地址:"<<pIpAddrString->IpMask.String<<endl; cout<<"网关地址:"<<pIpAdapterInfo->GatewayList.IpAddress.String<<endl; pIpAddrString=pIpAddrString->Next; } while (pIpAddrString); pIpAdapterInfo = pIpAdapterInfo->Next; cout<<"--------------------------------------------------------------------"<<endl; } } //释放内存空间 if (pIpAdapterInfo) { delete pIpAdapterInfo; } return 0; } 枚举和获取网卡物理MAC地址 int EnumHardWareMAC() { HRESULT hrVal; HKEY pHKey = NULL; hrVal = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE//Microsoft//Windows NT//CurrentVersion//NetworkCards"), 0, KEY_ALL_ACCESS, &pHKey); if(hrVal == ERROR_SUCCESS) { TCHAR sz[256]; DWORD i=0; while(RegEnumKey(pHKey, i++, sz, 255) == ERROR_SUCCESS) { HKEY pHKeyEx=0; hrVal = RegOpenKeyEx(pHKey, sz, 0, KEY_ALL_ACCESS, &pHKeyEx); if(hrVal == ERROR_SUCCESS) { int j=0; while(1) { TCHAR szName[256]; DWORD dwName=255; BYTE szVal[256]; DWORD dwVal=255; DWORD nType; hrVal = RegEnumValue(pHKeyEx, j++, szName, &dwName, 0, &nType, szVal, &dwVal); if(hrVal== ERROR_SUCCESS) { TRACE(_T("%s=>%s/r/n"), szName, szVal); } else break; } DWORD nType; BYTE ServeUUID[256] = {0}; DWORD dwSize=255; hrVal = RegQueryValueEx(pHKeyEx, _T("ServiceName"), 0, &nType, ServeUUID, &dwSize); if(hrVal == ERROR_SUCCESS) { HANDLE hHandle = 0; TCHAR DevName[256] = _T("//./"); _tcscat(DevName, (TCHAR*)ServeUUID); hHandle=CreateFile(DevName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0 , NULL); if(hHandle != INVALID_HANDLE_VALUE) { DWORD dw=0; DWORD IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002; int OID_802_3_PERMANENT_ADDRESS = 0x01010101; BYTE outBuf[256]={0}; if(DeviceIoControl(hHandle, IOCTL_NDIS_QUERY_GLOBAL_STATS, &OID_802_3_PERMANENT_ADDRESS,4, outBuf,256, &dw, NULL)) { TRACE(_T("%02X-%02X-%02X-%02X-%02X-%02X/r/n"), (WORD)outBuf[0], (WORD)outBuf[1], (WORD)outBuf[2], (WORD)outBuf[3], (WORD)outBuf[4], (WORD)outBuf[5]); //outBuf dw } CloseHandle(hHandle); } } RegCloseKey(pHKeyEx); } } RegCloseKey(pHKey); } return 0; } |
学习日记,兼职软件设计,软件修改,毕业设计。
本文出自 学习日记,转载时请注明出处及相应链接。
本文永久链接: https://www.softwareace.cn/?p=320