【问题标题】:Anyone made DCOM working with CoCreateInstanceEx in Windows 7任何人都让 DCOM 在 Windows 7 中使用 CoCreateInstanceEx
【发布时间】:2013-05-03 13:32:23
【问题描述】:

我受够了尝试实例化远程对象。

已使用 dcomcnfg,已启用对所有 Windows 7、相同工作组 PC 的访问。

CoInitializeEx(0,COINIT_APARTMENTTHREADED);
CoInitializeSecurity(0, -1, NULL, NULL,RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
COAUTHINFO ca = {0};
ca.dwAuthnSvc = RPC_C_AUTHN_WINNT;
ca.dwAuthzSvc = RPC_C_AUTHZ_NONE;
ca.dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
ca.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
COAUTHIDENTITY id = {0};
ca.pAuthIdentityData = &id;
id.User = (USHORT*)<username>;
id.UserLength = length;
id.Password = (USHORT*)<password>;
id.PasswordLength = pwdlength;
id.Domain = (USHORT*)L"WORKGROUP";
id.DomainLength = 9;
id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COSERVERINFO c = {0};
c.pwszName = L"192.168.10.3";
c.pAuthInfo = &ca;
MULTI_QI res = {0};
res.pIID = &TheIID;
HRESULT hr = CoCreateInstanceEx(TheCLSID,0,CLSCTX_REMOTE_SERVER,&c,1,&res);

总是 E_ACCESSDENIED。顺便说一下,这个示例 (http://support.microsoft.com/kb/259011) 有效。但我找不到它的来源。

服务器还调用 CoInitializeSecurity() 具有相同的级别。

以 Windows XP 计算机为目标时,CoCreateInstanceEx() 返回 S_OK,但未创建服务器。针对 Windows 7 时,E_ACCESSDENIED。

有什么线索吗? 此外,工作示例不使用 U+P。或许我应该试试匿名电话?

【问题讨论】:

    标签: com ole dcom


    【解决方案1】:

    我有它的工作...

    我对您的代码示例有一些观察:

    • 您在 CoInitializeSecurity 中对 SOLE_AUTHENTICATION_LIST 使用 NULL;我用与 CoCreateInstanceEx 相同的凭据填写它

    • 您使用 RPC_C_AUTHN_LEVEL_DEFAULT;我使用 RPC_C_AUTHN_LEVEL_CONNECT

    希望这会有所帮助。我是否可以建议您将 DCOM 作为标签添加到您的问题中……这将向您展示与 DCOM 相关的问题。这对我也有帮助。

        SEC_WINNT_AUTH_IDENTITY authIdent;
        std::wstring domain = string_cast<std::wstring>(commandLineOptions["domain"].as<std::string>());
        std::wstring username = string_cast<std::wstring>(commandLineOptions["username"].as<std::string>());
        std::wstring password = string_cast<std::wstring>(commandLineOptions["password"].as<std::string>());
        authIdent.Domain = reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(domain.c_str()));
        authIdent.DomainLength = wcslen(reinterpret_cast<const wchar_t*>(authIdent.Domain));
        authIdent.User = reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(username.c_str()));
        authIdent.UserLength = wcslen(reinterpret_cast<const wchar_t*>(authIdent.User));
        authIdent.Password = reinterpret_cast<unsigned short*>(const_cast<wchar_t*>(password.c_str()));
        authIdent.PasswordLength = wcslen(reinterpret_cast<const wchar_t*>(authIdent.Password));
        authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
    
        /*
        SOLE_AUTHENTICATION_INFO authInfo[2];
        authInfo[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
        authInfo[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
        authInfo[0].pAuthInfo = &authIdent;
    
        authInfo[1].dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS;
        authInfo[1].dwAuthzSvc = RPC_C_AUTHZ_NONE;
        authInfo[1].pAuthInfo = &authIdent;
    
        SOLE_AUTHENTICATION_LIST authList;
        authList.cAuthInfo = 2;
        authList.aAuthInfo = authInfo;
        */
    
        SOLE_AUTHENTICATION_INFO authInfo[1];
        authInfo[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
        authInfo[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
        authInfo[0].pAuthInfo = &authIdent;
    
        SOLE_AUTHENTICATION_LIST authList;
        authList.cAuthInfo = 1;
        authList.aAuthInfo = authInfo;
    
    
        HRESULT hr = CoInitializeSecurity(
            nullptr,                     // pVoid
            -1,                          // cAuthSvc
            nullptr,                     // asAuthSvc
            nullptr,                     // pReserved1,
            RPC_C_AUTHN_LEVEL_CONNECT,   // dwAuthnLevel,
            RPC_C_IMP_LEVEL_IMPERSONATE, // dwImpLevel,
            &authList,                   // pAuthList,
            EOAC_NONE,                   // dwCapabilities,
            nullptr);                    // pReserved3
    

    【讨论】:

    • 感谢您的回答。它仍然因 E_ACCESSDENIED 而失败。 :(
    • 我想你在 authIdent 中使用的用户是在服务器上定义的,你给了它 RemoteAccess、RemoteLaunch 和 RemoteActivate 权限。另外,我注意到您的代码中还有其他内容:您将工作组用作域。我只是使用了服务器的名称,因为 afaik 工作组与用户凭据没有任何关系。用户可以在域中或本地计算机上进行管理。试试看,让我知道。
    • 哦,还要检查防火墙没有以任何方式入侵。
    • 我设法让它工作,实际上它需要明确允许用户名“每个人”并不像看起来那样包括每个人。此外,它需要 CoSetProxyBlanket 用于所有返回的接口(以及您稍后查询的接口)。
    • 我不能说任何关于每个人的事情......我认为它应该可以工作,但我认为它不包括匿名(未经身份验证的)用户。我在配置中所做的是授予分布式 COM 用户组权限并将我想要的用户添加到该组。您需要为所有返回的接口设置 CoSetProxyBlanket 的事实表明您的 CoInitializeSecurity 有问题。事实上,这就是我发现在我的情况下 CoInitializeSecurity 没有足够快地调用的原因。
    【解决方案2】:

    我的 xp 机器上没有注册错误类,而相同的代码在 windows server 2003 上运行正常

      IGPM *pGPM = NULL; 
     hr = CoCreateInstance(CLSID_GPM, NULL, CLSCTX_INPROC_SERVER, IID_IGPM , (LPVOID*)&pGPM);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-21
      • 1970-01-01
      • 2023-04-11
      相关资源
      最近更新 更多