Вопрос все о том же E_ACCESSDENIED
От: Glaz  
Дата: 06.01.05 13:15
Оценка:
Имеется сервер, реализованный в виде ATL сервиса, и клиент в виде dll. Все создано при помощи мастера в VS 2003.
Клиент создает объект сервера (CoCreateInstance).
Затем регистрируется на нем, передавая одним из параметров метода регистрации указатель на свой интерфейс
( pServer->Advise(IUnknown** ppUnk) ).
Сервер ( в реализации Advise ) получает необходимые указатели на интерфейсы клиента и взаимодействует с ним.

Задача: заставить все это работать не настраивая параметры защиты вручную. ОС Win2000 SP4.

Клиент с сервером работает без проблем, а вот сервер с клиентом никак. При попытке со стороны сервера запросить необходимый интерфейс ( (*ppUnk)->QueryInterface(...) ) получаю E_ACCESSDENIED.

Изучил много постов на эту тему, но у всех постившихся и сервер и клиент реализованы в exe. В этом случае статья "Защита в DCOM/COM+" все проблемы решает.

Но в этой же статье я прочитал следующую фразу:
"Не стоит пытаться вызвать эту функцию (CoInitializeSecurity) из COM-сервера, расположенного в DLL, даже если DLL зарегистрирована в COM+-приложении, ибо к моменту создания пользовательского объекта данная функция точно уже вызвана самим COM."

Так как же быть в таком случае? Получается, что для COM-объектов расположенных в dll защиту программно не настроить?

А работает все только когда я изменяю настройки безопасности по умолчанию в dcomcnfg.
Но меня этот вариант совершенно не устраивает.
Помогите пожалуйста.
Re: Вопрос все о том же E_ACCESSDENIED
От: kzua  
Дата: 07.01.05 08:06
Оценка:
Здравствуйте, Glaz, Вы писали:

G>Имеется сервер, реализованный в виде ATL сервиса, и клиент в виде dll. Все создано при помощи мастера в VS 2003.

G>Клиент создает объект сервера (CoCreateInstance).
G>Затем регистрируется на нем, передавая одним из параметров метода регистрации указатель на свой интерфейс
G>( pServer->Advise(IUnknown** ppUnk) ).
G>Сервер ( в реализации Advise ) получает необходимые указатели на интерфейсы клиента и взаимодействует с ним.

G>Задача: заставить все это работать не настраивая параметры защиты вручную. ОС Win2000 SP4.


G>Клиент с сервером работает без проблем, а вот сервер с клиентом никак. При попытке со стороны сервера запросить необходимый интерфейс ( (*ppUnk)->QueryInterface(...) ) получаю E_ACCESSDENIED.


G>Изучил много постов на эту тему, но у всех постившихся и сервер и клиент реализованы в exe. В этом случае статья "Защита в DCOM/COM+" все проблемы решает.


G>Но в этой же статье я прочитал следующую фразу:

G>"Не стоит пытаться вызвать эту функцию (CoInitializeSecurity) из COM-сервера, расположенного в DLL, даже если DLL зарегистрирована в COM+-приложении, ибо к моменту создания пользовательского объекта данная функция точно уже вызвана самим COM."

G>Так как же быть в таком случае? Получается, что для COM-объектов расположенных в dll защиту программно не настроить?


G>А работает все только когда я изменяю настройки безопасности по умолчанию в dcomcnfg.

G>Но меня этот вариант совершенно не устраивает.
G>Помогите пожалуйста.


"FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508"

http://support.microsoft.com/default.aspx?scid=kb;en-us;158508

3. Why does IConnectionPoint::Advise not work?
4. I receive E_ACCESSDENIED from CoCreateInstanceEx. Why?
Re[2]: Вопрос все о том же E_ACCESSDENIED
От: Glaz  
Дата: 07.01.05 09:23
Оценка:
Здравствуйте, kzua, Вы писали:

K>"FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508"


K>http://support.microsoft.com/default.aspx?scid=kb;en-us;158508


K>3. Why does IConnectionPoint::Advise not work?

K>4. I receive E_ACCESSDENIED from CoCreateInstanceEx. Why?

Спасибо за линк.
Дело в том, что я не использую механизм точек подключения и метод Advise(IUnknown** ppUnk) — мой собственный.
Я не знаю где поставить вызов CoInitializeSecurity в клиенте. Он возвращает ошибку, а настройки безопасности прописанные для данного компонента в реестре не используются.

