| Доступ к inproc СОМ-серверу из под другого пользователя | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 17.03.06 05:02 |
| Добрый день! В общем, уже вторую, наверное, неделю бьюсь над такой проблемой. Есть in-proc СОМ-сервер, сделанный как синглтон — несколько процессов спокойно используют одну и туже DLL, которая сидит в самом первом запущенном процессе. Но как только я переключаюсь на другого пользователя и запускаю программу — эта ДЛЛ загружается снова, что совершенно неприемлемо, т.к. она работает с драйвером... И заказчик не хочет ни суррогат, ни out-proc Автор: EqWu , но что-то автор не отзывается. Я вообще пробовал обнулять этот DACL при помощи SetSecurityInfo — он обнуляется, но все равно не работает. Я, в принципе, готов и свой процесс мордовать — можно ли его сделать LocalSystem как-нибудь???Дата: 01.12.05 Буду очень благодарен за любые идеи. Спасибо, Алексей |
| Re: Доступ к inproc СОМ-серверу из под другого пользователя | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 17.03.06 08:30 |
| Вызови CoInitializeSecurity, разрешив тем самым активацию и доступ к обьекту всем пользователям ... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[2]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 19.03.06 12:31 |
| Здравствуйте, Tom, Вы писали: Tom>Вызови CoInitializeSecurity, разрешив тем самым активацию и доступ к обьекту всем пользователям Привет, Том! Спасибо большое за ответ. Я пробовал CoInitializeSecurity раньше, я пробовал обнулять DACL, давая полный доступ Everyone — один фиг. Я про защиту СОМ читал статью, Рихтера смотрел, сайты всякие обгуглил — а толку ноль пока что... Затык происходит в момент вызова CoGetClassObject. Если ДЛЛ была подгружена в процесс в другой сессии, то в текущей CoGetClassObject возвращает Class is not registered даже после всей моей возни с защитой. Может, здесь что-то более тонкое надо смотреть? С другой стороны, для out-proc сервера это же должно работать и между сессиями (но для этого надо поменять настройки защиты dcomcnfg). Вот что же он такого хитрого делает, что СОМ начинает видеть сервер и в другой сессии? Запуск из под LocalSystem? Это НАСТОЛЬКО критично? Что бы не быть голословным, приведу немного кода. Берется проект из статьи HOWTO: Глобальный COM-синглтон в DLL Автор(ы): Егор Синькевич, Сергей Холодилов , в клиенте ставиться getch() перед выходом из main, что бы в памяти висело, в ДЛЛ-ке — MessageBox() в FinalConstruct например. Запускается 2 раза под одним пользователем — все отлично, только один MessageBox. Оставляя эти приложения висящими, переключаемся под другого юзера — опять MessageBox Дата: 16.02.2005 Статья описывает реализацию синглтона, физически размещаемого в DLL, но уникального в пределах компьютера. Данная реализация позволяет создавать подобные синглтоны в своих проектах изменением однойединственной строки кода.
на
не помогает. Также не помогает и обнуление ДАКЛа:
В общем, я в полной прострации... А дедлайн-то приближается 1. Ручками пробовать находить и запускать DllGetClassObject через CreateRemoteThread. 2. Заюзать Register/Get ActiveObject 3. Что-нибудь пытаться делать с ROT (но это вроде то, чем 2 занимается). 4. MTS/COM+? Но боюсь этого заказчик не поймет... Буду очень благодарен за любые идеи/советы. Заранее спасибо, Алексей |
| Re[3]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 20.03.06 03:47 |
| A>В общем, я в полной прострации... А дедлайн-то приближается A>1. Ручками пробовать находить и запускать DllGetClassObject через CreateRemoteThread. как здесь пишут Автор: Polonius , CreateRemoteThread не работает в другой сессии...Дата: 06.10.04 A>2. Заюзать Register/Get ActiveObject Не находит... A>3. Что-нибудь пытаться делать с ROT (но это вроде то, чем 2 занимается). Тут — поиск моникера в ROT Автор: MORBiD Не прокатывает даже с Excel-ем, если его в той же сессии запустить RusAs от другого пользователя...Дата: 08.11.01 Буду ОЧЕНЬ благодарен за любые идеи/советы. Заранее спасибо, Алексей |
| Re[4]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 20.03.06 08:59 |
| A>Буду ОЧЕНЬ благодарен за любые идеи/советы. Это пробовал в начале процесса вызывать? Ессно это нужно делать перед вызовом CoRegisterClassObjects
... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[5]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 20.03.06 10:46 |
| Здравствуйте, Tom, Вы писали: A>>Буду ОЧЕНЬ благодарен за любые идеи/советы. Tom>Это пробовал в начале процесса вызывать? Ессно это нужно делать перед вызовом CoRegisterClassObjects Tom>
Привет! Для простоты я в предыдущих письмах использовал твой пример из статьи про ДЛЛ-синглтон. Соответственно, я начало клиента модифицирую так:
Оба варианта не работают... Сам синглтон не трогаю (ну делаю так, что бы он ProcessID возвращал для визуального контроля). Под одним юзером все отрабатывает как надо, если 2 разных — тогда 2 синглтона. Вот такие вот пироги... Спасибо за ответы! Алексей |
| Re[6]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 20.03.06 11:06 |
| A>Вот такие вот пироги... A>Спасибо за ответы! 1. CoInitializeSecurity должна на обоих сторонах вызываться 2. SetDACL(NULL); совсем выкинь, не нужно оно. 3. Нужно посмотреть настройки активации в реестре для твоего обьекта, под кем его запускать, там случаем "launching user" не стоит? ... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[7]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 20.03.06 11:37 |
| Здравствуйте, Tom, Вы писали: A>>Вот такие вот пироги... A>>Спасибо за ответы! Tom>1. CoInitializeSecurity должна на обоих сторонах вызываться Какие обе стороны? У меня есть exe, в котором сначала вызывается CoInitializeSecurity, а потом в него загружается DLL-Singleton. Этот же exe я вызываю из под другого пользователя. Вот тут вот мне кажется, я был несколько запутан. Я сейчас говорю о пользователе в контектсе WindowsXP — т.е. нажал "Смена пользователя", зашел под новым, и потом так же обратно вернулся. Мы говорим об одном и том же? Tom>2. SetDACL(NULL); совсем выкинь, не нужно оно. Да фиг с ним, выкинуть, закомментить... НА него надежд точно не было Tom>3. Нужно посмотреть настройки активации в реестре для твоего обьекта, под кем его запускать, там случаем "launching user" не стоит? Подожди, у меня exe, который грузит DLL с COM-объектом. Какие настройки активации??? AppID разве есть? |
| Re[8]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 20.03.06 12:46 |
| A>Подожди, у меня exe, который грузит DLL с COM-объектом. Какие настройки активации??? AppID разве есть? Попробуй создай APPID который должен быть равен CLSID обьекта, и в настройках активации укажи пользователя, от которого изначально запускается первый инстанс обьекта ... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[9]: CoGetClassObject не загружает СОМ-объект из другой се | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | EqWu | http://www.microsoft.com/rus |
| Дата: | 20.03.06 12:59 |
| Здравствуйте, Tom, Вы писали: A>>Подожди, у меня exe, который грузит DLL с COM-объектом. Какие настройки активации??? AppID разве есть? Tom>Попробуй создай APPID который должен быть равен CLSID обьекта, и в настройках активации укажи пользователя, от которого изначально запускается первый инстанс обьекта И как вы это себе представляете? Запускается процесс от имени COMPNAME\Vasya, а у outproc-сервера в launching user стоит COMPNAME\Dima. И вот система, узрев такую истину, создает COM-объект от имени Димы... Пока CoRegisterClassObject работает в контексте сессии, ничего не получится. Можно попробовать CoMarshalInterThreadInterfaceInStream (ее Microsoft предлагает в качестве замены IGlobalInterfaceTable::RegisterInterfaceInGlobal). Тут уж нужно как-то этот стрим между юзерами отшарить. Главное — понять, что синглтон уже существует. Это через mutex легко проверить: делаем CreateMutex и, если GetLastError() == ERROR_ALREADY_EXISTS, значит синглтон уже родился. Ну, и не забываем, что синглтон нужно с префиксом "Global\" создавать... |
| Re[10]: CoGetClassObject не загружает СОМ-объект из другой с | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 20.03.06 13:01 |
| EW>И как вы это себе представляете? Для решения проблеммы — проблемму нужно найти, и только потом думать как её решать. Вот мы и пытаемся найти и идентифицировать проблему ... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[11]: CoGetClassObject не загружает СОМ-объект из другой с | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | EqWu | http://www.microsoft.com/rus |
| Дата: | 20.03.06 13:10 | |
| Оценка: | 3 (1) | |
| Здравствуйте, Tom, Вы писали: EW>>И как вы это себе представляете? Tom>Для решения проблеммы — проблемму нужно найти, и только потом думать как её решать. Вот мы и пытаемся найти и идентифицировать проблему Я понимаю проблему именно так: CoRegisterClassObject, а ровно как и GIT работают в раммках сессии. Согласно постановки задачи, от них нужно добиться работы в рамках всей машины. Пытаться обнаружить нечто, зарегистрированное через CoRegisterClassObject в другой logon-сессии через CoGetClassObject, мне кажется, бесполезно. Если очень нужно, то стоит попробовать создать подобие своего GIT через свой stream и ф-ции CoMarshalInterThreadInterfaceInStream и CoGetInterfaceAndReleaseStream. Тут может встать проблема доступности стрима из другой сессии, но эта проблема выглядит более решаемой. |
| Re[12]: CoGetClassObject не загружает СОМ-объект из другой с | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | Tom rsdn | http://www.RSDN.ru |
| Дата: | 20.03.06 13:26 |
| Здравствуйте, EqWu, Вы писали: EW>Здравствуйте, Tom, Вы писали: EW>>>И как вы это себе представляете? Tom>>Для решения проблеммы — проблемму нужно найти, и только потом думать как её решать. Вот мы и пытаемся найти и идентифицировать проблему EW>Я понимаю проблему именно так: CoRegisterClassObject, а ровно как и GIT работают в раммках сессии. Согласно постановки задачи, от них нужно добиться работы в рамках всей машины. Пытаться обнаружить нечто, зарегистрированное через CoRegisterClassObject в другой logon-сессии через CoGetClassObject, мне кажется, бесполезно. Понимание проблеммы неправильное. Задумаяся, хотя бы, о DCOM серверах, обращение к которым идёт от множества различных пользователей. А вообще конечно вместо вызова CoGetClassObject можно получать указатель размаршаливая его например из файла, или даже БД — разница небольшая ... << RSDN@Home 1.1.4 beta 4 rev. 303>> Народная мудрось | всем все никому ничего(с). |
| Re[12]: CoGetClassObject не загружает СОМ-объект из другой с | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | EqWu | http://www.microsoft.com/rus |
| Дата: | 20.03.06 13:27 | |
| Оценка: | 3 (1) | |
| Дополнение... Если посмотреть здесь, то CoRegisterClassObject, это просто CreateStreamOnHGlobal + CoMarshalInterface. Нужно сделать то же самое, но создав стрим, на memory-mapped файле, доступном все юзерам. |
| Re[13]: CoGetClassObject не загружает СОМ-объект из другой с | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | EqWu | http://www.microsoft.com/rus |
| Дата: | 20.03.06 13:32 |
| Tom>Понимание проблеммы неправильное. Задумаяся, хотя бы, о DCOM серверах, обращение к которым идёт от множества различных пользователей. Для DCOM-сервера известен пользователь, от имени которого он работает, а значит и система знает в контексте какой сессии ПЫТАТЬСЯ ЗАПУСТИТЬ еще один экземпляр и искать созданный объект. Синглтоны — отдельная песня. По сути создавать или нет очередной экземпляр решает сам процесс синглтона. |
| Re: Сделал! | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 23.03.06 04:24 | |
| Оценка: | 3 (1) | |
| Ну что ж, позвольте отчитаться о проделанной работе Вкратце — да, таки получилось объект поднимать в другой сессии. Но с БОЛЬШИМ "но". Теперь что делал. 1. Взял DLL-синглтон из статьи HOWTO: Глобальный COM-синглтон в DLL Автор(ы): Егор Синькевич, Сергей Холодилов .Дата: 16.02.2005 Статья описывает реализацию синглтона, физически размещаемого в DLL, но уникального в пределах компьютера. Данная реализация позволяет создавать подобные синглтоны в своих проектах изменением однойединственной строки кода. 2. Немного его поменял, что бы он выдавал CurrentProcessID() для облегчения контроля 3. В фабрике классов заменил CoGet/RegisterClassOBject на вызовы маршалинга/размаршалинга. 4. В клиенте (кстати, только сейчас я задумался, а зачем я так делал??
Возникшие и решенные проблемы. 1. Маршалинг. Обычный, в файл через ShellCreateStreamOnFile (или как-то так) работает прекрасно, но некрасиво в файл писать. Пробовал делать в Memory-Mapped — не срабатывал CreateStreamOnHGlobal после MapViewOfFile — потому что то, что возвращает MapViewOfFile != тому, что возвращает GlobalAlloc. Тоже с этим намучался изрядно. В итоге — сначала создаем CreateStreamOnHGlobal, маршалим туда интерфейс при помощи CoMarshalInterface, а вот затем создаем Memory-Mapped файл через CreateFileMapping, открываем его в своем процессе при помощи MapViewOfFile и затем в эту память пишем содержимое IStream:
Не забываем закрыть отображение файла через UnmapViewOfFile. Про таинственный sizeof(DWORD) см. ниже. 2. Размаршаливание интерфейса. Делается примерно также, открывается файл через OpenFileMapping -> MapViewOfFile, создается стрим через CreateStreamOnHGlobal и в него записывается содержимое этого файл.
Тут проблема была с определение размера этого самого файл в памяти. GetFileSize(), естественно не работает. В итоге я его просто записываю первым словом в начало самого файла (тот самый sizeof(DWORD) 3. Но это еще цветочки... Когда это все заработало в одной сессии, я попробовал через сессию это делать. Фиг вам. Для этого надо сбросить настройки безопастности:
Вот здесь, честно сказать, я потерялся. Я не понимаю, что и зачем я делаю. С этим работает, без — нет. Почему именно так, какие конкретно права надо дать (полностью же сбрасывать это совсем неправильно) — вот здесь нужен комментарий специалиста. После этого работает и между сессиями. 4. Ну и на сладенькое. Во-первых, спасибо Владимиру за совет, он указал, что фабрике классов синглтона мьютекс надо делать глобальным (Global\\MutexName), соответственно, тоже самое надо и для memory-mapped файла. А также для них надо передавать не дефолтный SECURITY_DESCRIPTOR, а со сброшенным DACL-ом, иначе фиг кто этот самый мьютекс откроет из другой сессии. А теперь внимание, вопрос Это все работает для процесса DllSingletonClient в примере. Мне же, в моем проекте, приходится подгружать DLL в произвольный процесс. Я реализовал это при помощи другой статьи с любимого сайта Автор(ы): Сергей Холодилов . Вот в произвольном случае это и не работает. Например, банальный notepad.exe не поддерживает эту фишку. А вот explorer.exe — запросто Дата: 13.02.2005 В статье описывается один из методов внедрения DLL. Разбираются способы взаимодействия с внедренной библиотекой. Вот такие вот пироги Ну и персональная благодарность Тому и Владимиру за подкинутые идеи! Спасибо, мужики, вы меня очень здорово выручили! Алексей ЗЫ код всего выложу вечером или в выходные. |
| Re[2]: И обещанные файлы.. | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 26.03.06 10:42 |
| Просто взял проект DllSingleton Автор(ы): Егор Синькевич, Сергей Холодилов , перевел Дата: 16.02.2005 Статья описывает реализацию синглтона, физически размещаемого в DLL, но уникального в пределах компьютера. Данная реализация позволяет создавать подобные синглтоны в своих проектах изменением однойединственной строки кода. Алексей. |
| Re[3]: файл - тут. | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | avs99 | |
| Дата: | 26.03.06 10:43 | |
| Оценка: | 6 (1) | |
| http://rsdn.ru/File/5317/DllSingleton2.zip |
| Re[2]: Сделал! | Оценить ![]() ![]() ![]() ![]() ![]() ![]() |
| От: | EqWu | http://www.microsoft.com/rus |
| Дата: | 27.03.06 14:27 |
| Здравствуйте, avs99, Вы писали: A>Ну что ж, позвольте отчитаться о проделанной работе Поздравляю. |