QQ登录

只需一步,快速开始

搜索
查看: 3815|回复: 1

[C/C++] VC++获取系统信息/获取OS/获取MAC/获取本地IP/判断是否为网吧

[复制链接]

192

积分

15

主题

2

精华

版主

Rank: 7Rank: 7Rank: 7

违规
0 点
JmPoint
7923 点
声望
17 点
赏金币
6 枚
发单信誉
0
接单信誉
0
注册时间
2015-7-25
最后登录
2017-6-12
在线时间
126 小时
发表于 2016-5-28 16:51:39 | 显示全部楼层 |阅读模式
本帖最后由 sunflover 于 2016-5-28 17:08 编辑

现在很多软件都有统计系统了,说好听点叫做统计用户习惯,改良产品,不好听点,呵呵,我就不说了。
核心我已经封装成类了,可以获取操作系统版本,MAC地址,本地IP地址,以及判定是否为网吧。
核心代码如下:
[C++] 纯文本查看 复制代码
//PCInfo.h

#pragma once
#include <string>

class CPCInfo
{
public:
        CPCInfo(void);
        ~CPCInfo(void);
private:
        // 获取MAC地址
        std::string& GetMAC();
        // 获取IP地址
        std::string& GetIP();
        // 获取操作系统
        std::string& GetOS();
        // 是否为网吧
        bool IsInternetBar();
public:
        std::string m_strIP;
        std::string m_strMAC;
        std::string m_strOS;
        bool m_bIsInternetBar;
};


[C++] 纯文本查看 复制代码
//PCInfo.cpp

#include "PCInfo.h"
#include <winsock2.h>
#include <Iphlpapi.h>
#pragma  comment(lib,"Iphlpapi.lib")
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")


using std::string;

void byte2Hex(unsigned char bData,unsigned char hex[])
{
        int high=bData/16,low =bData %16;
        hex[0] = (high <10)?('0'+high):('A'+high-10);
        hex[1] = (low <10)?('0'+low):('A'+low-10);
}

bool getLocalMac1(unsigned char *mac) //获取本机MAC址 
{
        ULONG ulSize=0;
        PIP_ADAPTER_INFO pInfo=NULL;
        int temp = GetAdaptersInfo(pInfo,&ulSize);//第一处调用,获取缓冲区大小
        pInfo=(PIP_ADAPTER_INFO)malloc(ulSize);
        temp = GetAdaptersInfo(pInfo,&ulSize);
        int iCount=0;
        while(pInfo)//遍历每一张网卡
        {
                //  pInfo->Address MAC址
                for(int i=0;i<(int)pInfo->AddressLength;i++)
                {
                        byte2Hex(pInfo->Address[i],&mac[iCount]);[/i]
[i]                        iCount+=2;[/i]
[i]                        if(i<(int)pInfo->AddressLength-1)[/i]
[i]                        {[/i]
[i]                                mac[iCount++] = ':';[/i]
[i]                        }[/i]
[i]                        else[/i]
[i]                        {[/i]
[i]                                mac[iCount++] = '#';[/i]
[i]                        }[/i]
[i]                }[/i]
[i]                break;[/i]
[i]                pInfo = pInfo->Next;[/i]
[i]        }[/i]
[i]        free(pInfo);[/i]

[i]        if(iCount >0)[/i]
[i]        {[/i]
[i]                mac[--iCount]='\0';[/i]
[i]                return true;[/i]
[i]        }[/i]
[i]        else[/i]
[i]        {[/i]
[i]                return false;[/i]
[i]        }[/i]
[i]}[/i]


