C/C++应用--Window下获取硬件信息(CPU, 硬盘,网卡等)

一、头文件如下:

#include <Windows.h>
#include <string>
#include <iostream>
#include <winnt.h>
#include <tchar.h>  
#include <IPHlpApi.h>
#pragma comment(lib,"ws2_32.lib") 
#pragma comment(lib,"Advapi32.lib") 
#pragma comment(lib, "Iphlpapi.lib")
using namespace std;

// ***** global macros ***** //
#define  GBYTES  1073741824  
#define  MBYTES  1048576  
#define  KBYTES  1024  
#define  DKBYTES 1024.0  

class CSysInfo
{
public:
    CSysInfo();
    ~CSysInfo();

public:
    const std::string GetOSVersion();
    void SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo);
    const std::string GetCPUInfo();
    const std::string GetMemoryStatus();

    void GetNetCardAndIPInfo(std::string &adapter_info, std::string &MAC_address, std::string &IP);
    const std::string GetComputerUserName();
    BOOL GetHardDiskInfo(LPTSTR pModelNo, LPTSTR pSerialNo);
    void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf);

};

二、cpp如下:

#include "SysInfo.h"



CSysInfo::CSysInfo()
{
}


CSysInfo::~CSysInfo()
{
}

const std::string CSysInfo::GetOSVersion()
{
    std::string os_version("");
    SYSTEM_INFO system_info;
    memset(&system_info, 0, sizeof(SYSTEM_INFO));
    GetSystemInfo(&system_info);
    OSVERSIONINFOEX os;
    os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    if (GetVersionEx((OSVERSIONINFO *)&os))
    {
        switch (os.dwMajorVersion) {
        case 4:
            //1996年7月发布 
            switch (os.dwMinorVersion) {
            case 0:
                if (os.dwPlatformId == VER_PLATFORM_WIN32_NT)
                    os_version = "Microsoft Windows NT 4.0 ";
                else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
                    os_version = "Microsoft Windows 95 ";
                break;
            case 10:
                os_version = "Microsoft Windows 98 ";
                break;
            case 90:
                os_version = "Microsoft Windows Me ";
                break;
            }
            break;
        case 5:
            switch (os.dwMinorVersion) {
                //1999年12月发布 
            case 0:
                os_version = "Microsoft Windows 2000 ";
                if (os.wSuiteMask == VER_SUITE_ENTERPRISE)
                    os_version.append("Advanced Server ");
                break;
                //2001年8月发布 
            case 1:
                os_version = "Microsoft Windows XP ";
                if (os.wSuiteMask == VER_SUITE_EMBEDDEDNT)
                    os_version.append("Embedded ");
                else if (os.wSuiteMask == VER_SUITE_PERSONAL)
                    os_version.append("Home Edition ");
                else
                    os_version.append("Professional ");
                break;
            case 2:
                if (os.wProductType == VER_NT_WORKSTATION &&
                    system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
                    os_version = "Microsoft Windows XP Professional x64 Edition ";
                if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_BLADE)
                    os_version = "Microsoft Windows Server 2003 Web Edition ";
                else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_COMPUTE_SERVER)
                    os_version = ("Microsoft Windows Server 2003 Compute Cluster Edition ");
                else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_STORAGE_SERVER)
                    os_version = ("Microsoft Windows Server 2003 Storage Server ");
                else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_DATACENTER)
                    os_version = ("Microsoft Windows Server 2003 Datacenter Edition ");
                else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_ENTERPRISE)
                    os_version = ("Microsoft Windows Server 2003 Enterprise Edition ");
                else if (GetSystemMetrics(SM_SERVERR2) != 0 && os.wSuiteMask == VER_SUITE_STORAGE_SERVER)
                    os_version = ("Microsoft Windows Server 2003 R2 Storage Server ");
                break;
            }
            break;
        case 6:
            switch (os.dwMinorVersion) {
            case 0:
                if (os.wProductType == VER_NT_WORKSTATION)
                {
                    os_version = "Microsoft Windows Vista ";
                    if (os.wSuiteMask == VER_SUITE_PERSONAL)
                        os_version.append("Home ");
                }
                else if (os.wProductType != VER_NT_WORKSTATION)
                {
                    os_version = "Microsoft Windows Server 2008 ";
                    if (os.wSuiteMask == VER_SUITE_DATACENTER)
                        os_version.append("Datacenter Server ");
                    else if (os.wSuiteMask == VER_SUITE_ENTERPRISE)
                        os_version.append("Enterprise ");
                }
                break;
            case 1:
                if (os.wProductType == VER_NT_WORKSTATION)
                    os_version = "Microsoft Windows 7 ";
                else
                    os_version = "Microsoft Windows Server 2008 R2 ";
                break;
            }
            break;
        default:
            os_version = "? ";
        }
    }
    SYSTEM_INFO si;
    SafeGetNativeSystemInfo(&si);
    if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 ||
        si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64)
        os_version.append("64bit");
    else os_version.append("32bit");
    return os_version;
    

}


