Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SendMessage() на чужой десктоп 
V
    Опции темы
leniviy
Дата 30.6.2012, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Привет. Я написал сервис, который стартует некое приложение на дефолтном десктопе интерактивной сессии.
При переключении пользователя приложение на старой сессии завершается и стартует новое.
Так как я стартую приложение через CreateProcessAsUser(), у меня есть хэндл процесса, который я передаю в TerminateProcess().
Но при таком завершении в трее остается значок.

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

Чтобы это обойти, я стартую второй вспомогательный процесс в сессии приложения и уже из него ищу окно и посылаю месагу.

Можно ли сделать это без вспомогательных процессов?
PM MAIL   Вверх
feodorv
Дата 30.6.2012, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
При переключении пользователя приложение на старой сессии завершается и стартует новое.

Не понятно, почему. Это Вы так специально задумали?

Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
сервис, который стартует некое приложение на дефолтном десктопе интерактивной сессии.

А на какой рабочей станции? winsta0?

Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
Но я не могу ни послать сообщение этому окну из сервиса, ни даже найти это окно.

Но это вопрос межпроцессного взаимодействия. Устроить его можно как угодно.
Например, через PostThreadMessage...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
feodorv
Дата 30.6.2012, 17:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
ни даже найти это окно.

Кстати, почему? Если у Вас есть описатель десктопа, то Вы можете в сервисе назначить потоку, выполняющему CreateProcessAsUser, десктоп через SetThreadDesktop или SetProcessWindowStation, и уже после старта нового процесса дождаться, когда он проинициализируется и опустошит очередь, а затем выполнить поиск окна, кмк.


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
leniviy
Дата 1.7.2012, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(feodorv @  30.6.2012,  17:46 Найти цитируемый пост)

Кстати, почему? Если у Вас есть описатель десктопа, то Вы можете в сервисе назначить потоку, выполняющему CreateProcessAsUser, десктоп через SetThreadDesktop или SetProcessWindowStation, и уже после старта нового процесса дождаться, когда он проинициализируется и опустошит очередь, а затем выполнить поиск окна, кмк. 


Цитата(OpenDesktop)
This desktop must belong to the current window station.

значит надо перед этим вызвать SetProcessWindowStation()

Цитата(OpenWindowStation)
This window station must belong to the current session.

Поменять sessionid процесса никак
PM MAIL   Вверх
feodorv
Дата 1.7.2012, 16:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(leniviy @  1.7.2012,  12:47 Найти цитируемый пост)
Поменять sessionid процесса никак 

Я потерялся. Мы сейчас о чём?

Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
При переключении пользователя

Пользователь может быть только один? Никак не больше?

Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
некое приложение

Приложение Ваше? Вы его можете менять/модифицировать?

Цитата(leniviy @  1.7.2012,  12:47 Найти цитируемый пост)
OpenWindowStation

Вот честно, никогда лично не пробовал поиск окна в чужом десктопе, но, думаю, у сервиса достаточно прав, чтобы такое учудить.
Код

saveWinsta = GetProcessWindowStation();
activeWinsta = OpenWindowStation( "winsta0", ....);
SetProcessWindowStation( activeWinsta );
hdesk = OpenDesktop( "default", ...);
SetProcessWindowStation( saveWinsta );
EnumDesktopWindows( hdesk, ....);
CloseDesktop( hdesk );
CloseWindowStation( activeWinsta );

Подобные шаги Вы должны бы были предпринимать, чтобы обеспечить доступ окну своего "некоего приложения" к активному десктопу.
И не знаю точно, что там наперечисляет EnumDesktopWindows, если вообще что-нибудь перечислит...

Это сообщение отредактировал(а) feodorv - 1.7.2012, 16:34


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
leniviy
Дата 1.7.2012, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(feodorv @  1.7.2012,  16:31 Найти цитируемый пост)
Цитата(leniviy @  1.7.2012,  12:47 Найти цитируемый пост)
Поменять sessionid процесса никак 

Я потерялся. Мы сейчас о чём?


Я так понимаю, winsta0\default у каждой сессии свой. Я попробую, конечно.

PM MAIL   Вверх
feodorv
Дата 1.7.2012, 17:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Может, вот это поможет  smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
leniviy
Дата 1.7.2012, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(feodorv @  1.7.2012,  17:14 Найти цитируемый пост)
Может, вот это поможет  smile  

Там в итоге CreateProcessAsUser() . Это-то как раз не проблема.

Код