[i]//通过GetAdaptersInfo函数(适用于Windows 2000及以上版本)[/i]
[i]bool getLocalMac2(unsigned char *mac)[/i]
[i]{[/i]
[i]        bool ret = false;[/i]
[i]        ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO);[/i]
[i]        PIP_ADAPTER_INFO pAdapterInfo = (IP_ADAPTER_INFO*)malloc(sizeof(IP_ADAPTER_INFO));[/i]
[i]        if(pAdapterInfo == NULL)[/i]
[i]                return false;[/i]
[i]        // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable[/i]
[i]        if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) [/i]
[i]        {[/i]
[i]                free(pAdapterInfo);[/i]
[i]                pAdapterInfo = (IP_ADAPTER_INFO *)malloc(ulOutBufLen);[/i]
[i]                if (pAdapterInfo == NULL) [/i]
[i]                        return false;[/i]
[i]        }[/i]
[i]        if(GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == NO_ERROR)[/i]
[i]        {[/i]
[i]                for(PIP_ADAPTER_INFO pAdapter = pAdapterInfo; pAdapter != NULL; pAdapter = pAdapter->Next)[/i]
[i]                {[/i]
[i]                        // 确保是以太网[/i]
[i]                        if(pAdapter->Type != MIB_IF_TYPE_ETHERNET)[/i]
[i]                                continue;[/i]
[i]                        // 确保MAC地址的长度为 00-00-00-00-00-00[/i]
[i]                        if(pAdapter->AddressLength != 6)[/i]
[i]                                continue;[/i]
[i]                        char acMAC[20] = {0};[/i]
[i]                        sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",[/i]
[i]                                int (pAdapter->Address[0]),[/i]
[i]                                int (pAdapter->Address[1]),[/i]
[i]                                int (pAdapter->Address[2]),[/i]
[i]                                int (pAdapter->Address[3]),[/i]
[i]                                int (pAdapter->Address[4]),[/i]
[i]                                int (pAdapter->Address[5]));[/i]
[i]                        memcpy(mac,acMAC,20);[/i]
[i]                        ret = true;[/i]
[i]                        break;[/i]
[i]                }[/i]
[i]        }[/i]
[i]        free(pAdapterInfo);[/i]
[i]        return ret;[/i]
[i]}[/i]


[i]//通过GetAdaptersAddresses函数(适用于Windows XP及以上版本)[/i]
[i]bool getLocalMac3(unsigned char *mac)[/i]
[i]{[/i]
[i]        bool ret = false;[/i]
[i]        ULONG outBufLen = sizeof(IP_ADAPTER_ADDRESSES);[/i]
[i]        PIP_ADAPTER_ADDRESSES pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);[/i]
[i]        if (pAddresses == NULL) [/i]
[i]                return false;[/i]
[i]        // Make an initial call to GetAdaptersAddresses to get the necessary size into the ulOutBufLen variable[/i]
[i]        if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)[/i]
[i]        {[/i]
[i]                free(pAddresses);[/i]
[i]                pAddresses = (IP_ADAPTER_ADDRESSES*)malloc(outBufLen);[/i]
[i]                if (pAddresses == NULL) [/i]
[i]                        return false;[/i]
[i]        }[/i]

[i]        if(GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAddresses, &outBufLen) == NO_ERROR)[/i]
[i]        {[/i]
[i]                // If successful, output some information from the data we received[/i]
[i]                for(PIP_ADAPTER_ADDRESSES pCurrAddresses = pAddresses; pCurrAddresses != NULL; pCurrAddresses = pCurrAddresses->Next)[/i]
[i]                {[/i]
[i]                        // 确保MAC地址的长度为 00-00-00-00-00-00[/i]
[i]                        if(pCurrAddresses->PhysicalAddressLength != 6)[/i]
[i]                                continue;[/i]
[i]                        char acMAC[20] = {0};[/i]
[i]                        sprintf(acMAC, "%02X:%02X:%02X:%02X:%02X:%02X",[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[0]),[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[1]),[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[2]),[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[3]),[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[4]),[/i]
[i]                                int (pCurrAddresses->PhysicalAddress[5]));[/i]
[i]                        memcpy(mac,acMAC,20);[/i]
[i]                        ret = true;[/i]
[i]                        break;[/i]
[i]                }[/i]
[i]        } [/i]
[i]        free(pAddresses);[/i]
[i]        return ret;[/i]
[i]}[/i]



