Из предыдущих глав вам должен быть понятен или, по крайней мере, известен механизм, который используется Windows для управления окнами приложений, – сообщения. Вероятно, большая мощь этого механизма и в то же время его уязвимость состоят в возможности посылки сообщений любым окнам (окнам одного процесса или окнам других процессов).
В Windows также предусмотрен мощный механизм, позволяющий следить за некоторыми важными событиями в системе и, конечно, производить мониторинг сообщений, получаемых различными окнами. Речь идет об установке так называемых ловушек. Ловушка представляет собой функцию, вызываемую при возникновении определенного события, например перед получением каким-либо окном нового сообщения, при нажатии клавиши, записи события в системный журнал и т. д.: все зависит от того, для каких событий разработчики предусмотрели ловушки. Интересен тот факт, что в Windows предусмотрены даже ловушки для отладки других ловушек.
Мы рассмотрим некоторые наиболее простые виды ловушек, перехватывающих сообщения окон. По глобальности действия рассмотренные нами ловушки являются устанавливаемыми на отдельный поток: при ошибке в функции-ловушке это безопаснее для системы.
Начинается создание ловушки с написания собственно функции-ловушки, имеющей следующий прототип:
...
function HookProc(code: Integer; wParam: WPARAM; lParam: LPARAM): LRESULT stdcall;
Параметр code используется для обозначения тех случаев, когда функция ловушки должна вызвать специальную API-функцию CallNextHookEx и вернуть значение, возвращенное ею. Назначения параметров wParamи lParam этой функции сильно зависят от того, для реакции на какое именно событие ловушка используется.
Для регистрации ловушки используется API-функция SetWindowsHookEx, имеющая следующий прототип:
...
function SetWindowsHookEx(idHook: Integer; //Тип ловушки
lpfn: TFNHookProc; //Адрес функции-ловушки
hmod: HINST; //Используемый модуль, в котором
//расположена функция ловушки
dwThreadId: DWORD //Идентификатор потока, для
//которого создается ловушка
): HHOOK; stdcall;
В случае успешного создания ловушки функция SetWindowsHookEx возвращает дескриптор новой ловушки (ненулевое значение).
Для удаления ловушки используется функция UnhookWindowsHookEx, принимающая единственный параметр – дескриптор ловушки, возвращенный функцией SetWindowsHookEx. Причем удаление ловушки нужно производить обязательно, поэтому по крайней мере при закрытии приложения не следует забывать вызывать функцию UnhookWindowsHookEx.
Теперь несколько слов о функции CallNextHookEx. Ее объявление имеет следующий вид:
...
function CallNextHookEx(hhk: HHOOK; nCode: Integer;
wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
В чем важность этой функции? Она предназначена для продолжения передачи сообщения по цепочке ловушек (ведь одновременно несколько приложений могут создать несколько ловушек). Вызов этой функции настоятельно рекомендуется осуществлять в любом случае (независимо от значения параметра code функции-ловушки), только если целью не стоит блокирование других ловушек.
Виды ловушек
Приведем список некоторых простых типов ловушек, а именно констант из модуля Windows, их обозначающих и передаваемых в функцию SetWindowsHookEx:
• WH_CALLWNDPROC – функция ловушки вызывается каждый раз до вызова функции обработки сообщений окон, созданных наблюдаемым потоком;
• WH_CALLWNDPROCRET – вызывается каждый раз при возврате из функции обработки сообщений окон наблюдаемого потока;
• WH_KEYBOARD – функция ловушки вызывается перед обработкой сообщений WM_KEYDOWN и WM_KEYUP оконной функцией исследуемого потока;
• WH_MOUSE – вызывается перед обработкой оконной функцией наблюдаемого потока сообщений от манипулятора «мышь».
Рассмотрим, какое значение имеют параметры 1 Par am и wParam функции-ловушки в каждом из перечисленных случаев.
Перехват вызова оконной функции
Итак, для ловушки WH_CALLWNDPROC, которая, кстати, используется в рассматриваемом далее приложении, два последних параметра функции-ловушки трактуются следующим образом:
• wParam – равен нулю, если сообщение послано в окно тем же потоком, в котором исполняется функция ловушки, и не равен нулю, если сообщение послано другим потоком;
• lParam – указатель на структуру TCWPStruct, содержащую информацию о сообщении, которое передано окну (и будет передано в оконную функцию).
Объявление структуры TCWPStruct с описанием ее полей выглядит следующим образом:
Читать дальше
Конец ознакомительного отрывка
Купить книгу