Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Collecting Windows Hardware and OS Information in C/C++ using Win32 APIs, Registry, and WMI

Tech 2

Win32/Registry-based approach

Direct Win32 calls and registry queries provide fast access to operating system and hardware metadata. The code below wraps commonly used queries (OS/service pack, CPU, memory, NICs, disks, GPU).

SystemProbe.h

#pragma once

#include <afxtempl.h>

class SystemProbe
{
public:
    SystemProbe() {}
    ~SystemProbe() {}

    // OS information
    void QueryOSVersion(CString& osVersion, CString& servicePack);
    BOOL IsRunningUnderWow64();

    // Network interfaces
    int  EnumerateNics();
    void GetNicName(CString& nicName, int index);

    // Memory
    void QueryMemory(CString& totalPhysical, CString& totalVirtual);

    // CPU
    void QueryCpu(CString& cpuName, CString& cpuType, DWORD& logicalCount, DWORD& maxClockMHz);

    // Disks
    void EnumerateDisks(DWORD& outCount, CString outDescriptions[]);

    // Graphics adapters
    void EnumerateVideoAdapters(DWORD& outCount, CString outNames[]);

private:
    CStringList m_nicNames;
    CList<DWORD, DWORD&> m_nicBandwidths;
    CList<DWORD, DWORD&> m_nicTraffic; // placeholder for future counters
};

SystemProbe.cpp

#include "StdAfx.h"
#include "SystemProbe.h"
#include <float.h>
#include <winperf.h>

static BOOL TryGetNativeSystemInfo(SYSTEM_INFO* p)
{
    typedef VOID (WINAPI *PFN)(LPSYSTEM_INFO);
    PFN fn = (PFN)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
    if (fn) { fn(p); return TRUE; }
    GetSystemInfo(p); return FALSE;
}

void SystemProbe::QueryOSVersion(CString& osVersion, CString& servicePack)
{
    CString buff;
    OSVERSIONINFOEX ver = {0};
    ver.dwOSVersionInfoSize = sizeof(ver);
    if (!GetVersionEx((OSVERSIONINFO*)&ver)) {
        OSVERSIONINFO v2 = {0};
        v2.dwOSVersionInfoSize = sizeof(v2);
        if (!GetVersionEx(&v2)) { osVersion.Empty(); servicePack.Empty(); return; }
        ver.dwMajorVersion = v2.dwMajorVersion;
        ver.dwMinorVersion = v2.dwMinorVersion;
        ver.dwBuildNumber  = v2.dwBuildNumber;
        lstrcpyn(ver.szCSDVersion, v2.szCSDVersion, _countof(ver.szCSDVersion));
    }

    SYSTEM_INFO si = {0};
    TryGetNativeSystemInfo(&si);

    switch (ver.dwPlatformId)
    {
    case VER_PLATFORM_WIN32_NT:
        if (ver.dwMajorVersion == 6 && ver.dwMinorVersion == 0)
        {
            if (ver.wProductType == VER_NT_WORKSTATION) buff = _T("Windows Vista");
            else buff = _T("Windows Server 2008");
        }
        else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 2)
        {
            if (GetSystemMetrics(SM_SERVERR2)) buff = _T("Windows Server 2003 R2");
            else if (ver.wProductType == VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64)
                buff = _T("Windows XP Professional x64 Edition");
            else buff = _T("Windows Server 2003");
        }
        else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 1) buff = _T("Windows XP");
        else if (ver.dwMajorVersion == 5 && ver.dwMinorVersion == 0) buff = _T("Windows 2000");
        else if (ver.dwMajorVersion <= 4) buff = _T("Windows NT");

        servicePack.Format(_T("%s"), ver.szCSDVersion[0] ? ver.szCSDVersion : _T(""));
        osVersion = buff;
        break;

    case VER_PLATFORM_WIN32_WINDOWS:
        if (ver.dwMajorVersion == 4 && ver.dwMinorVersion == 0) {
            buff = _T("Windows 95");
            if (ver.szCSDVersion[1] == 'B' || ver.szCSDVersion[1] == 'C') buff += _T(" OSR2");
        } else if (ver.dwMajorVersion == 4 && ver.dwMinorVersion == 10) {
            buff = _T("Windows 98");
            if (ver.szCSDVersion[1] == 'A' || ver.szCSDVersion[1] == 'B') buff += _T(" SE");
        } else if (ver.dwMajorVersion == 4 && ver.dwMinorVersion == 90) buff = _T("Windows ME");
        osVersion = buff; servicePack.Empty();
        break;

    default:
        osVersion.Empty(); servicePack.Empty();
        break;
    }
}

