C/C++ 获取 MAC 地址的几种方法

2022-12-28 17:46:46 浏览数 (1)

Netbios

代码语言:javascript复制
#include <windows.h>
#pragma comment(lib, "Netapi32.lib")
 
namespace
{
bool GetAdapterInfo(int adapterNum, std::string& macOUT)
{
	NCB Ncb;
	memset(&Ncb, 0, sizeof(Ncb));
	Ncb.ncb_command = NCBRESET; // 重置网卡,以便我们可以查询
	Ncb.ncb_lana_num = adapterNum;
	if (Netbios(&Ncb) != NRC_GOODRET)
		return false;
	 
	// 准备取得接口卡的状态块
	memset(&Ncb, sizeof(Ncb), 0);
	Ncb.ncb_command = NCBASTAT;
	Ncb.ncb_lana_num = adapterNum;
	strcpy((char *) Ncb.ncb_callname, "*");
	struct ASTAT
	{
		ADAPTER_STATUS adapt;
		NAME_BUFFER nameBuff[30];
	}adapter;
	memset(&adapter,sizeof(adapter), 0);
	Ncb.ncb_buffer = (unsigned char *)&adapter;
	Ncb.ncb_length = sizeof(adapter);
	if (Netbios(&Ncb) != 0)
		return false;
	 
	char acMAC[32];
	sprintf(acMAC, "X-X-X-X-X-X",
		int (adapter.adapt.adapter_address[0]),
		int (adapter.adapt.adapter_address[1]),
		int (adapter.adapt.adapter_address[2]),
		int (adapter.adapt.adapter_address[3]),
		int (adapter.adapt.adapter_address[4]),
		int (adapter.adapt.adapter_address[5]));
	macOUT = acMAC;
	return true;
}
}

bool GetMacByNetBIOS(std::string& macOUT)
{
	// 取得网卡列表
	LANA_ENUM adapterList;
	NCB Ncb;
	memset(&Ncb, 0, sizeof(NCB));
	Ncb.ncb_command = NCBENUM;
	Ncb.ncb_buffer = (unsigned char *)&adapterList;
	Ncb.ncb_length = sizeof(adapterList);
	Netbios(&Ncb);
	 
	// 取得MAC
	for (int i = 0; i < adapterList.length;   i)
	{
		if (GetAdapterInfo(adapterList.lana[i], macOUT))
		return true;
	}
	 
	return false;
}

DeviceIoControl

代码语言:javascript复制
#include <stdio.h>
#include <locale.h>
#include <tchar.h>

#include <windows.h>
#include <shlwapi.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi.lib")
#include <devguid.h>
#pragma comment(lib, "uuid.lib")
#include <ntddndis.h>
#include <ndisguid.h>
#include <iptypes.h>
#include <regstr.h>

using DIDD_TYPE_BASE = SP_DEVICE_INTERFACE_DETAIL_DATA;
using DIDD_TYPE_CHAR = decltype(*static_cast<DIDD_TYPE_BASE *>(nullptr)->DevicePath);

static constexpr SIZE_T DIDD_SIZE_HEAD = offsetof(DIDD_TYPE_BASE, DevicePath);
static constexpr SIZE_T DIDD_SIZE_BODY = sizeof(DIDD_TYPE_CHAR) * MAX_PATH;
static constexpr SIZE_T DIDD_SIZE_FULL = DIDD_SIZE_HEAD   DIDD_SIZE_BODY;

using DEVICE_INTERFACE_DETAIL_DATA = union DEVICE_INTERFACE_DETAIL_DATA {
	inline SP_DEVICE_INTERFACE_DETAIL_DATA *operator->() { return &DetailData; }
	inline SP_DEVICE_INTERFACE_DETAIL_DATA *operator &() { return &DetailData; }
	SP_DEVICE_INTERFACE_DETAIL_DATA DetailData;
	BYTE Buffer[DIDD_SIZE_FULL];
};