static
BOOL CALLBACK MyEnumProc(HWND hwnd, LPARAM lparam) {
    TCHAR txt1[100], cls1[100];

    *(BOOL*)lparam = TRUE;

    _ftprintf(stderr, "MyEnumProc() hwnd=%p\n", (void*)hwnd);
    if (GetClassName(hwnd, cls1, ARRAYLEN(cls1))) {
      _ftprintf(stderr, _T("class: %s\n"), cls1);
    } else {
      pWin32Error("GetClassName() failed");
    }
    if (!GetWindowText(hwnd, txt1, ARRAYLEN(txt1)) && GetLastError() != 0) {
      pWin32Error("GetWindowText() failed");
    } else {
      _ftprintf(stderr, _T("text: %s\n"), txt1);
    }
  return TRUE;
}

    HWINSTA saveWinsta = GetProcessWindowStation();
    HWINSTA activeWinsta = OpenWindowStation( "winsta0", TRUE, WINSTA_ALL_ACCESS);
    if (!activeWinsta) {
      pWin32Error("OpenWindowStation() failed");
    } else {
      if (!SetProcessWindowStation( activeWinsta )) {;
        pWin32Error("SetProcessWindowStation() failed");
      } else {
        HDESK hdesk = OpenDesktop( "default", 0, TRUE, GENERIC_ALL);
        if (!hdesk) {
          pWin32Error("OpenDesktop() failed");
        } else {
          if (!SetThreadDesktop(hdesk)) {
            pWin32Error("SetThreadDesktop() failed");
          } else {
            BOOL ok = FALSE;
            EnumDesktopWindows( hdesk, MyEnumProc, (LPARAM)&ok);
            if (!ok) {
              pWin32Error("EnumDesktopWindows() failed");
            }
          }
        }
        CloseDesktop( hdesk );
      }
      CloseWindowStation( activeWinsta );
    }
    SetProcessWindowStation( saveWinsta );



маловато окон:
Код

MyEnumProc() hwnd=000100A6
class: EF0F4B22-39FC-4902-A2FA-57A0730A2A7C
text: 
MyEnumProc() hwnd=000100A0
class: EF0F4B22-39FC-4902-A2FA-57A0730A2A7C
text: 
MyEnumProc() hwnd=000100A8
class: IME
text: Default IME
MyEnumProc() hwnd=000100A2
class: IME
text: Default IME

Все окна принадлежат explorer.exe, запущенному в активной сессии.

Добавлено через 2 минуты и 42 секунды
Цитата(feodorv @  1.7.2012,  16:31 Найти цитируемый пост)
Приложение Ваше? Вы его можете менять/модифицировать?

Не мое. Это cdlocker.
Его надо рестартовать при просыпании и при переключении.
PM MAIL   Вверх
feodorv
Дата 1.7.2012, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(leniviy @  1.7.2012,  18:38 Найти цитируемый пост)
Не мое. 

Возможно, стоит обратиться к разработчику с целью выработки приемлемого решения проблемы)))


Цитата(leniviy @  1.7.2012,  18:38 Найти цитируемый пост)
маловато окон

Мда. Либо всё неправильно, либо одно из двух)))

Первое. Дело в EnumDesktopWindows. К сожалению, в ближайшее время я не смогу воспроизвести эту интересную ситуацию, но можно Вас попросить заменить EnumDesktopWindows на просто EnumWindows?

Второе. Вы правы:
Цитата(leniviy @  1.7.2012,  17:55 Найти цитируемый пост)
winsta0\default у каждой сессии свой.

Но тогда я не понимаю, как Вы исхитрились запустить cdlocker на активном десктопе. Неужели, для этого достаточно SERVICE_INTERACTIVE_PROCESS плюс sessionid в токене? Без установки дополнительных прав для десктопа?

Можно Вас так же попросить выполнить подобный код:
Код

USEROBJECTFLAGS uof;
DWORD tmp;
GetUserObjectInformation( hWinsta, UOI_FLAGS, &uof, sizeof(uof), &tmp);
if( (uof.dwFlags & WSF_VISIBLE) != 0 )
  _ftprintf( stderr, _T("test: visible\n"));
else
  _ftprintf(stderr, _T("test: not visible\n"));

для saveWinsta перед установкой activeWinsta и для activeWinsta перед восстановлением saveWinsta?

Тогда решение с
Цитата(leniviy @  30.6.2012,  16:23 Найти цитируемый пост)
я стартую второй вспомогательный процесс в сессии приложения и уже из него ищу окно и посылаю месагу

вполне адекватное  smile 

ЗЫ Впрочем, хендл десктопа главного потока запущенного процесса можно попробовать получить через GetThreadDesktop, безо всяких дополнительных телодвижений. И тогда можно будет попробовать EnumDesktopWindows на правильном десктопе... Но PostMessage/SendMessage всё равно работать не будут...