BOOL SystemProbe::IsRunningUnderWow64()
{
    typedef BOOL (WINAPI *PFN)(HANDLE, PBOOL);
    PFN pIsWow64 = (PFN)GetProcAddress(GetModuleHandle(_T("kernel32")), "IsWow64Process");
    BOOL isWow64 = FALSE;
    if (pIsWow64) pIsWow64(GetCurrentProcess(), &isWow64);
    return isWow64;
}

void SystemProbe::QueryCpu(CString& cpuName, CString& cpuType, DWORD& logicalCount, DWORD& maxClockMHz)
{
    cpuName.Empty(); cpuType.Empty(); logicalCount = 0; maxClockMHz = 0;

    // Read CPU marketing name and nominal MHz from registry
    CRegKey k;
    if (ERROR_SUCCESS == k.Open(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"), KEY_READ))
    {
        WCHAR nameBuf[128] = {0}; DWORD cb = sizeof(nameBuf);
        if (ERROR_SUCCESS == k.QueryStringValue(_T("ProcessorNameString"), nameBuf, &cb)) cpuName = nameBuf;

        DWORD mhz = 0;
        if (ERROR_SUCCESS == k.QueryDWORDValue(_T("~MHz"), mhz)) maxClockMHz = mhz;

        k.Close();
    }

    SYSTEM_INFO si = {0};
    GetSystemInfo(&si);
    logicalCount = si.dwNumberOfProcessors;

    switch (si.dwProcessorType)
    {
    case PROCESSOR_INTEL_386:   cpuType = _T("Intel 386"); break;
    case PROCESSOR_INTEL_486:   cpuType = _T("Intel 486"); break;
    case PROCESSOR_INTEL_PENTIUM: cpuType = _T("Intel Pentium"); break;
    case PROCESSOR_INTEL_IA64:  cpuType = _T("Intel IA64"); break;
    case PROCESSOR_AMD_X8664:   cpuType = _T("AMD x86-64"); break;
    default:                    cpuType = _T("Unknown"); break;
    }
}

void SystemProbe::QueryMemory(CString& totalPhysical, CString& totalVirtual)
{
    MEMORYSTATUS ms = {0};
    ms.dwLength = sizeof(ms);
    GlobalMemoryStatus(&ms);

    DWORD physMB = (DWORD)(ms.dwTotalPhys / (1024 * 1024));
    DWORD virtMB = (DWORD)(ms.dwTotalVirtual / (1024 * 1024));

    totalPhysical.Format(_T("physical memory:%lu MB"), physMB);
    totalVirtual.Format(_T("virtual memory:%lu MB"), virtMB);
}

int SystemProbe::EnumerateNics()
{
    m_nicNames.RemoveAll();
    m_nicBandwidths.RemoveAll();
    m_nicTraffic.RemoveAll();

    const DWORD kObjIdx = 510; // Network Interface
    const DWORD kBandwidthCounterIdx = 520; // Current Bandwidth

    const DWORD kChunk = 40960;
    DWORD bufSize = kChunk;
    BYTE* buf = (BYTE*)malloc(bufSize);
    if (!buf) return 0;

    DWORD type = 0; DWORD ret = 0;
    CString idx; idx.Format(_T("%u"), kObjIdx);

    for (;;)
    {
        ret = RegQueryValueEx(HKEY_PERFORMANCE_DATA, idx, 0, &type, buf, &bufSize);
        if (ret == ERROR_SUCCESS) break;
        if (ret == ERROR_MORE_DATA) {
            bufSize += kChunk; BYTE* tmp = (BYTE*)realloc(buf, bufSize);
            if (!tmp) { free(buf); return 0; }
            buf = tmp; continue;
        }
        free(buf); return 0;
    }

    PERF_DATA_BLOCK* pdb = (PERF_DATA_BLOCK*)buf;
    PERF_OBJECT_TYPE* pot = (PERF_OBJECT_TYPE*)((BYTE*)pdb + pdb->HeaderLength);

    for (LONG oi = 0; oi < (LONG)pdb->NumObjectTypes; ++oi)
    {
        if (pot->ObjectNameTitleIndex == kObjIdx)
        {
            DWORD bandwidthOffset = ULONG_MAX;
            PERF_COUNTER_DEFINITION* pcd = (PERF_COUNTER_DEFINITION*)((BYTE*)pot + pot->HeaderLength);
            for (LONG ci = 0; ci < (LONG)pot->NumCounters; ++ci)
            {
                if (pcd->CounterNameTitleIndex == kBandwidthCounterIdx)
                    bandwidthOffset = pcd->CounterOffset;
                pcd = (PERF_COUNTER_DEFINITION*)((BYTE*)pcd + pcd->ByteLength);
            }
            if (bandwidthOffset == ULONG_MAX) break;

            PERF_INSTANCE_DEFINITION* pid = (PERF_INSTANCE_DEFINITION*)((BYTE*)pot + pot->DefinitionLength);
            for (LONG ii = 0; ii < pot->NumInstances; ++ii)
            {
                WCHAR* wname = (WCHAR*)((BYTE*)pid + pid->NameOffset);
                CHAR nameA[256] = {0};
                WideCharToMultiByte(CP_ACP, 0, wname, -1, nameA, sizeof(nameA), nullptr, nullptr);

                PERF_COUNTER_BLOCK* pcb = (PERF_COUNTER_BLOCK*)((BYTE*)pid + pid->ByteLength);
                DWORD bandwidth = *(DWORD*)((BYTE*)pcb + bandwidthOffset);

                m_nicNames.AddTail(CString(nameA));
                m_nicBandwidths.AddTail(bandwidth);
                m_nicTraffic.AddTail(0);

                pid = (PERF_INSTANCE_DEFINITION*)((BYTE*)pid + pid->ByteLength + pcb->ByteLength);
            }
        }
        pot = (PERF_OBJECT_TYPE*)((BYTE*)pot + pot->TotalByteLength);
    }

    free(buf);
    return (int)m_nicNames.GetCount();
}

void SystemProbe::GetNicName(CString& nicName, int index)
{
    nicName.Empty();
    POSITION p = m_nicNames.FindIndex(index);
    if (!p) return;
    CString name = m_nicNames.GetAt(p);

    p = m_nicBandwidths.FindIndex(index);
    if (!p) { nicName = name; return; }
    DWORD bw = m_nicBandwidths.GetAt(p);

    CString s; s.Format(_T("%lu"), bw);
    nicName = name + s;
}

void SystemProbe::EnumerateDisks(DWORD& outCount, CString outDescriptions[])
{
    DWORD mask = GetLogicalDrives();
    UINT count = 0;
    for (DWORD v = mask; v; v >>= 1) if (v & 1) ++count;

    if (outCount < count) { return; }
    outCount = count;

    UINT len = GetLogicalDriveStrings(0, nullptr);
    CArray<TCHAR, TCHAR> buf; buf.SetSize(len + 2);
    GetLogicalDriveStrings(len, buf.GetData());

    UINT idx = 0;
    for (LPTSTR p = buf.GetData(); *p; p += lstrlen(p) + 1)
    {
        CString root = p;
        UINT type = GetDriveType(root);
        CString kind;
        switch (type)
        {
        case DRIVE_FIXED:    kind = _T("Local disk"); break;
        case DRIVE_CDROM:    kind = _T("Optical"); break;
        case DRIVE_REMOVABLE:kind = _T("Removable"); break;
        case DRIVE_REMOTE:   kind = _T("Network"); break;
        case DRIVE_RAMDISK:  kind = _T("RAM disk"); break;
        default:             kind = _T("Unknown"); break;
        }

        ULARGE_INTEGER freeCaller = {0}, total = {0}, freeAll = {0};
        BOOL ok = GetDiskFreeSpaceEx(root, &freeCaller, &total, &freeAll);
        CString sTotal, sFree;
        if (ok) {
            sTotal.Format(_T("Total %0.0fMB"), (double)total.QuadPart / 1024.0 / 1024.0);
            sFree.Format(_T(" Free %0.0fMB"), (double)freeCaller.QuadPart / 1024.0 / 1024.0);
        }
        outDescriptions[idx++] = kind + _T(" (") + root + _T("):") + sTotal + sFree;
    }
}

void SystemProbe::EnumerateVideoAdapters(DWORD& outCount, CString outNames[])
{
    outCount = 0;

    HKEY hServices = nullptr, hEnum = nullptr;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Services"), 0, KEY_READ, &hServices) != ERROR_SUCCESS)
        return;
    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("SYSTEM\\CurrentControlSet\\Enum"), 0, KEY_READ, &hEnum) != ERROR_SUCCESS)
    {
        RegCloseKey(hServices); return;
    }

    for (DWORD i = 0;; ++i)
    {
        TCHAR sub[256] = {0}; DWORD cch = _countof(sub);
        if (RegEnumKeyEx(hServices, i, sub, &cch, nullptr, nullptr, nullptr, nullptr) == ERROR_NO_MORE_ITEMS) break;

        HKEY hSrv = nullptr;
        if (RegOpenKeyEx(hServices, sub, 0, KEY_READ, &hSrv) != ERROR_SUCCESS) continue;

        TCHAR group[64] = {0}; DWORD cb = sizeof(group); DWORD type = 0;
        LONG lr = RegQueryValueEx(hSrv, TEXT("Group"), nullptr, &type, (LPBYTE)group, &cb);
        if (lr != ERROR_SUCCESS || _tcscmp(group, TEXT("Video")) != 0) { RegCloseKey(hSrv); continue; }

        HKEY hSrvEnum = nullptr;
        if (RegOpenKeyEx(hSrv, TEXT("Enum"), 0, KEY_READ, &hSrvEnum) != ERROR_SUCCESS) { RegCloseKey(hSrv); continue; }

        DWORD count = 0; cb = sizeof(count);
        if (RegQueryValueEx(hSrvEnum, TEXT("Count"), nullptr, &type, (LPBYTE)&count, &cb) != ERROR_SUCCESS)
        { RegCloseKey(hSrvEnum); RegCloseKey(hSrv); continue; }

        outCount = count;
        for (DWORD j = 0; j < count; ++j)
        {
            TCHAR idxStr[32]; wsprintf(idxStr, TEXT("%u"), j);
            TCHAR path[512] = {0}; cb = sizeof(path);
            if (RegQueryValueEx(hSrvEnum, idxStr, nullptr, &type, (LPBYTE)path, &cb) != ERROR_SUCCESS) continue;

            HKEY hDev = nullptr;
            if (RegOpenKeyEx(hEnum, path, 0, KEY_READ, &hDev) != ERROR_SUCCESS) continue;

            TCHAR name[512] = {0}; DWORD cbb = sizeof(name);
            if (RegQueryValueEx(hDev, TEXT("FriendlyName"), nullptr, &type, (LPBYTE)name, &cbb) != ERROR_SUCCESS)
            {
                cbb = sizeof(name);
                if (RegQueryValueEx(hDev, TEXT("DeviceDesc"), nullptr, &type, (LPBYTE)name, &cbb) != ERROR_SUCCESS) name[0] = 0;
            }
            outNames[j] = name;
            RegCloseKey(hDev);
        }

        RegCloseKey(hSrvEnum);
        RegCloseKey(hSrv);
        break; // first matching video service is enough
    }

    RegCloseKey(hEnum);
    RegCloseKey(hServices);
}