static void SetupDiOutputDeviceAddress(LPCTSTR DevicePath)
{
	HANDLE hFile = CreateFile(DevicePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
	if (hFile != INVALID_HANDLE_VALUE)
	{
		BOOL bResult = FALSE;
		BYTE bAddress[MAX_ADAPTER_ADDRESS_LENGTH] = { 0 };
		DWORD dwCtls[] = { OID_802_3_PERMANENT_ADDRESS, OID_802_3_CURRENT_ADDRESS };
		for (DWORD i = 0; i < ARRAYSIZE(dwCtls); i  )
		{
			DWORD dwCode = dwCtls[i];
			DWORD cbRead = 0;
			bResult = DeviceIoControl(hFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwCode, sizeof(dwCode), bAddress, sizeof(bAddress), &cbRead, nullptr);
			if (bResult)
			{
				wprintf(L"网卡地址 [X-X-X-X-X-X]n", bAddress[0], bAddress[1], bAddress[2], bAddress[3], bAddress[4], bAddress[5]);
				break;
			}
		}

		DWORD dwType = 0;
		DWORD dwCode = OID_GEN_PHYSICAL_MEDIUM;
		DWORD cbRead = 0;
		bResult = DeviceIoControl(hFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwCode, sizeof(dwCode), &dwType, sizeof(dwType), &cbRead, nullptr);
		CloseHandle(hFile);
		if (bResult)
		{
			BOOL bWireless = FALSE;
			switch (dwType) {
			case NdisPhysicalMediumWirelessLan:
			case NdisPhysicalMediumWirelessWan:
			case NdisPhysicalMediumNative802_11:
			case NdisPhysicalMediumBluetooth:
			case NdisPhysicalMediumWiMax:
			case NdisPhysicalMediumUWB:
				bWireless = TRUE;
			default:
				wprintf(L"是否无线 [%d]n", bWireless);
				break;
			}
		}
	}
}

ipconfig /all 类似的还有 :getmac /v /fo list

代码语言:javascript复制
bool GetMacByCmd(std::string& macOUT)
{
	bool ret = false;
	 
	//初始化返回MAC地址缓冲区
	SECURITY_ATTRIBUTES sa; 
	sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
	sa.lpSecurityDescriptor = NULL; 
	sa.bInheritHandle = TRUE; 
	 
	//创建管道
	HANDLE hReadPipe,hWritePipe;
	if(CreatePipe(&hReadPipe, &hWritePipe, &sa, 0) == TRUE)
	{
		//控制命令行窗口信息
		STARTUPINFO si; 
		//返回进程信息
		PROCESS_INFORMATION pi;
		si.cb = sizeof(STARTUPINFO); 
		GetStartupInfo(&si); 
		si.hStdError = hWritePipe; 
		si.hStdOutput = hWritePipe; 
		si.wShowWindow = SW_HIDE; //隐藏命令行窗口
		si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
		 
		//创建获取命令行进程
		if (CreateProcess(NULL, "ipconfig /all", NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) == TRUE) 
		{ 
			WaitForSingleObject(pi.hProcess, 3000); // 设置超时时间,防止Vista、Win7等操作系统卡死
			unsigned long count;
			CloseHandle(hWritePipe);
			std::string strBuffer(1024 * 10, ''); // 准备足够大的缓冲区
			if(ReadFile(hReadPipe, const_cast<char*>(strBuffer.data()), strBuffer.size() - 1, &count, 0) == TRUE)
			{
				strBuffer.resize(strBuffer.find_first_of('')); // 截掉缓冲区后面多余的''
				ret = ParseMac(strBuffer, macOUT);//提取MAC地址串
			}
			CloseHandle(pi.hThread); 
			CloseHandle(pi.hProcess); 
		}
		CloseHandle(hWritePipe); // VS2010下调试,此处会有“An invalid handle was specified”的中断,直接运行正常,原因未知。VS2008上正常。
		CloseHandle(hReadPipe);
	}
	
	return ret;
}

SNMP

代码语言:javascript复制
#include <snmp.h>
#pragma comment(lib, "snmpapi.lib")
#pragma comment(lib, "Ws2_32.lib")
 
bool GetMacBySNMP(std::string& macOUT)
{
	bool ret = false;
	WSADATA WinsockData;
	if (WSAStartup(MAKEWORD(2, 0), &WinsockData) != 0) 
		return false;
 
	// Load the SNMP dll and get the addresses of the functions necessary
	const HINSTANCE m_dll = LoadLibrary("inetmib1.dll");
	if (m_dll < (HINSTANCE) HINSTANCE_ERROR)
		return false;
 
	const PFNSNMPEXTENSIONINIT f_SnmpExtensionInit = (PFNSNMPEXTENSIONINIT) GetProcAddress(m_dll, "SnmpExtensionInit");
	const PFNSNMPEXTENSIONINITEX f_SnmpExtensionInitEx = (PFNSNMPEXTENSIONINITEX) GetProcAddress(m_dll, "SnmpExtensionInitEx");
	const PFNSNMPEXTENSIONQUERY f_SnmpExtensionQuery = (PFNSNMPEXTENSIONQUERY) GetProcAddress(m_dll, "SnmpExtensionQuery");
	const PFNSNMPEXTENSIONTRAP f_SnmpExtensionTrap = (PFNSNMPEXTENSIONTRAP) GetProcAddress(m_dll, "SnmpExtensionTrap");
 
	HANDLE pollForTrapEvent;
	AsnObjectIdentifier supportedView;
	f_SnmpExtensionInit(GetTickCount(), &pollForTrapEvent, &supportedView);
	 
	// Initialize the variable list to be retrieved by f_SnmpExtensionQuery
	const AsnObjectIdentifier MIB_NULL = { 0, 0 };
	 
	RFC1157VarBind varBind[2];
	varBind[0].name = MIB_NULL;
	varBind[1].name = MIB_NULL;
	 
	RFC1157VarBindList varBindList;
	varBindList.list = varBind;
	 
	UINT OID_ifEntryType[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 3 };
	UINT OID_ifEntryNum[] = { 1, 3, 6, 1, 2, 1, 2, 1 };
	UINT OID_ipMACEntAddr[] = { 1, 3, 6, 1, 2, 1, 2, 2, 1, 6 };
	AsnObjectIdentifier MIB_ifMACEntAddr = { sizeof(OID_ipMACEntAddr) / sizeof(UINT), OID_ipMACEntAddr };
	AsnObjectIdentifier MIB_ifEntryType = { sizeof(OID_ifEntryType) / sizeof(UINT), OID_ifEntryType };
	AsnObjectIdentifier MIB_ifEntryNum = { sizeof(OID_ifEntryNum) / sizeof(UINT), OID_ifEntryNum };
 
	// Copy in the OID to find the number of entries in the Inteface table
	varBindList.len = 1;        // Only retrieving one item
	SnmpUtilOidCpy(&varBind[0].name, &MIB_ifEntryNum);
	AsnInteger errorStatus;
	AsnInteger errorIndex;
	f_SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex);
	varBindList.len = 2;
 
	// Copy in the OID of ifType, the type of interface
	SnmpUtilOidCpy(&varBind[0].name, &MIB_ifEntryType);
	 
	// Copy in the OID of ifPhysAddress, the address
	SnmpUtilOidCpy(&varBind[1].name, &MIB_ifMACEntAddr);
	 
	for(int j = 0; j < varBind[0].value.asnValue.number; j  )
	{
		// Submit the query.  Responses will be loaded into varBindList.
		// We can expect this call to succeed a # of times corresponding to the # of adapters reported to be in the system
		if(f_SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex) == FALSE)
			continue;
		// Confirm that the proper type has been returned
		if(SnmpUtilOidNCmp(&varBind[0].name, &MIB_ifEntryType, MIB_ifEntryType.idLength) != 0)
			continue;
		// Type 6 describes ethernet interfaces
		if(varBind[0].value.asnValue.number != 6) 
			continue;
		// Confirm that we have an address here
		if(SnmpUtilOidNCmp(&varBind[1].name, &MIB_ifMACEntAddr, MIB_ifMACEntAddr.idLength) != 0)
			continue;
		if(varBind[1].value.asnValue.address.stream == NULL)
			continue;
		// Ignore all dial-up networking adapters
		if ((varBind[1].value.asnValue.address.stream[0] == 0x44)
		&& (varBind[1].value.asnValue.address.stream[1] == 0x45)
		&& (varBind[1].value.asnValue.address.stream[2] == 0x53)
		&& (varBind[1].value.asnValue.address.stream[3] == 0x54)
		&& (varBind[1].value.asnValue.address.stream[4] == 0x00)) 
			continue;
		// Ignore NULL addresses returned by other network interfaces
		if ((varBind[1].value.asnValue.address.stream[0] == 0x00)
		&& (varBind[1].value.asnValue.address.stream[1] == 0x00)
		&& (varBind[1].value.asnValue.address.stream[2] == 0x00)
		&& (varBind[1].value.asnValue.address.stream[3] == 0x00)
		&& (varBind[1].value.asnValue.address.stream[4] == 0x00)
		&& (varBind[1].value.asnValue.address.stream[5] == 0x00)) 
			continue;
		char buf[32];
		sprintf(buf, "X-X-X-X-X-X",
			varBind[1].value.asnValue.address.stream[0],
			varBind[1].value.asnValue.address.stream[1],
			varBind[1].value.asnValue.address.stream[2],
			varBind[1].value.asnValue.address.stream[3],
			varBind[1].value.asnValue.address.stream[4],
			varBind[1].value.asnValue.address.stream[5]);
		macOUT = buf;
		ret = true;
		break;
	}
	 
	// Free the bindings
	SnmpUtilVarBindFree(&varBind[0]);
	SnmpUtilVarBindFree(&varBind[1]);
	return ret;
}

