Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Найти окно по классу, в терминальной сессии 
:(
    Опции темы
Danger
Дата 23.7.2009, 13:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Привет всем,
Вобщем, есть терминальный сервер, удаленные пользователи через терминал запускают определенную программу (уникальный класс окна, создаваемый программой, знаю). Нужно "пробежаться" по всем сессиям, и проверить наличие в них окна с определенным классом.

Вот здесь уже обсуждалось: http://www.delphimaster.ru/cgi-bin/forum.p...9955786&n=5 попробовал, как описано - нифига не работает. Непонятно, как получить Desktop терминальной сессии ( WTSEnumerateSessions() перечисляет лишь имена сессий, но не windows stations). Максимум, могу получить список процессов терминальной сессии - но по ним же я не могу получить список окон, созданных этими процессами?

Кто знает, посоветуйте, пожалста..

PM WWW ICQ Jabber   Вверх
kami
Дата 23.7.2009, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



WTSEnumerateSessions возвращает массив WTS_SESSION_INFO, один из параметров которой - pWinStationName.

Пройдя по массиву, найдя нужную терминальную сессию и WinSta, проходим по EnumDesktops, находим нужный и EnumDesktopWindows.

Добавлено через 8 минут и 36 секунд
мда...
поторопился немного. Для того, чтобы перечислить десктопы нужно открыть winSta, а в OpenWindowStation не учитывается сессия...
PM MAIL WWW   Вверх
kami
Дата 23.7.2009, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  23.7.2009,  13:12 Найти цитируемый пост)
Максимум, могу получить список процессов терминальной сессии - но по ним же я не могу получить список окон

а если так:
WTSEnumerateProcesses>CreateToolhelp32Snapshot & Thread32First|Next>EnumThreadWindows .....
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 05:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(kami @ 23.7.2009,  17:59)
Для того, чтобы перечислить десктопы нужно открыть winSta, а в OpenWindowStation не учитывается сессия...

Кстати, в процессе я так и не понял, что там с windows station в терминальных сессиях. То ли, используется текущая (консольная) window station ('WInSta0'), либо для всех терминальных сессий window station называется всегда одинаково (упомянутый 'WinSta0').

Вообще, существует ли способ перечислить не сессии, а window station терминальных сессий?

Насчет 
Цитата(kami @ 23.7.2009,  17:59)
WTSEnumerateProcesses>CreateToolhelp32Snapshot & Thread32First|Next>EnumThreadWindows .....

Неясно, как связать данные, получаемые через WTSEnumerateProcesses() и CreateToolhelp32Snapshot().
Точнее, непонятно зачем нужна CreateToolhelp32Snapshot(), если WTSEnumerateProcesses() и так вернет список терминальных процессов? Может, CreateToolhelp32Snapshot() не нужен, или я что-то не понимаю?


Это сообщение отредактировал(а) Danger - 24.7.2009, 06:03
PM WWW ICQ Jabber   Вверх
kami
Дата 24.7.2009, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
 что там с windows station в терминальных сессиях

afaik, каждой терминальной сессии соответствует одна (СВОЯ) winSta. А вот название ее может отличаться:
Цитата

pWinStationName

Pointer to a null-terminated string that contains the WinStation name of this session. The WinStation name is a name that Windows associates with the session, for example, "services", "console", or "RDP-Tcp#0".



Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
непонятно зачем нужна CreateToolhelp32Snapshot(), если WTSEnumerateProcesses() и так вернет список терминальных процессов? Может, CreateToolhelp32Snapshot() не нужен, или я что-то не понимаю?

Наоборот smile это я опять недосмотрел, что в CreateToolhelp32Snapshot при указании TH32CS_SNAPTHREAD будут перечисляться все потоки в системе, а не потоки текущего процесса.

Цитата(Danger @  24.7.2009,  05:21 Найти цитируемый пост)
WTSEnumerateProcesses() и так вернет список терминальных процессов?

ну да, но окна-то вроде можно перечислить только для потока, а не для процесса (EnumThreadWindows), соответственно - просто список процессов ничего не даст...
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



так что же делать?  smile я запутался, честно.
PM WWW ICQ Jabber   Вверх
kami
Дата 24.7.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



попробуй так:
CreateToolhelp32Snapshot>Thread32First|Next>EnumThreadWindows>GetClassName.

Если нужно потом найти, в какой сессии это окно находится, то:
в Thread32First|Next>THREADENTRY32 есть параметр th32OwnerProcessID.
ProcessIDToSessionID, а зная SessionID можно получать о ней информацию из WTSQuerySessionInformation...
PM MAIL WWW   Вверх
Danger
Дата 24.7.2009, 20:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(kami @ 24.7.2009,  12:52)
попробуй так:
CreateToolhelp32Snapshot>Thread32First|Next>EnumThreadWindows>GetClassName.

