Межсессионная активация. Имя сеанса игнорируется - PullRequest
1 голос
/ 09 марта 2012

На моем компьютере с Windows есть две учетные записи: \ A1 и \ SYSTEM.Мой тестовый проект состоит из трех приложений:

  1. Server.exe - сервер com-of-proc.реализует объект Q
  2. Service.exe - out of out proc com service.реализует объект T
  3. Client.exe - клиентские приложения

Мой рабочий процесс показан ниже:

  1. Я вошел в систему\ A1.Я запускаю «Client.exe».
  2. Клиент создает экземпляр объекта «T»
  3. Клиент вызывает некоторый метод, скажем «T.ActivateQ», который создает экземпляр «Q».

Мое намерение - заставить Service.exe создать экземпляр «Q» в учетной записи \ A1, даже если Service.exe находится в учетной записи \ SYSTEM.

Каккак указано в этой статье, Windows имеет встроенную функциональность для выполнения такого рода активации, которая называется «активация сеанса к сеансу».Это реализовано с помощью Session Moniker («Session:! Clsid:»).

Учитывая это, я настроил «Server.exe» для запуска в качестве «Интерактивного пользователя» через dcomcnfg.Затем я реализовал функцию CoGetClassObjectInSession:

void CoGetClassObjectInSession(DWORD sessionId, Guid const& clsid, void *pvReserved, Guid const& riid, void **ppv)
{
    ATL::CComQIPtr<IBindCtx> bindCtxInst;
    COMCHK(CreateBindCtx(NULL, &bindCtxInst));

    CComQIPtr<IMoniker> classMonikerInst;
    COMCHK(::CreateClassMoniker(clsid, &classMonikerInst));

    std::wstringstream ss;
    ss << L"Session:" << std::dec << sessionId;

    ULONG parsed;
    ATL::CComQIPtr<IMoniker> sessionMonikerInst;
    COMCHK(::MkParseDisplayNameEx(bindCtxInst, ss.str().c_str(), &parsed, &sessionMonikerInst));

    ATL::CComQIPtr<IMoniker> classObjectMoniker;
    COMCHK(sessionMonikerInst->ComposeWith(classMonikerInst, FALSE, &classObjectMoniker));


    ATL::CComPtr<IClassFactory> sessionFactoryInst;
    COMCHK(classObjectMoniker->BindToObject(bindCtxInst, NULL, riid, ppv));
}

и использую ее в сервисе:

HRESULT CMyActivator::Activate()
{
    try
    {
        // Impersonate the client
        CComQIPtr<IServerSecurity> ss;
        COMCHK(::CoGetCallContext(__uuidof(IServerSecurity), reinterpret_cast<void**>(&ss))); 
        callctx_impersonation_handle _handle(ss);
        ImpersonationScope _imp_scope(_handle);

        CComQIPtr<IClassFactory> ppv;
        CoGetClassObjectInSession(/*session id for \\A1*/ 1, Guid(__uuidof(Q)), nullptr, Guid(__uuidof(IClassFactory)), reinterpret_cast<void**>(&ppv));
        ENSURE(NULL != ppv, "'ppv' should not be null");

        return S_OK;
    }
    catch(std::exception const& ex)
    {
        return E_FAIL;
    }
    catch(...)
    {
        return E_FAIL;
    }
}

Но ничего не происходит.Я имею в виду, что служба всегда запускает сервер в сеансе 0, который соответствует учетной записи \ SYSTEM.

Параметры безопасности клиента:

COMCHK(::CoSetProxyBlanket(
            activatorQ
            , RPC_C_AUTHN_DEFAULT
            , RPC_C_AUTHZ_DEFAULT
            , NULL
            , RPC_C_AUTHN_LEVEL_DEFAULT
            , RPC_C_IMP_LEVEL_DELEGATE
            , NULL
            , EOAC_DYNAMIC_CLOAKING));

Файл Server.rgs:

HKLM
{
    NoRemove Software
    {
        NoRemove Classes
        {
            NoRemove AppID
            {
                ForceRemove '%APPID%' = s 'Test Server'
                {
                    val RunAs = s 'Interactive User'
                }
            }
        }
    }
}

Я что-то не так делаю?

ОБНОВЛЕНИЕ Я наконец нашел решение.В сценарии регистрации для класса 'Q' отсутствует поле AppID:

HKCR
{
    NoRemove CLSID
    {
        ForceRemove {6FDE856C-F1B2-4466-8435-20F4AEF2C2E1} = s 'SMonClass Class'
        {
            ForceRemove Programmable
            LocalServer32 = s '%MODULE%'
            {
                val ServerExecutable = s '%MODULE_RAW%'
            }
            TypeLib = s '{4FA39B0F-5B24-43C6-A5B1-11D8F34277B7}'
            Version = s '1.0'

            --> val AppID = s '%APPID%'** <-- This line

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...