Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


WMI Provider EvtWmiInstanceSetInstance not called if class has string members

Shane_CorbinShane_Corbin Member Posts: 265
edited November 16 in NTDEV

I had a WMI provider class working fine with user space such that it could read and write members of the provider class. I then needed to add a couple members of type string. Once I added these new members to the class my EvtWmiInstanceQueryInstance callback still works fine, but my EvtWmiInstanceSetInstance callback doesn't get called any more. If I set a breakpoint on the call to this callback it never gets hit.

What would cause this behavior? And better yet, how do I resolve it?

Here's how I'm attempting to modify my WMI object:

$ci = get-ciminstance My_WMIClass -Namespace "root/wmi"

$ci.NormalMember= 10
Set-CimInstance -CimInstance $ci -PassThru

This works just fine if my class doesn't have any members of type string. When I add a string member I get the following error when I call Set-CimInstance -CimInstance $ci -PassThru:

Set-CimInstance : Generic failure 
At line:5 char:1
+ Set-CimInstance -CimInstance $ci -PassThru
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (My_WMIClass...5&7047288&8...):CimInstance) [Set-CimInsta 
   nce], CimException
    + FullyQualifiedErrorId : HRESULT 0x80041001,Microsoft.Management.Infrastructure.CimCmdlets.SetCimIns 
   tanceCommand
Post edited by Shane_Corbin on

Comments

  • Shane_CorbinShane_Corbin Member Posts: 265
    edited November 16

    My query call is working fine. The strings have the read attribute set in the .mof like so:

        [WmiDataId(8),
         read,
         Description("Description"),
         MaxLen(511)]
        string Description;
    

    I can set my description in my driver and read it in PowerShell with this command just fine:

    get-ciminstance My_WMIClass -Namespace "root/wmi"
    

    The problem I'm facing now is that I can't write to ANY members of my class. For example I have another member defined in the .mof as:

        [WmiDataId(4),
         read,
         write,
         Description("Scratch value to practice reading and writing")]
        uint32 scratch;
    

    If I don't add Description to my class I can read/write scratch from PowerShell just fine. If I add Description to my class I can read scratch fine, but I can no longer write a new scratch value. It results in the error I have shown in my previous post.

  • ThatsBerkanThatsBerkan Member Posts: 17
    edited November 16

    From my understanding, if your WMI class contains a read-only item, then you will have to set a single item everytime, when modifying a field, instead of setting the entire instance.

    Please setup a EvtWmiInstanceSetItem function and try again.

  • Shane_CorbinShane_Corbin Member Posts: 265

    I have other read only items in the class that are of type uint32 and I am still able to set the entire instance. It's only since I added the string members that things fell apart. I suppose I can try that though.

  • Shane_CorbinShane_Corbin Member Posts: 265

    Any idea how to set a single item from PowerShell? No matter what I do it seems to call the EvtWmiInstanceSetInstance callback.

  • ThatsBerkanThatsBerkan Member Posts: 17

    You might want to share some code that is related to your issue, otherwise it is going to be like your last post in March asking about the same issue.
    It is a problem with your code (obviously). We can't do anything without knowing even the most basics parts of your wmi config structure setup.

    https://community.osr.com/discussion/291918/use-powershell-to-call-wmi-evtwmiinstancesetitem

  • Shane_CorbinShane_Corbin Member Posts: 265

    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.

  • Scott_Noone_(OSR)Scott_Noone_(OSR) Administrator Posts: 3,362

    Have you tried playing with the Toaster and WMI? It has read/write members with descriptions. If you get the same problems there you'll at least know it's not you.

    https://github.com/microsoft/Windows-driver-samples/tree/master/general/toaster/toastDrv/kmdf/func/featured

    -scott
    OSR

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Writing WDF Drivers 7 Dec 2020 LIVE ONLINE
Internals & Software Drivers 25 Jan 2021 LIVE ONLINE
Developing Minifilters 8 March 2021 LIVE ONLINE