Notes

  • The registry-based CPU/GPU detection is fast and broadly compatible across Windows NT family versions.
  • NIC enumeration via HKEY_PERFORMANCE_DATA reads the "Network Interface" performance object (index 510) and its "Current Bandwidth" counter (index 520).
  • For memory, GlobalMemoryStatusEx is preferable on modern systems, but GlobalMemoryStatus is maintained above for compatibility with the original data types.

WMI-based approach

WMI (Windows Menagement Instrumentation) exposes a uniform model for OS and hardware. Its easy to query but typically slower than direct Win32/registry calls.

WmiClient.h

#pragma once

#include <atlbase.h>
#include <afxpriv.h>
#include <WbemIdl.h>
#pragma comment(lib, "WbemUuid.lib")

class WmiClient
{
public:
    WmiClient() : m_svc(nullptr), m_loc(nullptr), m_enum(nullptr), m_obj(nullptr) {}
    ~WmiClient() {}

    HRESULT Initialize();
    HRESULT Shutdown();

    BOOL QuerySingle(CString wmiClass, CString member, CString& outValue);
    BOOL QueryFields(CString wmiClass, CString members[], int count, CString& outJoined);

private:
    void VariantToCString(const VARIANT* v, CString& out) const;

private:
    IWbemServices*        m_svc;
    IWbemLocator*         m_loc;
    IEnumWbemClassObject* m_enum;
    IWbemClassObject*     m_obj;
};

