Skip to content

Instantly share code, notes, and snippets.

@KunYi
Created November 26, 2019 02:50
Show Gist options
  • Save KunYi/fd01081818463374674f2c3c21e5aac0 to your computer and use it in GitHub Desktop.
Save KunYi/fd01081818463374674f2c3c21e5aac0 to your computer and use it in GitHub Desktop.
WMI - MSPower_DeviceEnable demo
#include "stdafx.h"
#include <atlbase.h>
#include <atlstr.h>
#include <stdio.h>
#include <wbemidl.h> // For WMI
#pragma comment(lib, "wbemuuid.lib") // Link to WMI library.
// ref.
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/creating-a-wmi-application-using-c-
int main() {
// Step 1. Initialize COM.
HRESULT hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr)) {
printf("Failed, called CoInitializeEx(), return:0x%X\r\n", hr);
return -1;
}
// NOTE:
// When using asynchronous WMI API's remotely in an environment where the "Local System" account
// has no network identity (such as non-Kerberos domains), the authentication level of
// RPC_C_AUTHN_LEVEL_NONE is needed. However, lowering the authentication level to
// RPC_C_AUTHN_LEVEL_NONE makes your application less secure. It is wise to
// use semi-synchronous API's for accessing WMI data and events instead of the asynchronous ones.
hr = ::CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE,
NULL, EOAC_NONE, NULL);
if (FAILED(hr)) {
printf("Failed, called CoInitializeSecurity(), return:0x%X\r\n", hr);
goto CleanUp;
}
{
// Step 2. Create a connection to a WMI namespace.
CComPtr<IWbemLocator> pWbemLocator;
hr = pWbemLocator.CoCreateInstance(CLSID_WbemLocator);
if (FAILED(hr)) {
printf("Failed, called CoCreateInstance(), return:0x%X\r\n", hr);
goto CleanUp;
}
// connect to namespace root\wmi
CComPtr<IWbemServices> pWbemServices;
hr = pWbemLocator->ConnectServer(CComBSTR(L"root\\wmi"), NULL, NULL, 0, NULL, 0, NULL, &pWbemServices);
if (FAILED(hr)) {
printf("Failed, called ConnectServer(), return:0x%X\r\n", hr);
goto CleanUp;
}
// Step 3. Set the security levels on the WMI connection.
// setting proxy security
CComPtr<IClientSecurity> pClientSecurity;
hr = pWbemServices->QueryInterface(IID_IClientSecurity, (void **)&pClientSecurity);
if (FAILED(hr)) {
printf("Failed, called QueryInterface(IID_IClientSecurity), return:0x%X\r\n", hr);
goto CleanUp;
}
hr = pClientSecurity->SetBlanket(pWbemServices,
RPC_C_AUTHN_WINNT,
RPC_C_AUTHZ_NONE,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
NULL,
EOAC_NONE);
// Step 4. Implement the purpose of your application.
CComPtr<IEnumWbemClassObject> pEnum;
hr = pWbemServices->ExecQuery(CComBSTR(L"WQL"),
CComBSTR(L"Select * FROM MSPower_DeviceEnable"),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnum);
do {
CComPtr<IWbemClassObject> pObj;
ULONG uReturned = 0;
CStringW prefix = L"\"PCI\\\\VEN_8086&DEV_9D";
hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned);
if (hr == WBEM_S_NO_ERROR) {
CComBSTR bstrObj;
pObj->GetObjectText(0, &bstrObj);
CStringW find(bstrObj);
if (int n = find.Find(prefix) > 0) {
CStringW i2cs[] = {
L"\"PCI\\\\VEN_8086&DEV_9DC5",
L"\"PCI\\\\VEN_8086&DEV_9DC6",
L"\"PCI\\\\VEN_8086&DEV_9DE8",
L"\"PCI\\\\VEN_8086&DEV_9DE9",
L"\"PCI\\\\VEN_8086&DEV_9DEA",
L"\"PCI\\\\VEN_8086&DEV_9DEB"
};
for each (CStringW dev in i2cs) {
if (find.Find(dev, n - 1) > 0) {
CComVariant vtProp;
CComBSTR en(L"Enable");
// only for debug
// wprintf(L"%s\n\n", (LPWSTR)bstrObj);
if (WBEM_S_NO_ERROR == pObj->Get(en, 0, &vtProp, NULL, NULL)) {
if (vtProp.boolVal != VARIANT_FALSE) {
vtProp.boolVal = VARIANT_FALSE;
hr = pObj->Put(en, 0, &vtProp, CIM_BOOLEAN);
// Update Instance
// https://docs.microsoft.com/en-us/windows/win32/wmisdk/updating-an-entire-instance
// need administrator permission if got WBEM_E_ACCESS_DENIED (0x80041003)
hr = pWbemServices->PutInstance(pObj, WBEM_FLAG_UPDATE_ONLY, NULL, NULL);
}
}
}
}
}
}
pObj = NULL;
} while (hr == WBEM_S_NO_ERROR);
}
// Step 5. Cleanup and shut down your application.
CleanUp:
CoUninitialize();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment