windows获取物理mac地址

直接调用windows的接口获取mac地址,当系统安装了VMWARE 虚拟机,虚拟机创建的网卡的地址也被认为是mac地址。这个时候需要通过注册表将物理mac地址和虚拟mac地址区分出来。

#include <Windows.h>

#include "iphLpapi.h"

#pragma comment(lib, "IPHLPAPI.lib")
std::string getMac()
{
    std::string name;
    if (!getPhysicalMacName(name))
    {
        return "";
    }
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter = NULL;
    DWORD dwRetVal = 0;

    ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);
    pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(sizeof(IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL) {
        return "";
    }
    // 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 "";
        }
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
        pAdapter = pAdapterInfo;
        while (pAdapter) {
            if (MIB_IF_TYPE_ETHERNET == pAdapter->Type && !name.compare(pAdapter->AdapterName))
            {
                FREE(pAdapterInfo);
                return byte2UTF8(pAdapter->Address, pAdapter->AddressLength);
            }            
            pAdapter = pAdapter->Next;
        }
    }
    if (pAdapterInfo)
        FREE(pAdapterInfo);
    return "";

}

int getPhysicalMacName(std::string& name)
{
    HKEY key;
    TCHAR szDataBuf[MAX_PATH + 1] = {0};    
    DWORD dwDataLen = MAX_PATH;
    DWORD dwType = REG_SZ;
    HKEY hNetKey = NULL;
    HKEY hLocalNet = NULL;
    TCHAR netCfgInstanceIdBuff[512 + 1] = { 0 };
    DWORD netCfgInstanceIdlength = 512;
    DWORD netCfgInstanceId_type = REG_SZ;

    int index = 0;
    

    if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}", 0, KEY_READ, &key))
    {
        return 0;
    }

    while (true)
    {
        std::wstring sub_key = L"000";
        sub_key.append(UTF82WC(std::to_string(index)));
        if (ERROR_SUCCESS != RegOpenKeyEx(key, sub_key.c_str(), 0, KEY_READ, &hLocalNet))
        {
            RegCloseKey(key);
            RegCloseKey(hLocalNet);
            return 0;
        }
        memset(szDataBuf, 0, sizeof(szDataBuf[0]));
        if (ERROR_SUCCESS == RegQueryValueEx(hLocalNet, L"Characteristics", 0, &dwType, (BYTE *)szDataBuf, &dwDataLen))
        {
            if (*((DWORD *)szDataBuf) & 0x4) //0x04是物理网卡
            {
                if (ERROR_SUCCESS == RegQueryValueEx(hLocalNet, L"NetCfgInstanceId", 0, &netCfgInstanceId_type, (BYTE *)netCfgInstanceIdBuff, &netCfgInstanceIdlength))
                {
                    name =         WC2UTF8(netCfgInstanceIdBuff);
                    RegCloseKey(key);
                    RegCloseKey(hLocalNet);
                    return 1;
                }
            }
        }
        index++;
    }
    RegCloseKey(key);
    RegCloseKey(hLocalNet);
    return 0;
}

std::wstring UTF82WC(const std::string &utf8)
{
    int lenWC = ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), static_cast<int>(utf8.length()), NULL, 0);
    std::unique_ptr<wchar_t> wc(new wchar_t[lenWC]());
    ::MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), static_cast<int>(utf8.length()), wc.get(), lenWC);
    return std::wstring(wc.get(), lenWC);
}

std::string byte2UTF8(unsigned char* byte_arr, int arr_len)
{
    std::string hexstr;
    //
    for (int i = 0; nullptr != byte_arr && i < arr_len; ++i)
    {
        char hex1;
        char hex2;

        /*借助C++支持的unsigned和int的强制转换,把unsigned char赋值给int的值,那么系统就会自动完成强制转换*/
        int value = byte_arr[i];
        int S = value / 16;
        int Y = value % 16;

        //将C++中unsigned char和int的强制转换得到的商转成字母
        if (S >= 0 && S <= 9)
        {
            hex1 = (char)(48 + S);
        }
        else
        {
            hex1 = (char)(55 + S);
        }

        //将C++中unsigned char和int的强制转换得到的余数转成字母
        if (Y >= 0 && Y <= 9)
        {
            hex2 = (char)(48 + Y);
        }
        else
        {
            hex2 = (char)(55 + Y);
        }

        //最后一步的代码实现,将所得到的两个字母连接成字符串达到目的
        hexstr = hexstr + hex1 + hex2;
    }

    return hexstr;
}
原文地址:https://www.cnblogs.com/devil-shadow/p/12794592.html