Это сообщение отредактировал(а) feodorv - 1.7.2012, 22:06


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
leniviy
Дата 1.7.2012, 22:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(feodorv @  1.7.2012,  20:09 Найти цитируемый пост)
Но тогда я не понимаю, как Вы исхитрились запустить cdlocker на активном десктопе. Неужели, для этого достаточно SERVICE_INTERACTIVE_PROCESS плюс sessionid в токене? Без установки дополнительных прав для десктопа?

Я взял пример отсюда
http://www.rsdn.ru/forum/winapi/4243735.1.aspx

Добавлено через 8 минут и 22 секунды
Цитата(feodorv @  1.7.2012,  20:09 Найти цитируемый пост)

для saveWinsta перед установкой activeWinsta и для activeWinsta перед восстановлением saveWinsta?

saveWinsta test: not visible
activeWinsta test: visible

Добавлено через 8 минут и 49 секунд
Цитата(feodorv @  1.7.2012,  20:09 Найти цитируемый пост)
но можно Вас попросить заменить EnumDesktopWindows на просто EnumWindows?

одинаковый результат
PM MAIL   Вверх
feodorv
Дата 1.7.2012, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
Я взял пример отсюда

Спасибо за ссылку! Всё таки без WTS-функций не обошлось)))

Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
activeWinsta test: visible

Ха!

Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
одинаковый результат 

Ну да, всё правильно...

Полистал Интеренет, похоже, другого решения, кроме как запуск процесса в соответствующее окружение, нет smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
bass
Дата 26.7.2012, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: 2
Всего: 2



Цитата(feodorv @ 1.7.2012,  23:35)
Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
Я взял пример отсюда

Спасибо за ссылку! Всё таки без WTS-функций не обошлось)))

Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
activeWinsta test: visible

Ха!

Цитата(leniviy @  1.7.2012,  23:28 Найти цитируемый пост)
одинаковый результат 

Ну да, всё правильно...

Полистал Интеренет, похоже, другого решения, кроме как запуск процесса в соответствующее окружение, нет smile

Есть но тоже геморойный, инжектить свою длл в процесс и корректно его завершать.
PM MAIL   Вверх
feodorv
Дата 27.7.2012, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 9
Всего: 45



Цитата(bass @  26.7.2012,  12:01 Найти цитируемый пост)
Есть но тоже геморойный, инжектить свою длл в процесс и корректно его завершать. 

Интересно, а перекрыла ли Майкрософт кислород в возможности дебажить (из одной сессии) процессы (из другой сессии)... Я бы всё-таки ещё надеялся на имперсонализацию... А вдруг...


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
leniviy
Дата 27.7.2012, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(feodorv @  27.7.2012,  00:43 Найти цитируемый пост)
Цитата(bass @  26.7.2012,  12:01 Найти цитируемый пост)
Есть но тоже геморойный, инжектить свою длл в процесс и корректно его завершать. 

Интересно, а перекрыла ли Майкрософт кислород в возможности дебажить (из одной сессии) процессы (из другой сессии)... Я бы всё-таки ещё надеялся на имперсонализацию... А вдруг... 

.dll можно добавить, пропатчив .exe файл. Это работает с несжатыми. Сжатые upx можно распаковать, сжатые проприетарно, типа skype.exe, нельзя.
PM MAIL   Вверх
bass
Дата 29.7.2012, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 315
Регистрация: 5.8.2007

Репутация: 2
Всего: 2



Я не пропатчить а инжектить уже во время работы.....  Или распределить память в процессе там
Код

 push 0
 jmp exitprocess

И поменять eip главного потока на область этой памяти......


А вот пропатчить не увлекался этим. Есть у меня дллка сквозная называеться USER32.dll. Вот если ее подкинуть в папку программы то вместо системной сначала подсосеться она..... Ну и делай с процессом что хочешь. Незнаю что в висте будет и в семерке.

Добавлено @ 14:48
Цитата(feodorv @ 27.7.2012,  00:43)
Цитата(bass @  26.7.2012,  12:01 Найти цитируемый пост)
Есть но тоже геморойный, инжектить свою длл в процесс и корректно его завершать. 

Интересно, а перекрыла ли Майкрософт кислород в возможности дебажить (из одной сессии) процессы (из другой сессии)... Я бы всё-таки ещё надеялся на имперсонализацию... А вдруг...

Надо попробовать сам сейчас интересуюсь. Вот от юзера в систем точно незя.

Это сообщение отредактировал(а) bass - 29.7.2012, 14:53
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0600 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.