Ассемблер под Windows №29

Хуки в Windows #2


Доброго времени суток, уважаемые подписчики. Сегодня мы подробнее рассмотрим возможности Windows-хуков.


Вначале следует заметить, что существует два разных типа хуков, локальные и глобальные. Не смотря на то, что работают они одинаково, между ними существует огромная разница в исполнении. Тогда как хук-процедуры локальных хуков могут находится где угодно, хук-процедуры глобальных хуков ДОЛЖНЫ находиться в динамической библиотеки. Именно это даёт им возможность быть загруженными в адресное пространство любого приложения, а это, в свою очередь, означает возможность перехватывать сообщения всех приложений одновременно. Как было упомянуто в прошлом выпуске, хуки бывают следующих типов:
WH_CALLWNDPROC    - Перехватывает ВСЕ сообщения ДО того как их получает процедура окна
WH_CALLWNDPROCRET - Перехватывает ВСЕ сообщения ПОСЛЕ того как их обработала процедура окна
WH_CBT            - Перехватывает сообщения связанные с изменениями окна
WH_DEBUG          - Перехватывает ВСЕ сообщения прежде чем они попадают к хук-процедурам
WH_KEYBOARD       - Перехватывает "клавиатурные" сообщения, такие как нажатие клавиши
WH_MOUSE          - Перехватывает сообщения мышки
WH_MSGFILTER      - Перехватывает сообщение посланые диалогом, MessageBox-ом, меню или ScrollBar-ом
WH_SHELL          - Перехватывает сообщения оболочки (то есть Windows), такие как изменение текущего языка ввода текста
Сегодня мы рассмотрим использование этих типов (кроме WH_CBT) хуков и их процедур.
Первый тип хуков, это WM_CALLWNDPROC. Он вызывается если любое сообщение отправлено (была вызвана функция SendMessage, PostMessage и т.п.), перед тем, как его получает окно. Сообщение нельзя изменять. Хук-процедура получает 3 параметра, хук-код, флаг текущего процесса и указатель на структуру CWPSTRUCT,
CWPSTRUCT struc
  lParam  dd ?
  wParam  dd ?
  message dd ?
  hWnd    dd ?
CWPSTRUCT endp
Флаг текущего процесса равно нулю, если сообщение не относится к текущему процессу.
Следующий тип, WM_CALLWNDPROCRET отличается нем, что вызывается после обработки сообщения процедурой окна, и тем, что получает указатель на структуру CWPRETSTRUCT вместо CWPSTRUCT.
CWPRETSTRUCT struc
  lResult dd ?
  lParam  dd ?
  wParam  dd ?
  message dd ?
  hWnd    dd ?
CWPRETSTRUCT endp
Такие хуки имеет смысл устанавливать тогда, когда нужен полный контроль за тем, что происходит в системе.
Установка хука с типом WH_DEBUG позволяет программисту решать, какие сообщения будут получены хук-процедурами, а какие нет. Такая хук-процедура вызывается перед вызовом других хук-процедур и от её результата зависит будут ли другие хук-процедуры вызваны. Она получает 3 параметра, хук-код, тип хука, который был перехвачен, и указатель на структуру DEBUGHOOKINFO.
DEBUGHOOKINFO struc
  idThread          dd ?
  idThreadInstaller dd ?
  lParam            dd ?
  wParam            dd ?
  code              dd ?
DEBUGHOOKINFO ends
Здесь lParam третий параметр, которой будет получен хук-процедурой (если функция возвращает ненулевое значение, то хук-процедура не будет вызвана и параметр получен не будет), wParam - второй параметр, code, первый параметр.
Хук-процедуры типа WM_MOUSE получают три параметра, хук-код, флаг текущего процесса и указатель на структуру MOUSEHOOKSTRUCT
MOUSEHOOKSTRUCT struc
  pt           POINT <>
  hWnd         dd ?
  wHitTestCode dd ?
  dwExtraInfo  dd ?
MOUSEHOOKSTRUCT ends
Здесь pt, точка, над которой находится мышка, hWnd - окно которому будет передано сообщение, wHitTestCode - код определяющий нахождение мышки по отношению к окнам, который может принимать одно из следующих значений:
КодНазваниеМесто нахождения мышки
-2HTERRORНа разделительной полосе между двумя окнами или на рабочем столе, Нажатие мышки в таком мете сопровождается Beep-ом
-1HTTRANSPARENTНа окне, которое закрыто другим окном
0HTNOWHEREНа разделительной полосе между двумя окнами или на рабочем столе
1HTCLIENTНа клиентской части окна (Client Area)
2HTCAPTIONНа Title bar-е окна
3HTSYSMENUНад системным меню или на кнопке закрытия дочерного окна
4HTGROWBOXМышкой можно изменять размер окна
5HTMENUНад меню
6HTHSCROLLНад горизонтальным Scroll bar-ом
7HTVSCROLLНад вертикальным Scroll bar-ом
8HTMINBUTTONНад кнопкой минимизации окна
9HTMAXBUTTONНад кнопкой максимизации окна
10HTLEFTНад левым краем окна
11HTRIGHTНад правым краем окна
12HTTOPНад верхним краем окна
13HTTOPLEFTНад верхним левым углом окна
14HTTOPRIGHTНад верхним правым углом окна
15HTBOTTOMНад нижнем краем окна
16HTBOTTOMLEFTНад нижним левым углом окна
17HTBOTTOMRIGHTНад нижним правым углом окна
18HTBORDERНад краем окна, размер которого нельзя изменять
Если хук-процедура возвращает ненулевое значение то сообщение не будет отправлено окну.
Хук процедура WM_SHELL имеет три параметра, но они очень отличаются для WinNT/Win2K/WinXP и Win95/Win98/WinMe. В первом случае следующие сообщение доступны (они передаются первым параметром):
КодНазваниеОписаниеВторой параметр
1HSHELL_WINDOWCREATEDПроизошло создание переднего окнаhandle созданного окна
2HSHELL_WINDOWDESTROYEDПроисходит уничтожение переднего окнаhandle уничтожаемого окна
3HSHELL_ACTIVATESHELLWINDOWОболочка (Windows) активизирует своё главное окноне используется
Третий параметр не используется. В случае Win95/Win98/WinMe кроме этих сообщений могут быть получены следующие:
КодНазваниеОписаниеТретий параметр
4HSHELL_WINDOWACTIVATEDАктивное окно сменилосьФлаг полноэкранности
5HSHELL_GETMINRECTОкно минимизировано или максимизировано, система определяет размер окнауказатель на структкру RECT
6HSHELL_REDRAWНазвание окна перерисовываетсяне используется
8HSHELL_LANGUAGEИзменён текущий языкне используется
Второй параметр - handle окна.


На сегодня это всё. В следующем уроке рассмотрим хук-процедуру WH_CBT. Если есть какие вопросы, пишите. Пишите на Dark_Lord@RusFAQ.ru или Dark_Lord@land.ru.

Сайт управляется системой uCoz