GetAdaptersInfo

代码语言:javascript复制
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
 
bool GetMacByGetAdaptersInfo(std::string& macOUT)
{
	bool ret = false;
	 
	ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
	PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));
	if(pAdapterInfo == NULL)
		return false;
	// Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable
	if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) 
	{
		free(pAdapterInfo);
		pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);
		if (pAdapterInfo == NULL) 
			return false;
	}
	 
	if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR)
	{
		for(PIP_ADAPTER_INFO pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next)
		{
			// 确保是以太网
			if(pAdapter->Type != MIB_IF_TYPE_ETHERNET)
				continue;
			// 确保MAC地址的长度为 00-00-00-00-00-00
			if(pAdapter->AddressLength != 6)
				continue;
			char acMAC[32];
			sprintf(acMAC, "X-X-X-X-X-X",
				int (pAdapter->Address[0]),
				int (pAdapter->Address[1]),
				int (pAdapter->Address[2]),
				int (pAdapter->Address[3]),
				int (pAdapter->Address[4]),
				int (pAdapter->Address[5]));
			macOUT = acMAC;
			ret = true;
			break;
		}
	}
	 
	free(pAdapterInfo);
	return ret;
}

GetAdaptersAddresses

代码语言:javascript复制
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "IPHLPAPI.lib")
 
