c++通过mac地址 获取 设备UUID

来源:互联网 发布:淘宝上如何找真弩 编辑:程序博客网 时间:2024/04/28 12:28

(注:仅支持pc端的设备UUID获取,不支持android和ios移动设备UUID的获取)

原料:vs2013+cocos2dx3.3+openssl+macaddr.h/cpp

第一步:

下载好OpenSSL,导入openssl文件夹到工程目录下
导入macaddr.h和macaddr.cpp到工程

头文件macaddr.h

#ifndef __MACADDR_H__#define __MACADDR_H__#include <windows.h>#define MACADDRESS_BYTELEN  6                       // MAC地址字节长度typedef struct _MACADDRESS{    BYTE    SrcMacAddr[MACADDRESS_BYTELEN];         // 原生MAC地址    BYTE    CurMacAddr[MACADDRESS_BYTELEN];         // 当前MAC地址} MACADDRESS;#ifdef __cplusplusextern "C"{#endif    /*    */    /*        功能     : 结合WMI和DeviceIoControl获取网卡原生MAC地址和当前MAC地址        入口参数  :                   iQueryType  需要获取的网卡类型                               0 : 包括USB网卡                               1 : 不包括USB网卡                   pMacAddress 存储网卡MAC地址                   uSize       可存储的最大网卡数目        返回值:                   -1  不支持的设备属性值                   -2  WMI连接失败                   -3  不正确的WQL查询语句                   >=0 获取的网卡数目    */    INT WDK_MacAddress(INT iQueryType, MACADDRESS * pMacAddress, INT iSize);#ifdef __cplusplus}#endif#endif

实现文件macaddr.cpp

#include <tchar.h>#include <strsafe.h>#include <algorithm>#include "macaddr.h"#ifdef __cplusplusextern "C"{#endif#include <ntddndis.h>#include <setupapi.h>#include <hidsdi.h>#ifdef __cplusplus}#endif#pragma comment (lib, "setupapi")#pragma comment (lib, "hid")const GUID GUID_QUERYSET[] = {    // 网卡原生MAC地址(包含USB网卡)    {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C},    // 网卡原生MAC地址(剔除USB网卡)    {0xAD498944, 0x762F, 0x11D0, 0x8D, 0xCB, 0x00, 0xC0, 0x4F, 0xC3, 0x35, 0x8C},};// 获取网卡原生MAC地址static BOOL WDK_GetMacAddress(TCHAR * DevicePath, MACADDRESS * pMacAddress, INT iIndex, BOOL isIncludeUSB){    HANDLE  hDeviceFile;    BOOL    isOK = FALSE;    // 剔除虚拟网卡    if (_tcsnicmp(DevicePath + 4, TEXT("root"), 4) == 0)    {        return FALSE;    }    if (!isIncludeUSB)    {   // 剔除USB网卡        if (_tcsnicmp(DevicePath + 4, TEXT("usb"), 4) == 0)        {            return FALSE;        }    }    // 获取设备句柄    hDeviceFile = CreateFile(DevicePath,                             0,                             FILE_SHARE_READ | FILE_SHARE_WRITE,                             NULL,                             OPEN_EXISTING,                             0,                             NULL);    if (hDeviceFile != INVALID_HANDLE_VALUE)    {        ULONG   dwID;        BYTE    ucData[8];        DWORD   dwByteRet;        // 获取当前MAC地址        dwID = OID_802_3_CURRENT_ADDRESS;        isOK = DeviceIoControl(hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL);        if (isOK)        {            memcpy(pMacAddress[iIndex].CurMacAddr, ucData, dwByteRet);            // 获取原生MAC地址            dwID = OID_802_3_PERMANENT_ADDRESS;            isOK = DeviceIoControl(hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, &dwID, sizeof(dwID), ucData, sizeof(ucData), &dwByteRet, NULL);            if (isOK)            {                memcpy(pMacAddress[iIndex].SrcMacAddr, ucData, dwByteRet);            }        }        CloseHandle(hDeviceFile);    }    return isOK;}static BOOL WDK_GetProperty(TCHAR* DevicePath, INT iQueryType, MACADDRESS *pMacAddress, INT iIndex){    BOOL isOK = FALSE;    switch (iQueryType)    {        case 0:     // 网卡原生MAC地址(包含USB网卡)                   isOK = WDK_GetMacAddress(DevicePath, pMacAddress, iIndex, TRUE);            break;        case 1:     // 网卡原生MAC地址(剔除USB网卡)                   isOK = WDK_GetMacAddress(DevicePath, pMacAddress, iIndex, FALSE);            break;        default:            break;    }    return isOK;}INT WDK_MacAddress(INT iQueryType, MACADDRESS * pMacAddress, INT iSize){    HDEVINFO hDevInfo;    DWORD MemberIndex, RequiredSize;    SP_DEVICE_INTERFACE_DATA            DeviceInterfaceData;    PSP_DEVICE_INTERFACE_DETAIL_DATA    DeviceInterfaceDetailData;    INT iTotal = 0;    // 判断查询类型是否支持    if ((iQueryType < 0) || (iQueryType >= sizeof(GUID_QUERYSET) / sizeof(GUID)))    {        return -2;  // 查询类型不支持    }    // 获取设备信息集    hDevInfo = SetupDiGetClassDevs(GUID_QUERYSET + iQueryType, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);    if (hDevInfo == INVALID_HANDLE_VALUE)    {        return -1;    }    // 枚举设备信息集中所有设备    DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);    for (MemberIndex = 0; ((pMacAddress == NULL) || (iTotal < iSize)); MemberIndex++)    {   // 获取设备接口        if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, GUID_QUERYSET + iQueryType, MemberIndex, &DeviceInterfaceData))        {   // 设备枚举完毕            break;        }        // 获取接收缓冲区大小,函数返回值为FALSE,GetLastError()=ERROR_INSUFFICIENT_BUFFER        SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, NULL, 0, &RequiredSize, NULL);        // 申请接收缓冲区        DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(RequiredSize);        DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);        // 获取设备细节信息        if (SetupDiGetDeviceInterfaceDetail(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL))        {            if (pMacAddress != NULL)            {                if (WDK_GetProperty(DeviceInterfaceDetailData->DevicePath, iQueryType, pMacAddress, iTotal))                {                    iTotal++;                }            }            else            {                iTotal++;            }        }        free(DeviceInterfaceDetailData);    }    SetupDiDestroyDeviceInfoList(hDevInfo);    return iTotal;}

