wmi 提供程序实例未创建(ResultCode = 0x800706BE)

问题描述 投票:0回答:1

我已经根据以下描述安装了实例提供程序:

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

它已注册到 regsvr32 并创建了一个实例:

#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;
};

当我以管理员权限启动 Windows Powershell 并执行以下命令时,失败:

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

事件日志显示:

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

根据我的提供程序的跟踪,我可以看到调用了 DllGetClassObject,创建了 IClassFactory 类型的工厂,并且在返回之前将工厂的引用设置为 1。最后的跟踪显示进程 WmiPrvSE.exe 已终止,代码为 0xc0000005 (EXCEPTION_ACCESS_VIOLATION)。

工厂的 CreateInstance 方法永远不会被调用。

尝试更改 __Win32Provider 和 __InstanceProviderRegistration 的属性没有帮助。

即使使用“winmgmt /resetrepository”修复 WMI 存储库也无济于事。

有人知道问题出在哪里吗?

更新:

我没有使用 Windows Powershell,而是使用控制台程序从提供商处获取信息。为了清楚起见,这里缺少错误处理:

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();

我还使用管理控制台扩展了对命名空间“MyNamespace”的访问权限作为测试。没有成功。使用现有的命名空间,例如“cimv2”或“default”,也没有效果。

为了查看代码是否正常工作,我查询了另一个 WMI 提供程序:

SELECT * FROM Win32_Process(在命名空间 cimv2 中)。

这工作没有任何问题!?

我的提供商在采取任何行动之前就已被拒绝,这可能是什么原因?

c++ powershell wmi provider
1个回答
0
投票

如果您查看互联网上的各种报告,错误 0x800706BE 显然是 WMI 框架非常常用的。不幸的是,事件日志也无法使用。

就我而言,原因最终非常简单。当重构https://learn.microsoft.com/en-us/windows/win32/wmisdk/supplying-data-to-wmi-by-writing-a-provider中的示例代码时,我构建了一个错误: 即使 QueryInterface 成功,DllGetClassObject 方法在使用后也会删除工厂。因此,CreateInstance 方法当然永远不会被调用。

© www.soinside.com 2019 - 2024. All rights reserved.