bool GetMacByGetAdaptersAddresses(std::string& macOUT)
{
	bool ret = false;
	 
	ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);
	PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
	if (pAddresses == NULL) 
		return false;
	// Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable
	if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
	{
		free(pAddresses);
		pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);
		if (pAddresses == NULL) 
			return false;
	}
	 
	if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)
	{
	// If successful, output some information from the data we received
		for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)
		{
			// 确保MAC地址的长度为 00-00-00-00-00-00
			if(pCurrAddresses->PhysicalAddressLength != 6)
				continue;
			char acMAC[32];
			sprintf(acMAC, "X-X-X-X-X-X",
				int (pCurrAddresses->PhysicalAddress[0]),
				int (pCurrAddresses->PhysicalAddress[1]),
				int (pCurrAddresses->PhysicalAddress[2]),
				int (pCurrAddresses->PhysicalAddress[3]),
				int (pCurrAddresses->PhysicalAddress[4]),
				int (pCurrAddresses->PhysicalAddress[5]));
			macOUT = acMAC;
			ret = true;
			break;
		}
	} 
	 
	free(pAddresses);
	return ret;
}

socket

代码语言:javascript复制
int getMac(char* mac){
    int sockfd;
    struct ifreq tmp;
    char macAddr[30];
 
    sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd<0){
        cout<<"create socket fail"<<endl;
        return -1;
    }
 
    memset(&tmp,0,sizeof(struct ifreq));
 
    strncpy(tmp.ifr_name,"eth0",sizeof(tmp.ifr_name)-1);
 
    if((ioctl(sockfd,SIOCGIFHWADDR,&tmp))<0){
        cout<<"mac ioctl error"<<endl;
        return -1;
    }
 
    sprintf(macAddr,"xxxxxx",
            (unsigned char)tmp.ifr_hwaddr.sa_data[0],
            (unsigned char)tmp.ifr_hwaddr.sa_data[1],
            (unsigned char)tmp.ifr_hwaddr.sa_data[2],
            (unsigned char)tmp.ifr_hwaddr.sa_data[3],
            (unsigned char)tmp.ifr_hwaddr.sa_data[4],
            (unsigned char)tmp.ifr_hwaddr.sa_data[5]
           );
    close(sockfd);
    memcpy(mac,macAddr,strlen(macAddr));
    return 0;
}

