Skip to content

Instantly share code, notes, and snippets.

@dkw72n
Created July 24, 2018 07:24
Show Gist options
  • Select an option

  • Save dkw72n/b041a28091ec04a7086f307aac9ecf7c to your computer and use it in GitHub Desktop.

Select an option

Save dkw72n/b041a28091ec04a7086f307aac9ecf7c to your computer and use it in GitHub Desktop.
#include "stdafx.h"
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
#pragma warning( disable : 4503 )
typedef std::map<std::wstring, std::wstring> HWINFO;
typedef std::map<std::wstring, std::vector<HWINFO>> SYSINFO;
static std::string WideToUTF8(const std::wstring &wide) {
if (wide.length() == 0) {
return std::string();
}
// compute the length of the buffer we'll need
int charcount = WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1,
//int charcount = WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1,//因为dump采用gbk
NULL, 0, NULL, NULL);
if (charcount == 0) {
return std::string();
}
// convert
char *buf = new char[charcount];
WideCharToMultiByte(CP_UTF8, 0, wide.c_str(), -1, buf, charcount,
//WideCharToMultiByte(CP_ACP, 0, wide.c_str(), -1, buf, charcount,
NULL, NULL);
std::string result(buf);
delete[] buf;
return result;
}
const std::wstring StrAdapterRam = L"AdapterRAM";
static HWINFO GetHwInfo(CComPtr<IWbemClassObject>& pClassObject){
HWINFO ret;
SAFEARRAY *pvNames = NULL;
if( pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) != S_OK )
{
printf("GetHwInfo error\n");
return ret;
}
long vbl, vbu;
SafeArrayGetLBound(pvNames, 1, &vbl);
SafeArrayGetUBound(pvNames, 1, &vbu);
for(long i = vbl ; i<= vbu; i++ )
{
long index = i ;
WCHAR *wsName = NULL ;
CComVariant varValue ;
SafeArrayGetElement( pvNames, &index , &wsName ) ;
CComBSTR bstrName ( wsName ) ;
if( pClassObject->Get( bstrName , 0 , &varValue , NULL , 0 ) != S_OK ){
continue;
}
std::wstring str ;
if( varValue.vt == VT_BSTR )
{
// wprintf(L"%s = %s\n", wsName, varValue.bstrVal);
str = varValue.bstrVal ;
}
else if( varValue.vt == VT_ARRAY )
{
long iLowBound = 0 , iUpBound = 0 ;
SafeArrayGetLBound( varValue.parray , 1 , &iLowBound ) ;
SafeArrayGetUBound( varValue.parray , 1 , &iUpBound ) ;
for( long j = iLowBound ; j <= iUpBound ; j ++ )
{
VARIANT *pvar = NULL ;
long temp = j ;
if(SafeArrayGetElement( varValue.parray , &temp , pvar ) == S_OK && pvar)
{
CComVariant varTemp ;
if( varTemp.ChangeType( VT_BSTR , pvar ) == S_OK )
{
if( !str.empty() )
str += _T(",") ;
str += varTemp.bstrVal ;
}
}
}
}
else
{
if (StrAdapterRam == wsName){
// see: https://www.reddit.com/r/Windows10/comments/5vjkof/so_microsoft_when_will_you_fix_this_god_damn/
varValue.ChangeType(VT_UI4);
}
if( varValue.ChangeType( VT_BSTR ) == S_OK )
str = varValue.bstrVal ;
}
// 打印出硬件信息
// TRACE( "%s=%s/n" , CString(bstrName) , str ) ;
// wcout << wsName << L"=" << str << endl;
// wprintf(L"%s = %s\n", wsName, str.c_str());
ret[wsName] = str;
}
Exit0:
if(pvNames)
{
SafeArrayDestroy(pvNames);
}
return ret ;
}
class CoGuard{
CComPtr<IWbemServices> m_pWbemServices;
public:
CoGuard(){
CoInitialize(NULL);
}
bool Init(){
HRESULT hresult;
CComPtr<IWbemLocator> spWbemLocator ;
CComPtr<IWbemServices> spWbemServices ;
hresult = CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE,NULL, EOAC_NONE, 0);
if(hresult != S_OK && hresult != RPC_E_TOO_LATE){
return false;
}
if(spWbemLocator.CoCreateInstance( CLSID_WbemAdministrativeLocator, 0, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER ) != S_OK){
return false;
}
if( spWbemLocator->ConnectServer( L"\\\\.\\root\\CIMV2", NULL, NULL, NULL, 0, NULL, NULL, &spWbemServices ) != S_OK ){
return false;
}
m_pWbemServices = spWbemServices;
return true;
}
bool IsInit(){
return m_pWbemServices != nullptr;
}
const CComPtr<IWbemServices>& GetService(){
return m_pWbemServices;
}
bool QueryWmic(std::wstring query, std::vector<HWINFO>& ret, std::string& errmsg){
if (m_pWbemServices == nullptr){
errmsg = "CoGuard not inited";
return false;
}
auto spWbemServices = m_pWbemServices;
CComBSTR q(query.data());
CComPtr<IEnumWbemClassObject> spEnumWbemClassObject ;
if( spWbemServices->ExecQuery( L"WQL" , q , WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &spEnumWbemClassObject ) == S_OK ){
ULONG uCount = 1, uReturned;
CComPtr<IWbemClassObject> spClassObject ;
if( spEnumWbemClassObject->Reset() == S_OK )
{
while( spEnumWbemClassObject->Next( WBEM_INFINITE, uCount, &spClassObject, &uReturned) == S_OK )
{
ret.push_back(GetHwInfo( spClassObject ));
spClassObject.Release() ;
}
} else {
errmsg = "spEnumWbemClassObject->Reset() FAILED";
return false;
}
} else {
errmsg = "spWbemServices->ExecQuery() FAILED";
return false;
}
return true;
}
~CoGuard(){
m_pWbemServices = nullptr;
CoUninitialize();
}
};
/*
bool QueryWmic(std::wstring query, std::vector<HWINFO>& ret, std::string& errmsg){
if (!s_coguard){
errmsg = "s_coguard not inited";
return false;
}
auto spWbemServices = s_coguard->GetService();
CComBSTR q(query.data());
CComPtr<IEnumWbemClassObject> spEnumWbemClassObject ;
if( spWbemServices->ExecQuery( L"WQL" , q , WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &spEnumWbemClassObject ) == S_OK ){
ULONG uCount = 1, uReturned;
CComPtr<IWbemClassObject> spClassObject ;
if( spEnumWbemClassObject->Reset() == S_OK )
{
while( spEnumWbemClassObject->Next( WBEM_INFINITE, uCount, &spClassObject, &uReturned) == S_OK )
{
ret.push_back(GetHwInfo( spClassObject ));
spClassObject.Release() ;
}
} else {
errmsg = "spEnumWbemClassObject->Reset() FAILED";
return false;
}
} else {
errmsg = "spWbemServices->ExecQuery() FAILED";
return false;
}
return true;
}
*/
static bool GetSysInfo(SYSINFO& ret, std::string& err){
auto coguard = CoGuard();
if (!coguard.Init()){
err = "coguard.Init() FAILED";
return false;
}
if (!coguard.QueryWmic(L"SELECT Name,Manufacturer,MaxClockSpeed,NumberOfCores,NumberOfLogicalProcessors,ProcessorId,Revision,SerialNumber,UniqueId FROM win32_Processor", ret[L"CPU"], err)){
err += "(CPU)";
return false;
}
if (!coguard.QueryWmic(L"SELECT SerialNumber,Caption,Manufacturer,Product,Version FROM win32_BaseBoard", ret[L"Board"], err)){
err += "(Board)";
return false;
}
if (!coguard.QueryWmic(L"SELECT Capacity,Manufacturer,SerialNumber,PartNumber FROM win32_PhysicalMemory", ret[L"Memory"], err)){
err += "(Memory)";
return false;
}
if (!coguard.QueryWmic(L"SELECT MACAddress,GUID,Caption,PNPDeviceID,PhysicalAdapter FROM win32_NetworkAdapter", ret[L"Network"], err)){
err += "(Network)";
return false;
}
if (!coguard.QueryWmic(L"SELECT SerialNumber,Size,Name,Signature,Model,Caption,FirmwareRevision FROM win32_DiskDrive", ret[L"Disk"], err)){
err += "(Disk)";
return false;
}
if (!coguard.QueryWmic(L"SELECT AdapterRAM,DriverVersion,InstalledDisplayDrivers,Name,Caption FROM win32_VideoController", ret[L"Graphic"], err)){
err += "(Graphic)";
return false;
}
if (!coguard.QueryWmic(L"SELECT Caption,Name,Description,FreeSpace,Size,VolumeSerialNumber FROM win32_LogicalDisk", ret[L"Partition"], err)){
err += "(Partition)";
return false;
}
return true;
}
static std::string JsonEscape(std::string str){
std::string ret;
for(auto c:str){
switch(c){
case '\\':
case '"':
case '/':
ret += "\\";
ret += c;
break;
case '\b':
ret += "\\b";
break;
case '\f':
ret += "\\f";
break;
case '\t':
ret += "\\t";
break;
case '\n':
ret += "\\n";
break;
case '\r':
ret += "\\r";
break;
default:
if (c >=0 && c < ' ') {
char buf[10];
sprintf_s(buf, "\\u%04x", c);
ret += c;
} else {
ret += c;
}
}
}
return ret;
}
static std::string SysInfoToJson(SYSINFO sysinfo){
std::string ret;
int syscnt = 0;
ret += "{\n";
for(auto p: sysinfo){
if (syscnt++){
ret += ",\n";
}
ret += " \"";
ret += JsonEscape(WideToUTF8(p.first));
ret += "\": [\n";
int hwcnt = 0;
for (auto hw: p.second){
if (hwcnt++){
ret += ",\n";
}
ret += " {\n";
int propcnt = 0;
for (auto pp: hw){
if (propcnt++){
ret += ",\n";
}
ret += " \"";
ret += JsonEscape(WideToUTF8(pp.first));
ret += "\": \"";
ret += JsonEscape(WideToUTF8(pp.second));
ret += "\"";
}
ret += "\n }";
}
ret += "\n ]";
}
ret += "\n}\n";
return ret;
}
bool GetSysInfoJson(std::string& result, std::string& errmsg){
SYSINFO info;
if (!GetSysInfo(info, errmsg)){
return false;
}
result = SysInfoToJson(info);
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment