C语言获取windows系统mac列表

本文提供了一个使用C语言在Windows系统中获取所有物理及虚拟网卡MAC地址的示例代码。通过调用GetAdaptersInfo函数并进行适当的数据处理,可以有效地收集MAC地址信息。

欢迎转载,但转载时请注明本博客出处:http://blog.youkuaiyun.com/pingd/article/details/22397983,谢谢!

使用C语言获取windows操作系统MAC列表,包含实际存在的物理网卡以及虚拟网卡,话不多说,直接上代码:

//获取系统mac列表,每一个mac地址保存空间大小为18字节
//成功返回0,失败返回-1
int GetSysMac(int &macNum,char macList[][18])
{
	char mac[18] = { 0 };
	//记录网卡数量
	int netCardNum = 0;

	PIP_ADAPTER_INFO pIpAdapterInfo  = (PIP_ADAPTER_INFO)malloc(sizeof(IP_ADAPTER_INFO));
	unsigned long stSize = sizeof(IP_ADAPTER_INFO);
	int nRel = GetAdaptersInfo(pIpAdapterInfo,&stSize);

	if (ERROR_BUFFER_OVERFLOW == nRel) {
		free(pIpAdapterInfo);
		//重新申请内存
		pIpAdapterInfo = (PIP_ADAPTER_INFO)malloc(stSize);
		nRel=GetAdaptersInfo(pIpAdapterInfo,&stSize); 
	}

	if (ERROR_SUCCESS == nRel) {
		while (pIpAdapterInfo) {
			char temp[4] = { 0 };
			for (DWORD i = 0; i < pIpAdapterInfo->AddressLength; i++) {
				if (i < pIpAdapterInfo->AddressLength-1)
				{
					sprintf(temp,"%02X:", pIpAdapterInfo->Address[i]);
					strcat(mac,temp);
					memset(temp,0,sizeof(temp));
				}
				else
				{
					sprintf(temp,"%02X", pIpAdapterInfo->Address[i]);
					strcat(mac,temp);
					memset(temp,0,sizeof(temp));
				}
			}
			memcpy(macList[netCardNum],mac,sizeof(mac));
			memset(mac,0,sizeof(mac));
			pIpAdapterInfo = pIpAdapterInfo->Next;
			netCardNum++;
		}
	}

	//释放内存空间
	if (pIpAdapterInfo)
	{
		free (pIpAdapterInfo);
	}

	macNum = netCardNum;

	return 0;
}

其中macNum是所获取到的系统MAC数量,MAC列表存放在macList中。


完整代码下载请猛戳右边红色→(下载)

<think>我们使用Windows API中的GetAdaptersInfo或GetAdaptersAddresses函数来获取网络适配器的信息,包括MAC地址。 这里我们使用GetAdaptersInfo,因为它可以获取MAC地址(物理地址)。 但是注意:GetAdaptersInfo在较新的Windows版本中可能被GetAdaptersAddresses取代,但为了简单且兼容,我们先使用GetAdaptersInfo。 以下代码演示如何获取网络适配器的MAC地址(物理地址):</think>要获取 Windows 网络接口的 MAC 地址,可以使用 Windows API 中的 `GetAdaptersAddresses` 函数。以下是一个完整的 C 语言实现: ```c #include <winsock2.h> #include <iphlpapi.h> #include <stdio.h> #include <stdlib.h> #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "ws2_32.lib") int main() { ULONG flags = GAA_FLAG_INCLUDE_PREFIX; ULONG family = AF_UNSPEC; // 同时支持IPv4和IPv6 ULONG outBufLen = 15000; // 初始缓冲区大小 PIP_ADAPTER_ADDRESSES pAddresses = NULL; PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL; DWORD dwRetVal = 0; // 分配初始缓冲区 pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen); if (pAddresses == NULL) { printf("Memory allocation failed\n"); return 1; } // 获取适配器信息 dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); // 如果缓冲区太小,重新分配 if (dwRetVal == ERROR_BUFFER_OVERFLOW) { free(pAddresses); pAddresses = (IP_ADAPTER_ADDRESSES *)malloc(outBufLen); if (pAddresses == NULL) { printf("Memory allocation failed\n"); return 1; } dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses, &outBufLen); } if (dwRetVal == NO_ERROR) { pCurrAddresses = pAddresses; while (pCurrAddresses) { // 跳过没有物理地址的适配器 if (pCurrAddresses->PhysicalAddressLength != 0) { printf("\nAdapter Name: %S\n", pCurrAddresses->FriendlyName); printf("Adapter Type: %s\n", pCurrAddresses->IfType == IF_TYPE_ETHERNET_CSMACD ? "Ethernet" : pCurrAddresses->IfType == IF_TYPE_IEEE80211 ? "Wi-Fi" : "Other"); // 打印MAC地址 printf("MAC Address: "); for (ULONG i = 0; i < pCurrAddresses->PhysicalAddressLength; i++) { if (i == (pCurrAddresses->PhysicalAddressLength - 1)) printf("%.2X", (int)pCurrAddresses->PhysicalAddress[i]); else printf("%.2X-", (int)pCurrAddresses->PhysicalAddress[i]); } printf("\n"); } pCurrAddresses = pCurrAddresses->Next; } } else { printf("GetAdaptersAddresses failed with error: %d\n", dwRetVal); if (dwRetVal == ERROR_NO_DATA) printf("No adapters found\n"); } if (pAddresses) free(pAddresses); return 0; } ``` ### 代码解释: 1. **头文件和库**: - `<iphlpapi.h>`:提供网络适配器信息相关函数 - `#pragma comment(lib, ...)`:自动链接所需库 2. **GetAdaptersAddresses 函数**: - 这是核心函数,用于获取网络适配器信息 - 参数说明: - `family`:指定地址族(AF_UNSPEC 表示获取所有类型) - `flags`:控制返回的信息类型(GAA_FLAG_INCLUDE_PREFIX 包含前缀信息) - `outBufLen`:缓冲区大小(初始设为15000字节) 3. **MAC 地址处理**: - `PhysicalAddress` 字段包含 MAC 地址字节数组 - `PhysicalAddressLength` 表示地址长度(通常为6字节) - 使用十六进制格式打印地址(XX-XX-XX-XX-XX-XX) 4. **适配器类型识别**: - 通过 `IfType` 字段识别适配器类型 - 常见类型:IF_TYPE_ETHERNET_CSMACD(有线),IF_TYPE_IEEE80211(无线) 5. **错误处理**: - 检查 ERROR_BUFFER_OVERFLOW 错误并重新分配内存 - 处理 ERROR_NO_DATA 等错误情况 ### 编译和运行: 1. 在 Visual Studio 中创建 C 控制台项目 2. 复制代码到源文件(如 `get_mac.c`) 3. 编译并运行(不需要管理员权限) ### 输出示例: ``` Adapter Name: Intel(R) Wi-Fi 6 AX201 160MHz Adapter Type: Wi-Fi MAC Address: 78-28-97-AA-BB-CC Adapter Name: Realtek PCIe GbE Family Controller Adapter Type: Ethernet MAC Address: 00-1A-4B-CC-DD-EE ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值