Пробовал поставить в функцию DllRegisterServer. При регистрации компонента CoInitializeSecurity срабатывает удачно, но при запуске та же проблема. Видимо при запуске CoInitializeSecurity вызывается неявно еще раз.

Прочитав статью Влада и рассмотрев его пример понял, что с dll такие фокусы не проходят. Получается, что для COM-объектов расположенных в dll защиту можно настроить только(!) вручную. На мой взгляд это бред какой-то. Неужели нет какого-либо способя настроить защиту dll программно?
Re[3]: Вопрос все о том же E_ACCESSDENIED
От: kzua  
Дата: 07.01.05 10:45
Оценка:
Здравствуйте, Glaz, Вы писали:

G>Здравствуйте, kzua, Вы писали:


K>>"FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508"


K>>http://support.microsoft.com/default.aspx?scid=kb;en-us;158508


K>>3. Why does IConnectionPoint::Advise not work?

K>>4. I receive E_ACCESSDENIED from CoCreateInstanceEx. Why?

G>Спасибо за линк.

G>Дело в том, что я не использую механизм точек подключения и метод Advise(IUnknown** ppUnk) — мой собственный.

Дело не в этом.

G>Я не знаю где поставить вызов CoInitializeSecurity в клиенте. Он возвращает ошибку, а настройки безопасности прописанные для данного компонента в реестре не используются.


G>Пробовал поставить в функцию DllRegisterServer. При регистрации компонента CoInitializeSecurity срабатывает удачно, но при запуске та же проблема. Видимо при запуске CoInitializeSecurity вызывается неявно еще раз.


Нет туда пихать не надо.

G>Прочитав статью Влада и рассмотрев его пример понял, что с dll такие фокусы не проходят. Получается, что для COM-объектов расположенных в dll защиту можно настроить только(!) вручную. На мой взгляд это бред какой-то. Неужели нет какого-либо способя настроить защиту dll программно?


CoInitializeSecurity должна быть вызвана после CoInitialize(Ex) до первого вызова CoCreateInstance.
Соответственно это не про DLL, а про EXE.

G>Имеется сервер, реализованный в виде ATL сервиса, и клиент в виде dll. Все создано при помощи мастера в VS 2003.


Надо понимать, что "клиент в виде dll" является сервером по отношению к другим приложениям.?
Вот в этих клиентах и нужно делать вызов CoInitializeSecurity.
Re[3]: Вопрос все о том же E_ACCESSDENIED
От: kzua  
Дата: 07.01.05 19:23
Оценка:
Здравствуйте, Glaz, Вы писали:

G>Здравствуйте, kzua, Вы писали:


K>>"FAQ: COM Security Frequently Asked Questions," Knowledge Base article #Q158508"


K>>http://support.microsoft.com/default.aspx?scid=kb;en-us;158508


K>>3. Why does IConnectionPoint::Advise not work?

K>>4. I receive E_ACCESSDENIED from CoCreateInstanceEx. Why?

G>Спасибо за линк.

G>Дело в том, что я не использую механизм точек подключения и метод Advise(IUnknown** ppUnk) — мой собственный.
G>Я не знаю где поставить вызов CoInitializeSecurity в клиенте. Он возвращает ошибку, а настройки безопасности прописанные для данного компонента в реестре не используются.

G>Пробовал поставить в функцию DllRegisterServer. При регистрации компонента CoInitializeSecurity срабатывает удачно, но при запуске та же проблема. Видимо при запуске CoInitializeSecurity вызывается неявно еще раз.


G>Прочитав статью Влада и рассмотрев его пример понял, что с dll такие фокусы не проходят. Получается, что для COM-объектов расположенных в dll защиту можно настроить только(!) вручную. На мой взгляд это бред какой-то. Неужели нет какого-либо способя настроить защиту dll программно?


Пропиши в реестре соответствующие ключи при инcталляции компонента.
Re[4]: Вопрос все о том же E_ACCESSDENIED
От: Glaz  
Дата: 08.01.05 08:44
Оценка:
Здравствуйте, kzua, Вы писали:

K>CoInitializeSecurity должна быть вызвана после CoInitialize(Ex) до первого вызова CoCreateInstance.

K>Соответственно это не про DLL, а про EXE.

С exe все ясно, здесь у меня проблем не возникло. Вопрос касался программной настройки защиты COM-объекта в dll.

