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.
}