[i]bool GetLocalIP(char* ip)[/i]
[i]{[/i]
[i]        //1.初始化wsa[/i]
[i]        WSADATA wsaData;[/i]
[i]        int ret=WSAStartup(MAKEWORD(2,2),&wsaData);[/i]
[i]        if (ret!=0)[/i]
[i]        {[/i]
[i]                return false;[/i]
[i]        }[/i]
[i]        //2.获取主机名[/i]
[i]        char hostname[256];[/i]
[i]        ret=gethostname(hostname,sizeof(hostname));[/i]
[i]        if (ret==SOCKET_ERROR)[/i]
[i]        {[/i]
[i]                return false;[/i]
[i]        }[/i]
[i]        //3.获取主机ip[/i]
[i]        HOSTENT* host=gethostbyname(hostname);[/i]
[i]        if (host==NULL)[/i]
[i]        {[/i]
[i]                return false;[/i]
[i]        }[/i]
[i]        //4.转化为char*并拷贝返回[/i]
[i]        strcpy(ip,inet_ntoa(*(in_addr*)*host->h_addr_list));[/i]
[i]        return true;[/i]
[i]}[/i]


[i]CPCInfo::CPCInfo(void)[/i]
[i]:m_bIsInternetBar(false)[/i]
[i]{[/i]
[i]        m_strIP = GetIP();[/i]
[i]        m_strMAC = GetMAC();[/i]
[i]        m_strOS = GetOS();[/i]
[i]        m_bIsInternetBar = IsInternetBar();[/i]
[i]}[/i]

[i]//读取操作系统的名称[/i]
[i]string GetSystemName()[/i]
[i]{[/i]
[i]        SYSTEM_INFO info;        //用SYSTEM_INFO结构判断64位AMD处理器 [/i]
[i]        GetSystemInfo(&info);    //调用GetSystemInfo函数填充结构 [/i]
[i]        OSVERSIONINFOEX os; [/i]
[i]        os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);   [/i]

[i]        string osname = "unknown OperatingSystem.";[/i]

