7.5.1 - Установка и освобождение подключаемых процедур (Hook Procedures)

Вы можете установить подключаемую процедуру, вызывая функцию SetWindowsHookEx и определяя тип hook-точки, вызывающей процедуру, независимо должна ли процедура быть связана со всеми потоками или с отдельным потоком, и указатель на точку входа процедуры.

Вы должны поместить глобальную подключаемую процедуру в динамически подключаемой библиотеке (DLL), отделенной от прикладной программы, устанавливающей подключаемую процедуру. Приложение установки должно иметь дескриптор модуля динамически подключаемой библиотеки (DLL) прежде, чем оно может установить подключаемую процедуру. Функция LoadLibrary, когда дается имя динамически подключаемой библиотеке (DLL), возвращает дескриптор модуля DLL. После того, как Вы получите дескриптор, Вы можете вызвать функцию GetProcAddress, чтобы получить адрес подключаемой процедуры. Наконец, Вы используете SetWindowsHookEx, чтобы установить адрес подключаемой процедуры в соответствующую цепочку hook-точек. SetWindowsHookEx передает дескриптор модуля, указатель на точку входа подключаемой процедуры и 0 для идентификатора потока, указывая, что подключаемая процедура должна быть связана со всеми потоками в системе. Эта последовательность действий показывается в следующем примере.

HOOKPROC hkprcSysMsg;
static HINSTANCE hinstDLL;
static HHOOK hhookSysMsg;
hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll");
hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc");
hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER, hkprcSysMsg, hinstDLL, 0);

Вы можете освободить установленную потоком подключаемую процедуру (удалите ее адрес из цепочки hook-точек) вызвав функцию UnhookWindowsHookEx, которая определяет дескриптор подключаемой процедуры предназначенной для освобождения. Освобождайте подключаемую процедуру, как только ваша прикладная программа больше не нуждается в ней.

Вы можете освободить глобальную подключаемую процедуру, используя UnhookWindowsHookEx, но эта функция не освобождает динамически подключаемую библиотеку (DLL), содержащую подключаемую процедуру. Это происходит потому, что глобальные подключаемые процедуры вызываются в контексте процесса каждой прикладной программы в системе, вынуждая подразумеваемый вызов функции LoadLibrary для всех этих процессов. Поскольку вызов функции FreeLibrary не может быть сделан для другого процесса, следовательно, нет никакого способа освободить DLL. Windows, в конечном счете, освобождает DLL после того, как все процессы, явно связанные с ней или завершили работу или вызвали FreeLibrary, а все процессы, которые обратились к подключаемой процедуре, она продолжила обрабатывать вне динамически подключаемой библиотеки (DLL).

Альтернативный метод для установки глобальной подключаемой процедуры состоит в том, чтобы предусмотреть инсталляционную функцию в динамически подключаемой библиотеке (DLL), наряду с подключаемой процедурой. С этим методом, прикладная программа установки не нуждается в дескрипторе модуля DLL. Связываясь с DLL, прикладная программа получает доступ к инсталляционной функции. Инсталляционная функция может снабдить модуль динамически подключаемой библиотеки (DLL) дескриптором и другие деталями при обращении к SetWindowsHookEx. Динамически подключаемая библиотека (DLL) может также содержать функцию, которая освобождает глобальную подключаемую процедуру; прикладная программа может вызывать при завершении функцию этой освобождающейся hook-точки.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Владимир Соковиков - 18.06.2002