第二步:

main代码调用出:

/*缺省通用头文件,自己添加。比如:#include <stdio.h>等*/#include "openssl/md5.h"#include "macaddr.h"// openssl library#pragma comment(lib, "libeay32")int main(){    MACADDRESS macaddr = { 0 };    MD5_CTX md5ctx = { 0 };    uint8_t md[16] = { 0 };    char mac[128] = { 0 }; //测试mac地址(MAC地址就如同我们身份证上的身份证号码,具有全球唯一性)    char g_deviceuuid[260] = { 0 };//根据mac地址 获取 设备UUID    if (WDK_MacAddress(1, &macaddr, 1) < 1)        return -1;    sprintf(mac, "src mac : ");    for (int i = 0; i < 6; i++)        sprintf(mac + 10 + i * 2, "%02X ", macaddr.SrcMacAddr[i]);    sprintf(mac + 22, "\ncur mac : ");    for (int i = 0; i < 6; i++)        sprintf(mac + 33 + i * 2, "%02X", macaddr.CurMacAddr[i]);    sprintf(mac + 45, "\n");    if (MD5_Init(&md5ctx) < 0)        return -1;    if (MD5_Update(&md5ctx, macaddr.SrcMacAddr, sizeof(macaddr.SrcMacAddr)) < 0)    {        MD5_Final(nullptr, &md5ctx);        return -1;    }    if (MD5_Final((unsigned char *)md, &md5ctx) < 0)        return -1;    for (int i = 0; i < 16; i++)        sprintf(g_deviceuuid + i * 2, "%02X", md[i]);    CCLOG("======>[%s]", g_deviceuuid);    return 0}

最终:日志输出串就是设备UUID:======>[65C5459D3A2CC565F96A5223C85BC576 ]

**

第三步:

**
工程配置
1).拷贝openssl\bin\win32下的 libeay32.dll 到 Debug.win32(如果Release版本是Release.win32)目录下

2).配置 -> c/c++ -> 附加包含目录:..\openssl\include
3).配置 -> c/c++ -> 附加包含目录:C:\Program Files %28x86%29\Windows Kits\8.1\Include\shared
4).配置 -> 链接器 -> 附加库目录: C:\Program Files %28x86%29\Windows Kits\8.1\Lib\winv6.3\um\x86 和 ..\openssl\lib\win32

0 0
原创粉丝点击