Такое ощущение, что в слепок попадают только потоки, принадлежащие текущей window station.
Ни одного потока с процессов другого терминального пользователя..

Код

.....
//-----------------------------------------------------
function EnumThreadWndProc( Wnd: HWND; Param: LParam ): Boolean; stdcall;
var
 dwProcessId: DWord; strOwner: string;
 timeCreate: PFileTime;

begin
  Result:= true;  // we're enumerate all the thread windows

  ZeroMemory( @strWndClass, dwBufferSize );
  GetClassName( Wnd, strWndClass, dwBufferSize - 1 );

    dwProcessId:= PTHREADENTRY32( Param )^.th32OwnerProcessID;
    New( timeCreate );
    try
      if ( GetProcessParams( dwProcessId, strOwner, timeCreate ) ) then
      begin
        // using OEM codepage
        CharToOem( PChar( strOwner), PChar( strOwner ) );
        WriteLn( ' | ', dwProcessId, #9, '| ', FileTimeToStr( timeCreate ), #9, '| ', strOwner, #9, '|' );
      end;
     finally
       Dispose( timeCreate );
     end;
end;

//-----------------------------------------------------
begin
 .....

 // take a snapshot of all running threads
 hThreadSnap:= CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
 if ( hThreadSnap > 0 ) then
 begin

   te32.dwSize:= SizeOf( THREADENTRY32 );
   if ( Thread32First( hThreadSnap, te32 ) ) then
   begin
     EnumThreadWindows( te32.th32ThreadID, @EnumThreadWndProc, Integer( @te32 ) );
     // now walk the thread list of the system
     while ( Thread32Next( hThreadSnap, te32 ) ) do
      EnumThreadWindows( te32.th32ThreadID, @EnumThreadWndProc, Integer( @te32 ) );
   end;

   CloseHandle( hThreadSnap );
 end; // 'if ( hThreadSnap > 0 ) then '

//-----------------------------------------------------

GetProcessParams() - простейшая функция-"обёртка", возвращает некоторые параметры процесса..
PM WWW ICQ Jabber   Вверх
kami
Дата 25.7.2009, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Так погляжу, на "соседнем" форуме посоветовали то, о чем я думал, но не хотел говорить - может есть менее обходной путь, чем запуск дополнительного процесса в каждой терминальной сессии...
Но мнение Eraser -а в таких вопросах можно считать непререкаемым.
Посему - уточняющие вопросы: версия ОС, в которой нужно найти нужное окно в терминальной сессии?
PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 00:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(kami @ 25.7.2009,  22:32)
Так погляжу, на "соседнем" форуме посоветовали то, о чем я думал, но не хотел говорить - может есть менее обходной путь, чем запуск дополнительного процесса в каждой терминальной сессии...

А что, если отталкиваться от списка процессов, возвращаемых WTSEnumerateProcesses() ?
Т.е. получить список процессов, потом для каждого из них потоки, и в них искать окно? (без создания снимков).

Цитата(kami @ 25.7.2009,  22:32)

Посему - уточняющие вопросы: версия ОС, в которой нужно найти нужное окно в терминальной сессии?

MS Windows 2003 VLK Russian (R2), 32bit.
PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 03:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
получить список процессов, потом для каждого из них потоки, и в них искать окно?

Не нашел функцию перечисления потоков по известному процессу. :( Покажете, как?

Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
MS Windows 2003

Ага, значит предложенное Eraser-ом более чем возможно.


Это сообщение отредактировал(а) kami - 26.7.2009, 03:34
PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(kami @ 26.7.2009,  03:34)
Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
получить список процессов, потом для каждого из них потоки, и в них искать окно?

Не нашел функцию перечисления потоков по известному процессу. :(
Я имею в виду, сделать снимок CreateToolhelp32Snapshot() по ProcessID терминального процесса, и перечислить потоки по Thread32First() / Thread32Next(). Хотя, боюсь, получится то же самое (но попробовать стоит).

Цитата(kami @ 26.7.2009,  03:34)
Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)

Цитата(Danger @  26.7.2009,  00:21 Найти цитируемый пост)
MS Windows 2003

Ага, значит предложенное Eraser-ом более чем возможно.
Проблема в том, что мне придется внедрять свой процесс в сессию каждого терминального пользователя, либо для каждого пользователя добавлять в автозагрузку прогу, постоянно висящую в памяти. И все это только для того, чтоб я когда-то мог узнать -  есть ли у пользователя на десктопе данное окно.

PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  26.7.2009,  10:58 Найти цитируемый пост)
делать снимок CreateToolhelp32Snapshot() по ProcessID терминального процесса, и перечислить потоки по Thread32First() / Thread32Next()

Цитата(kami @  24.7.2009,  12:33 Найти цитируемый пост)
 в CreateToolhelp32Snapshot при указании TH32CS_SNAPTHREAD будут перечисляться все потоки в системе, а не потоки текущего процесса.


PM MAIL WWW   Вверх
Danger
Дата 26.7.2009, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Что характерно: запускаю Process Explorer от Sysinternals (в терминальной сессии), и он мне исправно перечисляет процессы других терминальных пользователей и потоки в них.
Да банально: диспетчер задач отображает все процессы, всех пользователей (с указанием имени пользователя и параметров процесса). Как-то же он это делает?

Это сообщение отредактировал(а) Danger - 26.7.2009, 18:25
PM WWW ICQ Jabber   Вверх
kami
Дата 26.7.2009, 20:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
запускаю Process Explorer от Sysinternals (в терминальной сессии), и он мне исправно перечисляет процессы других терминальных пользователей и потоки в них.

afaik, он использует свой драйвер, устанавливаемый на время его работы (драйвер находится в его ресурсах). Иначе многие из его возможностей (к примеру - закрытие любого хендла) из user-mode выглядят нереально.


Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
диспетчер задач отображает все процессы, всех пользователей (с указанием имени пользователя и параметров процесса). Как-то же он это делает?

Да перечислить процессы и получить их параметры не так и сложно. А вот перечислить потоки процесса и окна потоков - с учетом 
Цитата(Danger @  24.7.2009,  20:16 Найти цитируемый пост)
Такое ощущение, что в слепок попадают только потоки, принадлежащие текущей window station.

не вижу решения, кроме предложенного eraser-ом.

P.S. А почему именно окно?
Нельзя будет обойтись запущен/не запущен процесс?
PM MAIL WWW   Вверх
Danger
Дата 27.7.2009, 06:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(kami @ 26.7.2009,  20:45)
Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
запускаю Process Explorer от Sysinternals (в терминальной сессии), и он мне исправно перечисляет процессы других терминальных пользователей и потоки в них.

afaik, он использует свой драйвер, устанавливаемый на время его работы (драйвер находится в его ресурсах). Иначе многие из его возможностей (к примеру - закрытие любого хендла) из user-mode выглядят нереально.

Возможно. Кстати, я вышел даже на NtQuerySystemInformation() с недокументированным параметром для перечисления потоков, но результат ее использования аналогичен функциям из ToolHelp - в список исправно попадают все процессы/потоки, но только текущей сессии. Ни один процесс, принадлежащий другому пользователю, просто не попадает в список.

Цитата(kami @ 26.7.2009,  20:45)
Цитата(Danger @  26.7.2009,  15:06 Найти цитируемый пост)
диспетчер задач отображает все процессы, всех пользователей (с указанием имени пользователя и параметров процесса). Как-то же он это делает?

Да перечислить процессы и получить их параметры не так и сложно. А вот перечислить потоки процесса и окна потоков - с учетом 
Цитата(Danger @  24.7.2009,  20:16 Найти цитируемый пост)
Такое ощущение, что в слепок попадают только потоки, принадлежащие текущей window station.
P.S. А почему именно окно?
Нельзя будет обойтись запущен/не запущен процесс?

Довольно проблематично проверять "аутентичность процесса". По каким критериям лучше всего определять соответствие процесса нужному?

На первый взгляд, все параметры, по которым можно проверить, что запущен именно нужный исполнимый файл (работает нужный процесс) - ИМХО легко подделать обычному пользователю. Например, подменить exe-файл.
PM WWW ICQ Jabber   Вверх
kami
Дата 27.7.2009, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1806
Регистрация: 25.8.2007
Где: Санкт-Петербург

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



Цитата(Danger @  27.7.2009,  06:34 Найти цитируемый пост)
все параметры, по которым можно проверить, что запущен именно нужный исполнимый файл (работает нужный процесс) - ИМХО легко подделать обычному пользователю. Например, подменить exe-файл.

Хм...
Обычный юзверь не должен иметь прав подменять рабочие экзешники (это если админ грамотный). Тем более он не должен иметь прав админа, чтобы дать себе такие права smile
Но и без этого проверить оригинальность файла можно: действительное полное имя файла, всякие crc32, MD5 и иже с ними, доп. информация о версии файла...
PM MAIL WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

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


 




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


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

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