[i]        if(GetVersionEx((OSVERSIONINFO *)&os))[/i]
[i]        { [/i]
[i]                //下面根据版本信息判断操作系统名称 [/i]
[i]                switch(os.dwMajorVersion)//判断主版本号[/i]
[i]                {[/i]
[i]                case 4:[/i]
[i]                        switch(os.dwMinorVersion)//判断次版本号 [/i]
[i]                        { [/i]
[i]                        case 0:[/i]
[i]                                if(os.dwPlatformId==VER_PLATFORM_WIN32_NT)[/i]
[i]                                        osname = "Microsoft Windows NT 4.0"; //1996年7月发布 [/i]
[i]                                else if(os.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS)[/i]
[i]                                        osname = "Microsoft Windows 95";[/i]
[i]                                break;[/i]
[i]                        case 10:[/i]
[i]                                osname = "Microsoft Windows 98";[/i]
[i]                                break;[/i]
[i]                        case 90:[/i]
[i]                                osname = "Microsoft Windows Me";[/i]
[i]                                break;[/i]
[i]                        }[/i]
[i]                        break;[/i]

[i]                case 5:[/i]
[i]                        switch(os.dwMinorVersion)        //再比较dwMinorVersion的值[/i]
[i]                        { [/i]
[i]                        case 0:[/i]
[i]                                osname = "Microsoft Windows 2000";//1999年12月发布[/i]
[i]                                break;[/i]

[i]                        case 1:[/i]
[i]                                osname = "Microsoft Windows XP";//2001年8月发布[/i]
[i]                                break;[/i]

[i]                        case 2:[/i]
[i]                                if(os.wProductType==VER_NT_WORKSTATION [/i]
[i]                                        && info.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)[/i]
[i]                                {[/i]
[i]                                        osname = "Microsoft Windows XP Professional x64 Edition";[/i]
[i]                                }[/i]
[i]                                else if(GetSystemMetrics(SM_SERVERR2)==0)[/i]
[i]                                        osname = "Microsoft Windows Server 2003";//2003年3月发布 [/i]
[i]                                else if(GetSystemMetrics(SM_SERVERR2)!=0)[/i]
[i]                                        osname = "Microsoft Windows Server 2003 R2";[/i]
[i]                                break;[/i]
[i]                        }[/i]
[i]                        break;[/i]

[i]                case 6:[/i]
[i]                        switch(os.dwMinorVersion)[/i]
[i]                        {[/i]
[i]                        case 0:[/i]
[i]                                if(os.wProductType == VER_NT_WORKSTATION)[/i]
[i]                                        osname = "Microsoft Windows Vista";[/i]
[i]                                else[/i]
[i]                                        osname = "Microsoft Windows Server 2008";//服务器版本 [/i]
[i]                                break;[/i]
[i]                        case 1:[/i]
[i]                                if(os.wProductType == VER_NT_WORKSTATION)[/i]
[i]                                        osname = "Microsoft Windows 7";[/i]
[i]                                else[/i]
[i]                                        osname = "Microsoft Windows Server 2008 R2";[/i]
[i]                                break;[/i]
[i]                        case 2:[/i]
[i]                                if(os.wProductType == VER_NT_WORKSTATION)[/i]
[i]                                        osname = "Microsoft Windows 8";[/i]
[i]                                else[/i]
[i]                                        osname = "Microsoft Windows Server 2012";[/i]
[i]                                break;[/i]
[i]                        case 3:[/i]
[i]                                if(os.wProductType == VER_NT_WORKSTATION)[/i]
[i]                                        osname = "Microsoft Windows 8.1";[/i]
[i]                                else[/i]
[i]                                        osname = "Microsoft Windows Server 2012 R2";[/i]
[i]                                break;[/i]
[i]                        }[/i]
[i]                        break;[/i]

[i]                case 10:[/i]
[i]                        switch(os.dwMinorVersion)[/i]
[i]                        {[/i]
[i]                        case 0:[/i]
[i]                                if(os.wProductType == VER_NT_WORKSTATION)[/i]
[i]                                        osname = "Microsoft Windows 10";[/i]
[i]                                else[/i]
[i]                                        osname = "Microsoft Windows Server 2016 Technical Preview";//服务器版本 [/i]
[i]                                break;[/i]
[i]                        }[/i]
[i]                        break;[/i]
[i]                }[/i]
[i]        }//if(GetVersionEx((OSVERSIONINFO *)&os))[/i]
[i]        //https://msdn.microsoft.com/en-us/library/ms724832.aspx[/i]
[i]        return osname;[/i]
[i]} [/i]


[i]CPCInfo::~CPCInfo(void)[/i]
[i]{[/i]
[i]}[/i]


[i]// 获取MAC地址[/i]
[i]string& CPCInfo::GetMAC()[/i]
[i]{[/i]
[i]        unsigned char szMac[20] = {0};[/i]
[i]        //为了确保获取到MAC地址,通过三种方式来获取[/i]
[i]        if(!getLocalMac3(szMac))[/i]
[i]        {[/i]
[i]                if(!getLocalMac2(szMac))[/i]
[i]                {[/i]
[i]                        getLocalMac1(szMac);[/i]
[i]                }[/i]
[i]        }[/i]
[i]        m_strMAC.empty();[/i]
[i]        m_strMAC.append((const char*)szMac,sizeof(szMac));[/i]

[i]        return m_strMAC;[/i]
[i]}[/i]

[i]// 获取IP地址[/i]
[i]string& CPCInfo::GetIP()[/i]
[i]{[/i]
[i]        char ip[30] = {'\0'};[/i]
[i]        if (GetLocalIP(ip))[/i]
[i]        {[/i]
[i]                m_strIP.empty();[/i]
[i]                m_strIP.append(ip,sizeof(ip));[/i]
[i]        }[/i]

[i]        return m_strIP;[/i]
[i]}[/i]

[i]// 获取操作系统[/i]
[i]string& CPCInfo::GetOS()[/i]
[i]{[/i]
[i]        m_strOS = GetSystemName();[/i]

[i]        return m_strOS;[/i]
[i]}[/i]

