| 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. Разбираются способы взаимодействия с внедренной библиотекой. Вот такие вот пироги Ну и персональная благодарность Тому и Владимиру за подкинутые идеи! Спасибо, мужики, вы меня очень здорово выручили! Алексей ЗЫ код всего выложу вечером или в выходные. |