#include <windows.h>
#include <wbemidl.h>
#include <comdef.h>
#include <string>
#pragma comment(lib, "wbemuuid.lib")
std::string GetDiskHWID() {
HRESULT hres;
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
hres = CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE,
NULL
);
IWbemLocator* pLoc = NULL;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&pLoc
);
IWbemServices* pSvc = NULL;
hres = pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc
);
hres = CoSetProxyBlanket(
pSvc,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE
);
IEnumWbemClassObject* pEnumerator = NULL;
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT SerialNumber FROM Win32_PhysicalMedia"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
IWbemClassObject* pclsObj = NULL;
ULONG uReturn = 0;
std::string diskId;
while (pEnumerator) {
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn) break;
VARIANT vtProp;
hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
if (SUCCEEDED(hr) {
if (vtProp.vt == VT_BSTR) {
std::wstring ws(vtProp.bstrVal, SysStringLen(vtProp.bstrVal));
diskId = std::string(ws.begin(), ws.end());
// Удаляем пробелы и непечатные символы
diskId.erase(std::remove_if(diskId.begin(), diskId.end(),
[](char c) { return std::isspace(c) || !std::isprint(c); }), diskId.end());
}
VariantClear(&vtProp);
}
pclsObj->Release();
}
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
CoUninitialize();
return diskId;
}