K>Надо понимать, что "клиент в виде dll" является сервером по отношению к другим приложениям.?

K>Вот в этих клиентах и нужно делать вызов CoInitializeSecurity.

Совершенно верно. Только я не знаю где его вызывать. Везде где бы я его не ставил, метод возвращает ошибку HRESULT = -21..... Вероятнее всего потому, что он уже вызывался ранее неявно.

Отсюда вопрос как обойти(опередить) или заблокировать неявный вызов CoInitializeSecurity в COM-объектах расположенных в dll?
Re[4]: Вопрос все о том же E_ACCESSDENIED
От: Glaz  
Дата: 08.01.05 08:56
Оценка:
Здравствуйте, kzua, Вы писали:

K>Пропиши в реестре соответствующие ключи при инсталляции компонента.


Пробовал. Но беда в том, что по умолчанию настройки безопасности доступа в реестре не влияют на реальную политику безопасности (см. статью Влада). Для избавления от этого эффекта, код инициализации защиты сформированный визардом заменялся таким образом, чтобы настройки считывались из ветки реестра, соответствующей AppID. Но опять-таки все этот касаемо только exe. В dll явного вызова CoInitializeSecurity вообще нету, а следовательно и заменить ничего не получится. Поэтому настройки реестра игнорируются.
Re[5]: Вопрос все о том же E_ACCESSDENIED
От: kzua  
Дата: 08.01.05 09:44
Оценка:
Здравствуйте, Glaz, Вы писали:

G>Здравствуйте, kzua, Вы писали:


K>>Пропиши в реестре соответствующие ключи при инсталляции компонента.


G>Пробовал. Но беда в том, что по умолчанию настройки безопасности доступа в реестре не влияют на реальную политику безопасности (см. статью Влада). Для избавления от этого эффекта, код инициализации защиты сформированный визардом заменялся таким образом, чтобы настройки считывались из ветки реестра, соответствующей AppID. Но опять-таки все этот касаемо только exe. В dll явного вызова CoInitializeSecurity вообще нету, а следовательно и заменить ничего не получится. Поэтому настройки реестра игнорируются.


Настройки реестра не игнорируются если DLL запускается в суррогатном процессе.
Re[5]: Вопрос все о том же E_ACCESSDENIED
От: kzua  
Дата: 08.01.05 09:46
Оценка:
Здравствуйте, Glaz, Вы писали:

G>Здравствуйте, kzua, Вы писали:


K>>CoInitializeSecurity должна быть вызвана после CoInitialize(Ex) до первого вызова CoCreateInstance.

K>>Соответственно это не про DLL, а про EXE.

Смысл этой фразы понимаешь?
CoInitializeSecurity должна быть вызвана до первого инстанцирования любого компонента.
Т.к., твоя DLL компонент, то соответственно инстанцирование было.

G>С exe все ясно, здесь у меня проблем не возникло. Вопрос касался программной настройки защиты COM-объекта в dll.


Еще раз повторяю. Нужно делать вызов CoInitializeSecurity в тех EXE, которые используют твою DLL, которая
в свою очередь использует сервис.


K>>Надо понимать, что "клиент в виде dll" является сервером по отношению к другим приложениям.?

K>>Вот в этих клиентах и нужно делать вызов CoInitializeSecurity.

G>Совершенно верно. Только я не знаю где его вызывать. Везде где бы я его не ставил, метод возвращает ошибку HRESULT = -21..... Вероятнее всего потому, что он уже вызывался ранее неявно.


Вообще-то коды HRESULT нужно писать в hex виде.

G>Отсюда вопрос как обойти(опередить) или заблокировать неявный вызов CoInitializeSecurity в COM-объектах расположенных в dll?


В DLL нет вызова CoInitializeSecurity (явного/неявного).
Вызов CoInitializeSecurity нужно делать в EXE, которая использует твою DLL.

Еще раз повторить?
Re[6]: Вопрос все о том же E_ACCESSDENIED
От: Glaz  
Дата: 09.01.05 11:53
Оценка:
Здравствуйте, kzua, Вы писали:

K>Еще раз повторяю. Нужно делать вызов CoInitializeSecurity в тех EXE, которые используют твою DLL, которая

K>в свою очередь использует сервис.

Все заработало!
Извиняюсь за свои тормоза, я в этих делах еще зеленый совсем.
Огромное спасибо за помощь!!!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.