WmiClient.cpp

#include "StdAfx.h"
#include "WmiClient.h"

HRESULT WmiClient::Initialize()
{
    HRESULT hr = CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr) && hr != RPC_E_CHANGED_MODE) return hr;

    hr = CoInitializeSecurity(
        nullptr,
        -1,
        nullptr,
        nullptr,
        RPC_C_AUTHN_LEVEL_PKT,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        nullptr,
        EOAC_NONE,
        nullptr);
    // proceed even if RPC_E_TOO_LATE etc.

    hr = CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (void**)&m_loc);
    if (FAILED(hr)) return hr;

    hr = m_loc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"), nullptr, nullptr, 0, 0, 0, 0, &m_svc);
    if (FAILED(hr)) return hr;

    hr = CoSetProxyBlanket(
        m_svc,
        RPC_C_AUTHN_WINNT,
        RPC_C_AUTHZ_NONE,
        nullptr,
        RPC_C_AUTHN_LEVEL_CALL,
        RPC_C_IMP_LEVEL_IMPERSONATE,
        nullptr,
        EOAC_NONE);
    return hr;
}

HRESULT WmiClient::Shutdown()
{
    if (m_enum) { m_enum->Release(); m_enum = nullptr; }
    if (m_obj)  { m_obj->Release();  m_obj  = nullptr; }
    if (m_svc)  { m_svc->Release();  m_svc  = nullptr; }
    if (m_loc)  { m_loc->Release();  m_loc  = nullptr; }
    CoUninitialize();
    return S_OK;
}

