Запретить COM активировать исполняемый файл сервера? - PullRequest
0 голосов
/ 05 марта 2019

TL; DR - Как предотвратить запуск -Embedding сервера CLSCTX_LOCAL_SERVER?Желательно, чтобы клиенты сразу получали приличный код ошибки.

Фон

У нас есть родное приложение C ++ для интерактивного рабочего стола, которое взаимодействует с объектом COM в другом собственном приложении C ++ для интерактивного рабочего стола.

По существу, COM используется как механизм межпроцессного взаимодействия.

Теперь, когда приложение «сервер» запускается в интерактивном режиме после того, как пользователь перевел его в правильное состояние, оно подготовит COMинтерфейс: CoRegisterClassObject и т. д. и т. д.

Когда клиентское приложение используется, а затем выполняет CoCreateInstance для coclass, оно будет связываться с уже запущенным другим приложением Desktop, что и предназначено.

Однако, когда «серверное» приложение не запущено, запуск клиента в интерактивном режиме запускает серверное приложение, а это НЕ то, что нам нужно, потому что оно требует некоторой обработки и настройки, прежде чем клиент сможет осмысленно связаться с ним..

Вопрос

Итак, для клиента было бы разумнее просто выдавать ошибку в случае, если сервер не работает, вместо того, чтобы инфраструктура COM запускала интерактивное приложение, которое может 'В любом случае, запрос не будет полностью обработан.

Мыпоиграл со следующими идеями:

  • Отмена регистрации сервера при каждом его закрытии.
    • Кажется, это не сработает, поскольку нам нужны административные права для регистрации / отмены регистрации сервера.
  • Используйте флаг CLSCTX_DISABLE_AAA на стороне клиента.
    • Кажется, это работает, если клиент указывает это, а сервер не работает, он получит 0x80070005 ERROR_ACCESS_DENIED, но мы довольно не уверены, является ли это правильным подходом.
  • Выполните раннюю проверку в приложении сервера, чтобы обнаружить переключатель -Embedding, и немедленно выйдите из приложения.
    • Клиентское приложение будет работать в течение тайм-аута (~ 2 мин), что не очень удобно для пользователя.
  • из комментариев Не писатьинформация в реестр - CoRegisterClassObject должно быть достаточно .
    • В настоящее время у меня есть:
      • HKCR\AppID (...)
      • HKCR\CLSID\{...} плюс подразделы ProgID, VersionIndependentProgID, LocalServer32, Typelib
    • Клиенты в настоящее время разрешают CLSID из VersionIndependentProgID
    • Так что мне интересно, какие части реестра действительно необязательны.

Существует ли какой-либо "стандартный" способ предотвращения активации исполняемого файла локального сервера COM для данного зарегистрированного класса COM?

Ответы [ 2 ]

0 голосов
/ 27 марта 2019

Запишите то, что я узнал из комментариев:


Вам не нужно использовать CoCreateInstance, но вы можете использовать GetActiveObject, что

Извлекает указатель на работающий объект, который был зарегистрирован в OLE.

, так что у вас есть способ получить объект, не активируя его, но полагаясь на то, что он ужезарегистрировано.(Но это не делается с помощью CoRegosterClassObject, вместо этого вам нужно ...?)


Подобно подходу GetActiveObject, вы можете использовать оборудование вокруг IRunningObjectTable - что может бытьчто используется GetActiveObject в любом случае.я там немного потерян.


Другая информация состоит в том, что реестр считается "необязательным" во всем этом: (перефразируя)

CoRegisterClassObject - это просто публикация вашего объекта на COM (в качестве oop-сервера), ...

просто не регистрирует ваш объект CLSID в реестре.Если сервер еще не вызвал CoRegisterClassObject, клиент получает ошибку REGDB_E_CLASSNOTREG, в противном случае достаточно вызвать CoRegisterClassObject....

вам не нужно добавлять его в таблицу запущенных объектов - достаточно одного вызова CoRegisterClassObject - после этого клиент может создать экземпляр.Нет необходимости в регистрации в реестре - ...

... для любого удаленного интерфейса вам, конечно, нужна запись в реестре Interface\{..}\ProxyStubClsid32, но не нужна для CLSID.

CoRegisterClassObject вообще не нуждается в реестре ... Но вам все еще нужно маршал вашего интерфейса (ов).Для этого вам нужен ключ Interface\{..}\ProxyStubClsid32.

TypeLib, который вам нужен, если вы выполняете маршалинг этого типа - установите {00020424-0000-0000-C000-000000000046} здесь.CLSID и AppID вам не нужны.

CLSID и APPID вам нужны для запуска приложения, если оно не запущено (или загрузите dll).

Если вы уже работаете и звоните CoRegisterClassObject - этого достаточно, чтобы клиентский звонок подключился к вам.Но без CLSID клиент не может выполнить ваше приложение (просто неизвестно, что).

Если вы не делаете пользовательский маршалинг - нужно, чтобы каждый интерфейс имел информацию в реестре - какой dll ProxyStubClsid32 делает это маршалинг.Это может быть либо пользовательская dll, либо стандартная {00020424-0000-0000-C000-000000000046}, тогда вам нужна библиотека типов для использования oleaut32.


In summary , может показаться, что способ предотвратить активацию приложения Windows - это

  • НЕ записывать информацию, необходимую для активации, в реестр.
    • , но требуется только информация, необходимая для маршалинга.
  • и / или НЕ вызова CoCreateInstance и извлечения объекта по другому маршруту.
0 голосов
/ 15 марта 2019

Моя идея заключается в следующем ...

Просто установите глобальный флаг в вашем EXE, когда вы обнаружите, что сервер запущен с -Embedding.Вероятно, я бы создал фабрику специальных классов только при запуске с флагом -Embedding.Эта фабрика классов будет возвращать код ошибки при вызове IClassFactory :: CreateInstance ().Вы не зарегистрировали бы фабрику стандартного класса как работающую с CoRegisterClassObject (), но зарегистрировали бы только вашу альтернативную фабрику, которая всегда возвращает код ошибки.

Да, при запуске все равно будет небольшая задержкаEXE, но когда вызывается CreateInstance (), он немедленно возвращает код ошибки, поэтому у вызывающей стороны не будет продолжительного времени ожидания ... возможно, только 1-5 секунд.

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