void CSysInfo::SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo)
{
    if (NULL == lpSystemInfo)
        return;
    typedef VOID(WINAPI *LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo);
    LPFN_GetNativeSystemInfo nsInfo =
        (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetNativeSystemInfo");;
    if (NULL != nsInfo)
    {
        nsInfo(lpSystemInfo);
    }
    else
    {
        GetSystemInfo(lpSystemInfo);
    }

}

const std::string CSysInfo::GetCPUInfo()
{
    std::string processor_name("");
    std::string str_path = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
    HKEY key;
    if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)str_path.c_str(), 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS)
    {
        char processor_value[256];
        DWORD type = REG_SZ;
        DWORD value_size = sizeof(processor_value);
        if (::RegQueryValueEx(key, "ProcessorNameString", 0, &type, (LPBYTE)&processor_value, &value_size) == ERROR_SUCCESS)
            processor_name.append(processor_value, value_size);
        RegCloseKey(key);

    }
    return processor_name;
}

const std::string CSysInfo::GetMemoryStatus()
{
    std::string memory_info("");
    MEMORYSTATUSEX statusex;
    statusex.dwLength = sizeof(statusex);
    if (GlobalMemoryStatusEx(&statusex))
    {
        unsigned long long total = 0, remain_total = 0, avl = 0, remain_avl = 0;
        double decimal_total = 0, decimal_avl = 0;
        remain_total = statusex.ullTotalPhys % GBYTES;
        total = statusex.ullTotalPhys / GBYTES;
        avl = statusex.ullAvailPhys / GBYTES;
        remain_avl = statusex.ullAvailPhys % GBYTES;
        if (remain_total > 0)
            decimal_total = (remain_total / MBYTES) / DKBYTES;
        if (remain_avl > 0)
            decimal_avl = (remain_avl / MBYTES) / DKBYTES;

        decimal_total += (double)total;
        decimal_avl += (double)avl;
        char  buffer[MAX_PATH];
        //sprintf_s(buffer, MAX_PATH, "%.2f GB (%.2f GB可用)", decimal_total, decimal_avl);
        sprintf_s(buffer, MAX_PATH, "%.2f GB", decimal_total);
        memory_info.append(buffer);
    }
    return memory_info;
}

void CSysInfo::GetNetCardAndIPInfo(std::string &adapter_info, std::string &MAC_address, std::string &IP)
{
    PIP_ADAPTER_INFO pIp_adapter_info = new IP_ADAPTER_INFO();
    unsigned long adapter_size = sizeof(IP_ADAPTER_INFO);
    int ret = GetAdaptersInfo(pIp_adapter_info, &adapter_size);
    if (ERROR_BUFFER_OVERFLOW == ret)
    {
        delete pIp_adapter_info;
        pIp_adapter_info = (PIP_ADAPTER_INFO)new BYTE[adapter_size];
        ret = GetAdaptersInfo(pIp_adapter_info, &adapter_size);
    }
    if (ERROR_SUCCESS == ret)
    {
        while (pIp_adapter_info)
        {
            adapter_info.append("name: ");
            adapter_info.append(pIp_adapter_info->AdapterName);
            adapter_info.append("\ndescription: ");
            adapter_info.append(pIp_adapter_info->Description);
            adapter_info.append("\ntype: ");
            std::string card_type("");
            switch (pIp_adapter_info->Type)
            {
            case MIB_IF_TYPE_OTHER:
                card_type = "other";
                break;
            case MIB_IF_TYPE_ETHERNET:
                card_type = "ethernet";
                break;
            case MIB_IF_TYPE_TOKENRING:
                card_type = "tokenring";
                break;
            case MIB_IF_TYPE_FDDI:
                card_type = "fddi";
                break;
            case MIB_IF_TYPE_PPP:
                card_type = "ppp";
                break;
            case MIB_IF_TYPE_LOOPBACK:
                card_type = "loopback";
                break;
            case MIB_IF_TYPE_SLIP:
                card_type = "slip";
                break;
            default:
                break;
            }
            adapter_info.append(card_type);
            MAC_address.append("\nMACAddr: ");
            char  buffer[MAX_PATH];
            for (DWORD i = 0; i < pIp_adapter_info->AddressLength; i++)
                if (i < pIp_adapter_info->AddressLength - 1)
                {
                    sprintf_s(buffer, MAX_PATH, "%02X", pIp_adapter_info->Address[i]);
                    MAC_address.append(buffer);
                    MAC_address.append("-");
                }
                else
                {
                    sprintf_s(buffer, MAX_PATH, "%02X", pIp_adapter_info->Address[i]);
                    MAC_address.append(buffer);
                    adapter_info.append("\n");
                }

            IP_ADDR_STRING *pIp_addr_string = &(pIp_adapter_info->IpAddressList);
            do
            {
                IP.append("IPAddr:");
                IP.append(pIp_addr_string->IpAddress.String);;
                IP.append("\nIpMask:");
                IP.append(pIp_addr_string->IpMask.String);
                IP.append("\nGateway:");
                IP.append(pIp_adapter_info->GatewayList.IpAddress.String);
                IP.append("\n");
                pIp_addr_string = pIp_addr_string->Next;
            } while (pIp_addr_string);
            adapter_info.append("\n");
            pIp_adapter_info = pIp_adapter_info->Next;
        }

    }
    if (pIp_adapter_info)
    {
        delete pIp_adapter_info;
        pIp_adapter_info = nullptr;
    }
}

const std::string CSysInfo::GetComputerUserName()
{
    
    char szUsername[BUFSIZ];
    DWORD bufCharCount = BUFSIZ;
    
    // Get and display the name of the computer.
    if (GetComputerName(szUsername, &bufCharCount)) {
        return szUsername;
        
    }else {
        return "";
    }

}


BOOL CSysInfo::GetHardDiskInfo(LPTSTR pModelNo, LPTSTR pSerialNo)
{
    //-1是因为 SENDCMDOUTPARAMS 的结尾是 BYTE bBuffer[1];  
    BYTE IdentifyResult[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
    DWORD dwBytesReturned;
    GETVERSIONINPARAMS get_version;
    SENDCMDINPARAMS send_cmd = { 0 };

    HANDLE hFile = CreateFile(_T("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
    if (hFile == INVALID_HANDLE_VALUE)
        return FALSE;

    //get version  
    DeviceIoControl(hFile, SMART_GET_VERSION, NULL, 0,
        &get_version, sizeof(get_version), &dwBytesReturned, NULL);

    //identify device  
    send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10) ? ATAPI_ID_CMD : ID_CMD;
    DeviceIoControl(hFile, SMART_RCV_DRIVE_DATA, &send_cmd, sizeof(SENDCMDINPARAMS) - 1,
        IdentifyResult, sizeof(IdentifyResult), &dwBytesReturned, NULL);
    CloseHandle(hFile);

    //adjust the byte order  
    PUSHORT pWords = (USHORT*)(((SENDCMDOUTPARAMS*)IdentifyResult)->bBuffer);

    
    ToLittleEndian(pWords, 27, 46, pModelNo);
    ToLittleEndian(pWords, 10, 19, pSerialNo);

    
    return true;
}

//把WORD数组调整字节序为little-endian,并滤除字符串结尾的空格。  
void CSysInfo::ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf)
{
    int index;
    LPTSTR pDest = pBuf;
    for (index = nFirstIndex; index <= nLastIndex; ++index)
    {
        pDest[0] = pWords[index] >> 8;
        pDest[1] = pWords[index] & 0xFF;
        pDest += 2;
    }
    *pDest = 0;

    //trim space at the endof string; 0x20: _T(' ')  
    --pDest;
    while (*pDest == 0x20)
    {
        *pDest = 0;
        --pDest;
    }
}

 

posted on 2019-09-28 17:05  Anlia  阅读(3890)  评论(0编辑  收藏  举报

导航