BOOL WmiClient::QuerySingle(CString wmiClass, CString member, CString& outValue)
{
    outValue.Empty();
    if (!m_svc) return FALSE;

    CComBSTR q(L"SELECT * FROM "); q += CComBSTR(wmiClass);
    HRESULT hr = m_svc->ExecQuery(CComBSTR(L"WQL"), q,
                                  WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                                  nullptr, &m_enum);
    if (FAILED(hr)) return FALSE;

    VARIANT v; VariantInit(&v);
    ULONG fetched = 0;
    BOOL ok = FALSE;

    hr = m_enum->Next(WBEM_INFINITE, 1, &m_obj, &fetched);
    if (SUCCEEDED(hr) && fetched == 1)
    {
        hr = m_obj->Get(CComBSTR(member), 0, &v, nullptr, nullptr);
        if (SUCCEEDED(hr)) { VariantToCString(&v, outValue); ok = TRUE; }
        VariantClear(&v);
    }

    if (m_obj)  { m_obj->Release();  m_obj  = nullptr; }
    if (m_enum) { m_enum->Release(); m_enum = nullptr; }
    return ok;
}

BOOL WmiClient::QueryFields(CString wmiClass, CString members[], int count, CString& outJoined)
{
    outJoined.Empty();
    if (!m_svc) return FALSE;

    CComBSTR q(L"SELECT * FROM "); q += CComBSTR(wmiClass);
    HRESULT hr = m_svc->ExecQuery(CComBSTR(L"WQL"), q,
                                  WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                                  nullptr, &m_enum);
    if (FAILED(hr)) return FALSE;

    VARIANT v; VariantInit(&v);
    ULONG fetched = 0; BOOL ok = FALSE;
    hr = m_enum->Next(WBEM_INFINITE, 1, &m_obj, &fetched);
    if (SUCCEEDED(hr) && fetched == 1)
    {
        for (int i = 0; i < count; ++i)
        {
            CString piece;
            if (SUCCEEDED(m_obj->Get(CComBSTR(members[i]), 0, &v, nullptr, nullptr)))
            {
                VariantToCString(&v, piece);
                if (!outJoined.IsEmpty()) outJoined += _T("\t");
                outJoined += piece;
                VariantClear(&v);
                ok = TRUE;
            }
        }
        outJoined += _T("\r\n");
    }

    if (m_obj)  { m_obj->Release();  m_obj  = nullptr; }
    if (m_enum) { m_enum->Release(); m_enum = nullptr; }
    return ok;
}

