欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C++读取硬盘序列号

程序员文章站 2022-04-15 11:20:19
c++读取硬盘序列号:有时在将程序或者打包库提供给第三方时,为了防止传播泛滥,或者有一定的版权问题,需要绑定特定的计算机设备。此时就需要读取计算机的一些硬件资源(硬盘、cpu、bios等),来计算一...

c++读取硬盘序列号:有时在将程序或者打包库提供给第三方时,为了防止传播泛滥,或者有一定的版权问题,需要绑定特定的计算机设备。此时就需要读取计算机的一些硬件资源(硬盘、cpu、bios等),来计算一个验证码,达到一机一码的目的。

软件查看硬盘序列号

借助diskgenius查看硬盘序列号,选中硬盘,即可看到在下方有序列号。不过貌似ssd和机械硬盘的序列号格式是不一样的
ssd: 12位序列号
机械硬盘: 8位序列号

C++读取硬盘序列号

c++实现读取硬盘序列号

参考资料

(https://msdn.microsoft.com/en-us/library/aa389273(v=vs.85)

代码实现

代码实现使用的是微软提供的wmi providers库, 读取不同硬件设备有不同的类,具体查看上面的msdn链接。
- 硬盘 [win32_physicalmemory class](https://msdn.microsoft.com/en-us/library/aa394346(v=vs.85)
- cpu [win32_processor class](https://msdn.microsoft.com/en-us/library/aa394373(v=vs.85)
- bios [win32_bios class](https://msdn.microsoft.com/en-us/library/aa394077(v=vs.85)

#define _win32_dcom
#include 
using namespace std;
#include 
#include 

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

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

    // step 1: --------------------------------------------------
    // initialize com. 初始化com组件------------------------------

    hres = coinitializeex(0, coinit_multithreaded);
    if (failed(hres))
    {
        cout << "failed to initialize com library. error code = 0x"
            << hex << hres << endl;
        return 1;                  // program has failed.
    }

    // step 2: --------------------------------------------------
    // set general com security levels --------------------------
    // note: if you are using windows 2000, you need to specify -
    // the default authentication credentials for a user by using
    // a sole_authentication_list structure in the pauthlist ----
    // parameter of coinitializesecurity ------------------------

    hres = coinitializesecurity(
        null,
        -1,                          // com authentication
        null,                        // authentication services
        null,                        // reserved
        rpc_c_authn_level_default,   // default authentication
        rpc_c_imp_level_impersonate, // default 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.
    }

    // step 3: ---------------------------------------------------
    // obtain the initial locator to wmi -------------------------

    iwbemlocator *ploc = null;

    hres = cocreateinstance(
        clsid_wbemlocator,
        0,
        clsctx_inproc_server,
        iid_iwbemlocator, (lpvoid *)&ploc);

    if (failed(hres))
    {
        cout << "failed to create iwbemlocator object."
            << " err code = 0x"
            << hex << hres << endl;
        couninitialize();
        return 1;                 // program has failed.
    }

    // step 4: -----------------------------------------------------
    // connect to wmi through the iwbemlocator::connectserver method

    iwbemservices *psvc = null;

    // connect to the root\cimv2 namespace with
    // the current user and obtain pointer psvc
    // to make iwbemservices calls.
    hres = ploc->connectserver(
        _bstr_t(l"root\\cimv2"), // object path of wmi namespace
        null,                    // user name. null = current user
        null,                    // user password. null = current
        0,                       // locale. null indicates current
        null,                    // security flags.
        0,                       // authority (e.g. kerberos)
        0,                       // context object
        &psvc                    // pointer to 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;

    // step 5: --------------------------------------------------
    // set security levels on the proxy -------------------------

    hres = cosetproxyblanket(
        psvc,                        // indicates the proxy to set
        rpc_c_authn_winnt,           // rpc_c_authn_xxx
        rpc_c_authz_none,            // rpc_c_authz_xxx
        null,                        // server principal name
        rpc_c_authn_level_call,      // rpc_c_authn_level_xxx
        rpc_c_imp_level_impersonate, // rpc_c_imp_level_xxx
        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.
    }

    // step 6: --------------------------------------------------
    // use the iwbemservices pointer to make requests of wmi ----

    // for example, get the name of the operating system
    ienumwbemclassobject* penumerator = null;
    hres = psvc->execquery(
        bstr_t("wql"),
        bstr_t("select * win32_physicalmemory"),
        wbem_flag_forward_only | wbem_flag_return_immediately,
        null,
        &penumerator);

    if (failed(hres))
    {
        cout << "query for physical media failed."
            << " error code = 0x"
            << hex << hres << endl;
        psvc->release();
        ploc->release();
        couninitialize();
        return 1;               // program has failed.
    }

    // step 7: -------------------------------------------------
    // get the data from the query in step 6 -------------------

    iwbemclassobject *pclsobj =null;
    ulong ureturn = 0;

    while (penumerator)
    {
        hresult hr = penumerator->next(wbem_infinite, 1,
            &pclsobj, &ureturn);

        if (0 == ureturn)
        {
            break;
        }

        variant vtprop;

        // get the value of the name property
        hr = pclsobj->get(l"serialnumber", 0, &vtprop, 0, 0);

        wcout << "serial number : " << vtprop.bstrval << endl;
        variantclear(&vtprop);
    }

    // cleanup
    // ========

    psvc->release();
    ploc->release();
    penumerator->release();
    pclsobj->release();
    couninitialize();

    return 0;   // program successfully completed.
}

我在实验过程中,获取cpu序列号失败,简单搜了一下,是vmi的问题使用managementclass(“win32_processor”)获取cpuid失败的解决办法[原创],不过我没有测试,有兴趣的可以尝试一下。