Here’s the .mof
#PRAGMA AUTORECOVER
[WMI,
Dynamic,
Provider("WmiProv"),
Locale("MS\\0x409"),
Description("My WMI Class with confidential info removed") : amended,
guid("82DE1B9F-C0EC-4BA4-B81E-D6B9C9EDD2D3")]
class My_WMIClass
{
[key, read]
string InstanceName;
[read]
boolean Active;
[WmiDataId(1),
read,
write,
Description("R/W integer values")]
uint32 NormalMember;
[WmiDataId(2),
read,
Description("Description"),
MaxLen(511)]
string Description;
};
Here’s the header:
// WMI method
#define My_WMIClass _GUID)\
{ 0x82de1b9f,0xc0ec,0x4ba4, { 0xb8,0x1e,0xd6,0xb9,0xc9,0xed,0xd2,0xd3 } }
#if ! (defined(MIDL_PASS))
DEFINE_GUID(My_WMIClass _GUID), \
0x82de1b9f, 0xc0ec, 0x4ba4, 0xb8, 0x1e, 0xd6, 0xb9, 0xc9, 0xed, 0xd2, 0xd3);
#endif
typedef struct _My_WMIClass
{
// Normal integer member
ULONG NormalMember;
#define My_WMIClass_NormalMember_SIZE sizeof(ULONG)
#define My_WMIClass_NormalMember_ID 1
// Description
WCHAR Description[511 + 1];
#define My_WMIClass_Description_ID 2
}My_WMIClass, *PMy_WMIClass;
#define My_WMIClass_SIZE (FIELD_OFFSET(My_WMIClass, NormalMember) + sizeof(WCHAR)*512)
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(My_WMIClass, MyWmiGetData);
Here’s the registration:
NTSTATUS register_wmi_provider(
_In_ WDFDEVICE device
)
{
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES woa;
WDF_WMI_PROVIDER_CONFIG providerConfig;
WDF_WMI_INSTANCE_CONFIG instanceConfig;
DECLARE_CONST_UNICODE_STRING(mofResourceName, MOFRESOURCENAME);
PAGED_CODE();
//
// Register the MOF resource names of any customized WMI data providers
// that are not defined in wmicore.mof.
//
status = WdfDeviceAssignMofResourceName(device, &mofResourceName);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_WMI,
"WdfDeviceAssignMofResourceName failed 0x%x", status);
return status;
}
WDF_WMI_PROVIDER_CONFIG_INIT(&providerConfig, &My_WMIClass_GUID);
providerConfig.MinInstanceBufferSize = My_WMIClass_SIZE;
WDF_WMI_INSTANCE_CONFIG_INIT_PROVIDER_CONFIG(&instanceConfig, &providerConfig);
instanceConfig.Register = TRUE;
instanceConfig.EvtWmiInstanceQueryInstance = wmi_instance_query;
instanceConfig.EvtWmiInstanceSetInstance = wmi_instance_set;
instanceConfig.EvtWmiInstanceSetItem = wmi_item_set;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&woa, My_WMIClass );
//
// No need to get the newly created handle because we just reference data
// from our device extension directly.
//
status = WdfWmiInstanceCreate(device,
&instanceConfig,
&woa,
WDF_NO_HANDLE);
if (!NT_SUCCESS(status)) {
TraceEvents(TRACE_LEVEL_ERROR, TRACE_WMI,
"WdfWmiInstanceCreate failed 0x%x", status);
return status;
}
return status;
}
If I remove the Description
property, the following PowerShell works:
$x = get-ciminstance MY_WMIClass -Namespace "root/wmi"
$x.NormalMember = 42
Set-CimInstance -CimInstance $x -PassThru
As stated previously, as soon as I add the Description
property any attempt to update the instance fails. I have tried changing providerConfig.MinInstanceBufferSize
and that doesn’t change the observed behavior.
I still haven’t figured out how to use PowerShell such that it calls my EvtWmiInstanceSetItem
callback.