c++powershellwmiprovider

wmi provider instance not created (ResultCode = 0x800706BE)


I have installed an instance provider according to the following description:

https://learn.microsoft.com/en-us/windows/win32/wmisdk/supplying-data-to-wmi-by-writing-a-provider

It was registered with regsvr32 and an instance was created:

#PRAGMA AUTORECOVER
#PRAGMA NAMESPACE ("\\\\.\\Root\\MyNamespace")

instance of __Win32Provider as $P
{
    Name = "myprovider";
    CLSID = "{014D660A-59C4-483F-9F99-1237308B8E98}";
};


instance of __InstanceProviderRegistration
{
    Provider = $P;
    SupportsGet = TRUE;
    SupportsEnumeration = TRUE;
    SupportsPut = FALSE;
    SupportsDelete = FALSE;
    QuerySupportLevels;
};

When I start the Windows Powershell with administrator rights and execute the following command, it fails:

Get-WmiObject -Namespace "root/MyNamespace"  -Class "MyInfoClass"
Get-WmiObject :
At line:1 char:1
+ Get-WmiObject -Namespace "root/MyNamespace"  -Class "MyInfoClass"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], COMException
    + FullyQualifiedErrorId : GetWMICOMException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

The event log says:

Id = {ABDF9D5E-3FCE-000A-4B9F-DFABCE3FDB01}; ClientMachine = XYZ; User = XYZ\AnUser;
ClientProcessId = 3884; Component = Unknown; Operation = Start IWbemServices::ExecQuery - root\MyNamespace: select * from MyInfoClass; 
ResultCode = 0x800706BE; PossibleCause = Unknown

Based on the traces of my provider I can see that DllGetClassObject is called, the factory of type IClassFactory is created and the reference of the factory is set to 1 before it is returned. The last trace shows that the process WmiPrvSE.exe was terminated with 0xc0000005 (EXCEPTION_ACCESS_VIOLATION).

The CreateInstance method of the factory is never called.

Attempts with changed properties for __Win32Provider and __InstanceProviderRegistration did not help.

Even repairing the WMI repository using ‘winmgmt /resetrepository’ did nothing.

Does anyone have an idea where the problem could be?

Update:

Instead of the Windows Powershell I used a console programme to get the information from the provider. The error handling is missing here for the sake of clarity:

CoInitializeEx(
    nullptr,                //[in, optional] LPVOID pvReserved,
    COINIT_MULTITHREADED    //[in]           DWORD  dwCoInit
);

{
    CoInitializeSecurity(
        nullptr,                    //[in, optional] PSECURITY_DESCRIPTOR        pSecDesc,
        -1,                         //[in]           LONG                        cAuthSvc,
        nullptr,                    //[in, optional] SOLE_AUTHENTICATION_SERVICE * asAuthSvc,
        nullptr,                    //[in, optional] void* pReserved1,
        RPC_C_AUTHN_LEVEL_DEFAULT,  //[in]           DWORD                       dwAuthnLevel,
        RPC_C_IMP_LEVEL_IMPERSONATE,//[in]           DWORD                       dwImpLevel,
        nullptr,                    //[in, optional] void* pAuthList,
        EOAC_NONE,                  //[in]           DWORD                       dwCapabilities,
        nullptr                     //[in, optional] void* pReserved3
    );
   
    CComPtr<IWbemLocator> locator = nullptr;
    locator.CoCreateInstance(
        CLSID_WbemLocator,      //[in]  REFCLSID  rclsid,
        nullptr,                //[in]  LPUNKNOWN pUnkOuter,
        CLSCTX_INPROC_SERVER    //[in]  DWORD     dwClsContext
    );

    CComPtr<IWbemServices> myNamespace = nullptr;
    hr = locator->ConnectServer(
        bstr_t(L"\\\\.\\root\\MyNamespace"),    //[in]  const BSTR    strNetworkResource,
        nullptr,                                //[in]  const BSTR    strUser,
        nullptr,                                //[in]  const BSTR    strPassword,
        nullptr,                                //[in]  const BSTR    strLocale,
        0,                                      //[in]  long          lSecurityFlags,
        nullptr,                                //[in]  const BSTR    strAuthority,
        nullptr,                                //[in]  IWbemContext * pCtx,
        &myNamespace                            //[out] IWbemServices * *ppNamespace
    );

    CoSetProxyBlanket(
        myNamespace,                  //[in]           IUnknown * pProxy,
        RPC_C_AUTHN_WINNT,               //[in]           DWORD                    dwAuthnSvc,
        RPC_C_AUTHZ_NONE,               //[in]           DWORD                    dwAuthzSvc,
        nullptr,                        //[in, optional] OLECHAR * pServerPrincName,
        RPC_C_AUTHN_LEVEL_CALL,         //[in]           DWORD                    dwAuthnLevel,
        RPC_C_IMP_LEVEL_IMPERSONATE,    //[in]           DWORD                    dwImpLevel,
        nullptr,                        //[in, optional] RPC_AUTH_IDENTITY_HANDLE pAuthInfo,
        EOAC_NONE                       //[in]           DWORD                    dwCapabilities
    );

    CComPtr<IEnumWbemClassObject> enumerator = nullptr;
    myNamespace->ExecQuery(
        bstr_t(L"WQL"),                                             //[in]  const BSTR           strQueryLanguage,
        bstr_t(L"SELECT * FROM MyInfoClass"),                       //[in]  const BSTR           strQuery,
        (WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY),    //[in]  long                 lFlags,
        nullptr,                                                    //[in]  IWbemContext * pCtx,
        &enumerator                                                 //[out] IEnumWbemClassObject * *ppEnum
    );
    
    ULONG returnedObjCount = 0;
    for (;;) {

        CComPtr<IWbemClassObject> classObj = nullptr;
        enumerator->Next(
            WBEM_INFINITE,      ///* [in] */ long lTimeout,
            1,                  ///* [in] */ ULONG uCount,
            &classObj,          ///* [length_is][size_is][out] */ __RPC__out_ecount_part(uCount, *puReturned) IWbemClassObject * *apObjects,
            &returnedObjCount   ///* [out] */ __RPC__out ULONG * puReturned
        );
        
        !!! => ERROR 0x800706BE

        ...        
    }
}

CoUninitialize();

I also extended the access rights to the namespace ‘MyNamespace’ using the management console as a test. No success. The use of existing namespaces, such as ‘cimv2’ or ‘default’, also had no effect.

To see if the code works in general, I queried another WMI provider:

SELECT * FROM Win32_Process (in namespace cimv2).

This worked without any problems!?

What could be the reason that my provider is already rejected before it can do anything?


Solution

  • The error 0x800706BE is apparently quite commonly used by the WMI framework, if you look at the various reports on the Internet. Unfortunately, the event logs are also unusable.

    In my case, the cause was ultimately quite simple. When restructuring the sample code in https://learn.microsoft.com/en-us/windows/win32/wmisdk/supplying-data-to-wmi-by-writing-a-provider, I had built in an error: The method DllGetClassObject deleted the factory after its use even if QueryInterface was successful. As a result, the CreateInstance method could of course never be called.