[i]bool IsHaveKey(HKEY hKey, char* lpSubKey)[/i]
[i]{[/i]
[i]        HKEY phkResult = 0;        [/i]
[i]        if (ERROR_SUCCESS == RegOpenKeyExA(hKey, lpSubKey, 0, KEY_QUERY_VALUE, &phkResult))[/i]
[i]        {[/i]
[i]                RegCloseKey(phkResult);[/i]
[i]                return true;[/i]
[i]        }[/i]
[i]        return false;[/i]
[i]}[/i]

[i]// 是否为网吧[/i]
[i]bool CPCInfo::IsInternetBar()[/i]
[i]{[/i]
[i]        char* NetRoomKey[] =[/i]
[i]        {[/i]
[i]                "SOFTWARE\\Hintsoft\\PubwinClient",[/i]
[i]                "SOFTWARE\\Hintsoft\\pubwin",[/i]
[i]                "SOFTWARE\\Sicent\\wx2004Clt",[/i]
[i]                "SOFTWARE\\MpSoft\\smenu",[/i]
[i]                "SOFTWARE\\Microsoft\\jingzu",[/i]
[i]                "SOFTWARE\\iCafe8",[/i]
[i]                "SOFTWARE\\Goyoo\\i8desk",[/i]
[i]                "SOFTWARE\\Hintsoft1\\XunShanPro",[/i]
[i]                "SOFTWARE\\SyncExpertNetBar",[/i]
[i]                "SOFTWARE\\EYOOCLIENTSTATUS",[/i]
[i]                "SOFTWARE\\Richtech",[/i]
[i]                "SOFTWARE\\\u676d\u5dde\u987a\u7f51\u4fe1\u606f\u6280\u672f\u6709\u9650\u516c\u53f8\\\u7f51\u7ef4\u5927\u5e08\u874c\u86aa\u5a31\u4e50\u5e73\u53f0",[/i]
[i]                "SOFTWARE\\iCafe8",[/i]
[i]                "SOFTWARE\\Sicent\\wx2004Clt",[/i]
[i]                "SOFTWARE\\Sicent\\WxAdv",[/i]
[i]                "SOFTWARE\\Grabsun\\Netsense",[/i]
[i]        };[/i]

[i]        for (int i = 0; i < sizeof(NetRoomKey) / sizeof(char*); i++)[/i]
[i]        {[/i]
[i]                if (IsHaveKey(HKEY_LOCAL_MACHINE, NetRoomKey))[/i]
[i]                {[/i]
[i]                        m_bIsInternetBar = true;[/i]
[i]                        break;[/i]
[i]                }[/i]
[i]        }[/i]

[i]        return m_bIsInternetBar;[/i]
[i]}

有个使用注意事项,不注意会导致Win8以上系统获取到的操作系统信息错误
具体注意事项在这篇文章中有详细说明:http://www.jmpoep.com/thread-1564-1-1.html
执行结果如下:

测试工程为VS2010 MFC项目:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即加入

x

评分

参与人数 1JmPoint +10 声望 +1 +1 收起 理由
B1nGzL + 10 + 1 + 1 零日安全有你更精彩。

查看全部评分

just for fun!
博客地址:http://blog.csdn.net/sunflover454/article/
回复

使用道具 举报

72

积分

9

主题

0

精华

正式会员

Rank: 1

违规
0 点
JmPoint
600 点
声望
10 点
赏金币
0 枚
发单信誉
0
接单信誉
0
注册时间
2016-5-15
最后登录
2017-10-21
在线时间
97 小时
发表于 2016-7-9 23:41:10 | 显示全部楼层
来膜拜一下
回复 支持 反对

使用道具 举报

*滑动验证:
您需要登录后才可以回帖 登录 | 立即加入

本版积分规则

关闭

站长推荐上一条 /2 下一条

QQ|Archiver|手机版|小黑屋|零日安全论坛 ( 吉ICP备15004039号 点击这里给我发消息

GMT+8, 2017-10-23 12:29 , Processed in 0.174056 second(s), 33 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表