c 语言读取硬盘序列号,C++读取硬盘序列号

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

软件查看硬盘序列号

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

ssd: 12位序列号

机械硬盘: 8位序列号

52f7d44f4f6f6b34dc9e7867ea0fd828.png

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.

}