SendARP

代码语言:javascript复制
include "stdio.h"
#include "winsock2.h"
#include "iphlpapi.h"
// #pragma comment(lib,"C:Program FilesBorlandCBuilder6LibPsdkiphlpapi.lib")
#pragma comment(lib,"iphlpapi.lib")

int Stat[255];
String IPs[255];
String MACs[255];

#define maxThread 60
Mthread *thread[maxThread]; // 线程地址

String GetMAC(String IP,int & rs) // 取IP地址对应的MAC地址
{
	unsigned char mac[6];
	ULONG MacLen=6;
	ULONG DestIP=inet_addr(IP.c_str());
	rs=SendARP(DestIP,(ULONG)NULL,(PULONG)mac,(PULONG)&MacLen);
	String MACs="";
	if (rs==0)
	{
		char buf[32];
		sprintf(buf,"X-X-X-X-X-X",
		(unsigned int)mac[0],
		(unsigned int)mac[1],
		(unsigned int)mac[2],
		(unsigned int)mac[3],
		(unsigned int)mac[4],
		(unsigned int)mac[5]);
		MACs=buf;
	}
	return(MACs);
}

WMI

代码语言:javascript复制
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#include <string>

#pragma comment(lib, "wbemuuid.lib")

int main(int argc, char **argv)
{
  HRESULT hres;

  // Initialize COM.
  hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
  if (FAILED(hres))
  {
    cout << "Failed to initialize COM library. "
      << "Error code = 0x"
      << hex << hres << endl;
    return 1;              // Program has failed.
  }

  // Initialize 
  hres = CoInitializeSecurity(
    NULL,
    -1,      // COM negotiates service                  
    NULL,    // Authentication services
    NULL,    // Reserved
    RPC_C_AUTHN_LEVEL_DEFAULT,    // authentication
    RPC_C_IMP_LEVEL_IMPERSONATE,  // Impersonation
    NULL,             // Authentication info 
    EOAC_NONE,        // Additional capabilities
    NULL              // Reserved
    );


  if (FAILED(hres))
  {
    cout << "Failed to initialize security. "
      << "Error code = 0x"
      << hex << hres << endl;
    CoUninitialize();
    return 1;          // Program has failed.
  }

  // Obtain the initial locator to Windows Management
  // on a particular host computer.
  IWbemLocator *pLoc = 0;

  hres = CoCreateInstance(
    CLSID_WbemLocator,
    0,
    CLSCTX_INPROC_SERVER,
    IID_IWbemLocator, (LPVOID *)&pLoc);

  if (FAILED(hres))
  {
    cout << "Failed to create IWbemLocator object. "
      << "Error code = 0x"
      << hex << hres << endl;
    CoUninitialize();
    return 1;       // Program has failed.
  }

  IWbemServices *pSvc = 0;

  // Connect to the rootcimv2 namespace with the
  // current user and obtain pointer pSvc
  // to make IWbemServices calls.

  hres = pLoc->ConnectServer(

    _bstr_t(L"ROOT\CIMV2"), // WMI namespace
    NULL,                    // User name
    NULL,                    // User password
    0,                       // Locale
    NULL,                    // Security flags                 
    0,                       // Authority       
    0,                       // Context object
    &pSvc                    // IWbemServices proxy
    );

  if (FAILED(hres))
  {
    cout << "Could not connect. Error code = 0x"
      << hex << hres << endl;
    pLoc->Release();
    CoUninitialize();
    return 1;                // Program has failed.
  }

  cout << "Connected to ROOT\CIMV2 WMI namespace" << endl;

  // Set the IWbemServices proxy so that impersonation
  // of the user (client) occurs.
  hres = CoSetProxyBlanket(

    pSvc,                         // the proxy to set
    RPC_C_AUTHN_WINNT,            // authentication service
    RPC_C_AUTHZ_NONE,             // authorization service
    NULL,                         // Server principal name
    RPC_C_AUTHN_LEVEL_CALL,       // authentication level
    RPC_C_IMP_LEVEL_IMPERSONATE,  // impersonation level
    NULL,                         // client identity 
    EOAC_NONE                     // proxy capabilities     
    );

  if (FAILED(hres))
  {
    cout << "Could not set proxy blanket. Error code = 0x"
      << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
  }


  // Use the IWbemServices pointer to make requests of WMI. 
  // Make requests here:

  // For example, query for all the running processes
  IEnumWbemClassObject* pEnumerator = NULL;
  hres = pSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_NetworkAdapter"),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &pEnumerator);

  if (FAILED(hres))
  {
    cout << "Query for processes failed. "
      << "Error code = 0x"
      << hex << hres << endl;
    pSvc->Release();
    pLoc->Release();
    CoUninitialize();
    return 1;               // Program has failed.
  }
  else
  {
    IWbemClassObject *pclsObj;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
      hres = pEnumerator->Next(WBEM_INFINITE, 1,
        &pclsObj, &uReturn);
      if (0 == uReturn)
      {
        break;
      }

      VARIANT vtProp;
      VARIANT vtProp2;

      // Get the value of the Name property
      hres = pclsObj->Get(L"Description", 0, &vtProp, 0, 0);
      WCHAR* des;  
      des = vtProp.bstrVal;

      hres = pclsObj->Get(L"MACAddress", 0, &vtProp2, 0, 0);
      WCHAR* mac;
      mac = vtProp2.bstrVal;

      if (mac != NULL && des != NULL)
      {
        wcout << "Description: " << des << endl;
        wcout << "Description: " << mac << endl;
      }


      VariantClear(&vtProp);
      VariantClear(&vtProp2);
    }

  }

  // Cleanup
  // ========

  pSvc->Release();
  pLoc->Release();
  CoUninitialize();

  return 0;
}

0 人点赞