void WmiClient::VariantToCString(const VARIANT* pv, CString& out) const
{
    USES_CONVERSION;
    out.Empty();
    switch (pv->vt)
    {
    case VT_BSTR:
        out = W2T(pv->bstrVal); break;
    case VT_BOOL:
        out = (pv->boolVal == VARIANT_TRUE) ? _T("yes") : _T("no"); break;
    case VT_I4:
        out.Format(_T("%ld"), pv->lVal); break;
    case VT_UI4:
        out.Format(_T("%lu"), pv->ulVal); break;
    case VT_UI1:
        out.Format(_T("%u"), pv->bVal); break;

    case (VT_BSTR | VT_ARRAY):
    {
        CComBSTR HUGEP* pData = nullptr;
        if (SUCCEEDED(SafeArrayAccessData(pv->parray, (void HUGEP**)&pData)))
        {
            out = W2T(pData->m_str);
            SafeArrayUnaccessData(pv->parray);
        }
        break;
    }
    case (VT_I4 | VT_ARRAY):
    {
        BYTE HUGEP* pData = nullptr;
        LONG lo = 0, hi = 0;
        SafeArrayGetLBound(pv->parray, 1, &lo);
        SafeArrayGetUBound(pv->parray, 1, &hi);
        if (SUCCEEDED(SafeArrayAccessData(pv->parray, (void HUGEP**)&pData)))
        {
            CString t;
            hi = min<LONG>(hi, MAX_PATH * 2 - 1);
            for (LONG i = lo; i <= hi; ++i) { t.Format(_T("%02X"), pData[i]); out += t; }
            SafeArrayUnaccessData(pv->parray);
        }
        break;
    }
    default:
        break;
    }
}

Usage sequence

  • Construct WmiClient.
  • Call Initialize().
  • Invoke QuerySingle or QueryFields to retrieve properties from a WMI class.
  • Call Shutdown() when finished.

Examples

  • CPU name via WMI
    • Class: Win32_Processor
    • Property: Caption
    • Example: QuerySingle(_T("Win32_Processor"), _T("Caption"), value)
  • Multiple CPU properties
    • Properties array: {"Caption", "CurrentClockSpeed", "DeviceID", "Manufacturer"}
    • Example: QueryFields(_T("Win32_Processor"), arr, 4, value)

Frequently used WMI classes

Hardware

  • Win32_Processor
  • Win32_PhysicalMemory
  • Win32_Keyboard
  • Win32_PointingDevice
  • Win32_FloppyDrive
  • Win32_DiskDrive
  • Win32_CDROMDrive
  • Win32_BaseBoard
  • Win32_BIOS
  • Win32_ParallelPort
  • Win32_SerialPort
  • Win32_SerialPortConfiguration
  • Win32_SoundDevice
  • Win32_SystemSlot
  • Win32_USBController
  • Win32_NetworkAdapter
  • Win32_NetworkAdapterConfiguration
  • Win32_Printer
  • Win32_PrinterConfiguration
  • Win32_PrintJob
  • Win32_TCPIPPrinterPort
  • Win32_POTSModem
  • Win32_POTSModemToSerialPort
  • Win32_DesktopMonitor
  • Win32_DisplayConfiguration
  • Win32_DisplayControllerConfiguration
  • Win32_VideoController
  • Win32_VideoSettings

Operating system

  • Win32_TimeZone
  • Win32_SystemDriver
  • Win32_DiskPartition
  • Win32_LogicalDisk
  • Win32_LogicalDiskToPartition
  • Win32_LogicalMemoryConfiguration
  • Win32_PageFile
  • Win32_PageFileSetting
  • Win32_BootConfiguration
  • Win32_ComputerSystem
  • Win32_OperatingSystem
  • Win32_StartupCommand
  • Win32_Service
  • Win32_Group
  • Win32_GroupUser
  • Win32_UserAccount
  • Win32_Process
  • Win32_Thread
  • Win32_Share
  • Win32_NetworkClient
  • Win32_NetworkProtocol

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.