Здравствуйте все. Такая проблема - написал программку перехвата клавиатуры ( SetWindowsHookExA с параметром idHook == WH_KEYBOARD_LL). Всё классно... НО! теперь пожелал я эту гадость спрятать. Прятать в пользовательском процессе (том же Explorer) - банально, да и юзер может его перезапустить... Поэтому решил сразу по-взрослому - и запихнул его в WINLOGON (вот так прямо сразу и в WINLOGON!). Запихнул... И ничего. т.е. никакого вам перехвата клавиатуры, ничего. Посмотрел что вывелось в лог-файл: процедура (LowLevelKeyboardProc) в адресном пространстве WINLOGON'а есть, лежит по такому-то адресу... SetWindowsHookExA для этой процедуры отработал, вернул хэндл хука... WINLOGON не падает... Походил, пофтыкал, ничего не придумал. Тем временем машина заблокировалась. Нажимаю Alt+Ctrl+Del, ввожу пароль, для очистки совести лезу в файл лога. Там ПАРОЛЬ!!! Блин! Приехали... У Руссиновича написано, что WINLOGON, вешает хук на Alt+Ctrl+Del, блокирует другие хуки и остальные процессы, т.о. он единственный, кто может подсмотреть пользовательский пароль. А получается, что любой пользователь, который имеет возможность запустить сервис (ну или что-то прописать в ветку RunOnce) может получить пароль чела, интерактивно логинящегося на рабочую станцию. Пытаюсь мыслить логично, делаю совершенно дурацкий вывод, что WINLOGON перехватывает сообщения только когда у него активно какое-то окно. Это никак не вяжется с тем, что у потока, который живёт в WINLOGON'е (я его сам туда подселил) есть свой цикл выборки сообщений, но я это игнорирую. Создаю второй поток в WINLOGON'е, на этот раз вывожу на десктоп окно. И опять ничего... Нажимаю Alt+Ctrl+Del и наблюдаю своё окно. Рядом с окном "Безопасность Windows". (Понимаю, что рисовать окна инжектя свой код с чужой процесс, да ещё и в системный - это просто пинцет, но интерес уже чисто исследовательский...). Догоняю, что надо почитать мануал. Почитал. Обнаружил что WINLOGON создаёт 2 десктопа, причём окно "Безопасность Windows" живёт в его первом десктопе (системном, созданном для входа пользователя в систему). А во втором десктопе живёт пользователь и пользовательские процессы. Решил создать окно как дочернее от пользовательского десктопа. В программе, которая запускает потоки перехвата клавиатуры и рисования окна получаю HWND десктопа, пихаю в WINLOGON - облом. Хэндл валиден только в своем процессе. Можно, конечно, сделать DuplicateHandle в WINLOGON'е, но это уж сильный изврат. Теперь собственно вопросы: 1. Как получить хэндлы десктопов созданных процессом, чтобы привязать выводимое окно к определённому из них? 2. Как привязать клавиатурный хук к какому-либо десктопу (или привязать цикл выборки сообщений потока к десктопу, не знаю как правильней.) Заранее всем спасибо
Отвечу кратко, ибо времени нет. var hStaPrev,hSta:HWINSTA; hDeskPrev,hDesktop:HDESK; begin hStaPrev:=GetProcessWindowStation; hDeskPrev:= GetThreadDesktop(GetCurrentThreadId); hSta:=OpenWindowStation(pchar('Winsta0'), false, MAXIMUM_ALLOWED ); SetProcessWindowStation(hSta); hDesktop:=OpenDesktop( pchar('Winlogon'), 0, false, MAXIMUM_ALLOWED ); SetThreadDesktop( hDesktop ); SetThreadDesktop( hDeskPrev ); SetProcessWindowStation( hStaPrev ); CloseDesktop( hDesktop ); CloseWindowStation( hSta ); end. Переключение на десктоп и виндоусстатион винлогона. Про декстопы читать в мсдн.