当前位置: 移动技术网 > IT编程>开发语言>C/C++ > C++读取硬盘序列号

C++读取硬盘序列号

2018年10月30日  | 移动技术网IT编程  | 我要评论

便携式测油仪,环保袋制作,网站设计风格

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

软件查看硬盘序列号

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

\

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失败的解决办法[原创],不过我没有测试,有兴趣的可以尝试一下。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网