I'm trying to read UWF status through the WMI provider in my C++ application, but it doesn't seem to give me correct values. (Everything is false/zero.)
When I go through the same interface in PowerShell, it works. Just not sure what I'm doing wrong on the C++ side. HRESULT
doesn't give any errors.
C++ code
#include <iostream>
#define _WIN32_DCOM
#include <comdef.h>
#include <wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
// https://learn.microsoft.com/en-us/windows/win32/wmisdk/example--calling-a-provider-method
// https://learn.microsoft.com/en-us/windows-hardware/customize/enterprise/uwf-wmi-provider-reference
int foo() {
HRESULT hres;
// Initialize COM
hres = CoInitializeEx(0, COINIT_MULTITHREADED);
if (FAILED(hres)) {
return 1;
}
// Set COM security levels
hres = CoInitializeSecurity(
NULL,
-1, // COM negotiates service
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)) {
CoUninitialize();
return 2;
}
// Obtain initial locator to WMI
IWbemLocator* pLoc = nullptr;
hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator,
(LPVOID*)&pLoc
);
if (FAILED(hres)) {
CoUninitialize();
return 3;
}
// Connect to namespace
IWbemServices* pSvc = nullptr;
hres = pLoc->ConnectServer(
_bstr_t(L"root\\standardcimv2\\embedded"),
NULL,
NULL,
0,
NULL,
0,
0,
&pSvc
);
if (FAILED(hres)) {
pLoc->Release();
CoUninitialize();
return 4;
}
// Set security levels for 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)) {
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 5;
}
// Get UWF_Filter instance
BSTR ClassName = SysAllocString(L"UWF_Filter");
IWbemClassObject* pClass = nullptr;
hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
if (FAILED(hres)) {
return 6;
}
// Get property values
// https://learn.microsoft.com/en-us/windows/win32/api/wbemcli/nf-wbemcli-iwbemclassobject-get
VARIANT TempPropertyVal;
hres = pClass->Get(_bstr_t(L"CurrentEnabled"), 0, &TempPropertyVal, NULL, 0);
bool TempCurrentEnabled = TempPropertyVal.boolVal;
VariantClear(&TempPropertyVal);
if (FAILED(hres)) {
return 7;
}
hres = pClass->Get(_bstr_t(L"NextEnabled"), 0, &TempPropertyVal, NULL, 0);
bool TempNextEnabled = TempPropertyVal.boolVal;
VariantClear(&TempPropertyVal);
if (FAILED(hres)) {
return 8;
}
std::cout << "current session is " << (TempCurrentEnabled ? "enabled" : "disabled") << "\n";
std::cout << "next session is " << (TempNextEnabled ? "enabled" : "disabled") << "\n";
pClass->Release();
pClass = nullptr;
SysFreeString(ClassName);
// Get UWF_Filter instance
ClassName = SysAllocString(L"UWF_Overlay");
hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL);
if (FAILED(hres)) {
return 9;
}
// Get property values
hres = pClass->Get(_bstr_t(L"AvailableSpace"), 0, &TempPropertyVal, NULL, 0);
long TempAvailableSpace = TempPropertyVal.lVal;
VariantClear(&TempPropertyVal);
if (FAILED(hres)) {
return 10;
}
hres = pClass->Get(_bstr_t(L"OverlayConsumption"), 0, &TempPropertyVal, NULL, 0);
long TempOverlayConsumption = TempPropertyVal.lVal;
VariantClear(&TempPropertyVal);
if (FAILED(hres)) {
return 11;
}
hres = pClass->Get(_bstr_t(L"WarningOverlayThreshold"), 0, &TempPropertyVal, NULL, 0);
long TempWarningOverlayThreshold = TempPropertyVal.lVal;
VariantClear(&TempPropertyVal);
if (FAILED(hres)) {
return 12;
}
std::cout << "current available space: " << TempAvailableSpace << "\n";
std::cout << "current overlay consumption: " << TempOverlayConsumption << "\n";
std::cout << "current warning threshold: " << TempWarningOverlayThreshold << "\n";
pClass->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
SysFreeString(ClassName);
return 0;
}
int main()
{
std::cout << foo();
std::cout << "\n";
return 0;
}
Output
current session is disabled
next session is disabled
current available space: 0
current overlay consumption: 0
current warning threshold: 0
0
PowerShell code
Get-WmiObject -namespace "root\standardcimv2\embedded" -class UWF_Filter;
Get-WmiObject -namespace "root\standardcimv2\embedded" -class UWF_Overlay;
Output
__GENUS : 2
__CLASS : UWF_Filter
__SUPERCLASS :
__DYNASTY : UWF_Filter
__RELPATH : UWF_Filter.Id="UWF_Filter"
__PROPERTY_COUNT : 5
__DERIVATION : {}
__SERVER : localhost
__NAMESPACE : root\standardcimv2\embedded
__PATH : \\localhost\root\standardcimv2\embedded:UWF_Filter.Id="UWF_Filter"
CurrentEnabled : True
HORMEnabled : False
Id : UWF_Filter
NextEnabled : True
ShutdownPending : False
PSComputerName : localhost
__GENUS : 2
__CLASS : UWF_Overlay
__SUPERCLASS :
__DYNASTY : UWF_Overlay
__RELPATH : UWF_Overlay.Id="UWF_Overlay"
__PROPERTY_COUNT : 5
__DERIVATION : {}
__SERVER : localhost
__NAMESPACE : root\standardcimv2\embedded
__PATH : \\localhost\root\standardcimv2\embedded:UWF_Overlay.Id="UWF_Overlay"
AvailableSpace : 917
CriticalOverlayThreshold : 2040
Id : UWF_Overlay
OverlayConsumption : 2155
WarningOverlayThreshold : 2032
PSComputerName : localhost