C++读取硬盘序列号
程序员文章站
2022-04-15 11:20:19
c++读取硬盘序列号:有时在将程序或者打包库提供给第三方时,为了防止传播泛滥,或者有一定的版权问题,需要绑定特定的计算机设备。此时就需要读取计算机的一些硬件资源(硬盘、cpu、bios等),来计算一...
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失败的解决办法[原创],不过我没有测试,有兴趣的可以尝试一下。