Чтение онлайн

на главную - закладки

Жанры

Шрифт:
...

Листинг 10.21.

Установка (создание) ловушки

function InstallHook(wnd: HWND; spy: HWND): Boolean stdcall;

begin

//Открываем проекцию файла (области файла подкачки)

if not GetFileMapping then

begin

//Не удалось спроецировать файл в память

InstallHook := False;

Exit;

end;

//Сохраняем данные, необходимые для работы ловушки

hook_info^.wnd := wnd;

hook_info^.spy_wnd := spy;

//Создаем ловушку

if (GetWindowThreadProcessId(wnd) <> 0)

then

hook_info^.hook_handle :=

SetWindowsHookEx(WH_CALLWNDPROC, WndProcHook,

hInstance, GetWindowThreadProcessId(wnd))

else

//Создание ловушки для потоков нашего приложения

//было бы фатальным

hook_info^.hook_handle := 0;

InstallHook := hook_info^.hook_handle <> 0;

//Освободим проекцию файла

ReleaseFileMapping;

end;

Функция InstallHook использует глобальную переменную-указатель hook_inf о, которая объявлена в модуле HookData. Функция GetFileMapping, также используемая в листинге 10.21, связывает указатель hookinf о с областью памяти, на которую проецируется файл. Соответственно, процедура ReleaseFileMapping отменяет проецирование файла в память (после этого использовать указатель hookinf о нельзя).

API-функция GetWindowThreadProcessId используется для определения идентификатора потока, создавшего наблюдаемое окно. Проверка неравенства значения, возвращенного этой функцией, нулю используется для того, чтобы в случае закрытия интересующего нас окна до запуска ловушки мы не начали следить за окнами приложения-шпиона.

Работу с проецируемым файлом в ловушке рассмотрим чуть позже. Сейчас же обратимся к функции удаления ловушки, реализация которой приводится в листинге 10.22.

...

Листинг 10.22.

Удаление ловушки

function RemoveHook: Boolean stdcall;

begin

if GetFileMapping then

begin

if hook_info^.hook_handle <> 0 then

//Удаляем ловушку

UnhookWindowsHookEx(hook_info^.hook_handle);

//Закрываем проекцию файла

ReleaseFileMapping;

RemoveHook := True;

end

else

RemoveHook := False;

end;

Тут все просто и не требует подробного пояснения. Теперь же рассмотрим так часто используемые функцию и процедуру, работающие с проекцией файла в память. Функция GetFileMapping, приведенная в листинге 10.23, открывает проекцию файла в память и связывает указатель hookinf о с областью памяти, отведенной для проекции файла.

...

Листинг 10.23.

Открытие проекции файла

function GetFileMapping: Boolean;

begin

//Пытаемся открыть проекцию файла

hFile := OpenFileMapping(FILE_MAP_WRITE, False, PAnsiChar(strFileMapName));

//Получаем адрес разделяемой памяти

hook_info := MapViewOfFile(hFile, FILE_MAP_WRITE, 0, 0, SizeOf(THookInfo));

GetFileMapping := hook_info <> nil;

end;

Процедура ReleaseFileMapping, симметричная по своему назначению функции GetFileMapping, реализована так, как показано в листинге 10.24.

...

Листинг 10.24.

Освобождение проекции файла

procedure ReleaseFileMapping;

begin

UnmapViewOfFile(hook_info);

hook_info := nil;

CloseHandle(hFile);

hFile := 0;

end;

Функция GetFileMapping и процедура ReleaseFileMapping используют дополнительно глобальную переменную hFile (тип THandle), объявленную в модуле HookData.

Наконец пришла очередь функции-ловушки. Ее реализация приведена в листинге 10.25.

...

Листинг 10.25.

Функция-ловушка

function WndProcHook(code: Integer; wparam: WPARAM;

lparam: LPARAM): LRESULT stdcall;

var

hook_data: ^TCWPStruct;

begin

//Получим доступ к проекции файла

if not GetFileMapping then

begin

//Не удалось получить доступ к проекции файла. Ценой потери

//сообщений не дадим возникнуть ошибкам доступа к памяти

WndProcHook := 0;

Exit;

end;

if code < 0 then

begin

WndProcHook := CallNextHookEx(hook_info^.hook_handle, code,

wParam, lParam);

//Освободим проекцию файла

ReleaseFileMapping;

Exit;

end;

//Можно обрабатывать сообщение

hook_data := Pointer(lParam);

//Обрабатываем только сообщения нужного окна

if hook_data^.hwnd = hook_info^.wnd then

begin

//Заполняем поля структуры в общей области памяти и посылаем

//сообщение окну-шпиону

hook_info^.mess := hook_data^.message;

hook_info^.wParam := hook_data^.wParam;

hook_info^.lParam := hook_data^.lParam;

PostMessage(hook_info^.spy_wnd, WM_SPY_NOTIFY, 0, 0);

end;

//Передаем сообщение для дальнейшей обработки

WndProcHook := CallNextHookEx(hook_info^.hook_handle, code,

wParam, lParam);

//Освободим проекцию файла

ReleaseFileMapping;

end;

Код функции WndProc достаточно прост, поэтому не будем подробно его описывать. Поясним лишь, для чего все-таки GetFileMapping и ReleaseFileMapping вызываются при обработке каждого перехваченного сообщения.

Дело в том, что загрузка DLL в адресное пространство другого процесса отличается от штатной загрузки библиотеки, например, при помощи функции LoadLibrary: не вызывается код инициализации. Следовательно, мы не можем, например, обнулить указатель hookinf о или установить еще какой-либо признак того, была ли открыта проекция файла. Велика вероятность того, что без отсутствия ручной инициализации указатель hookinf о не будет равен нулю. Как тогда определить, связан ли этот указатель с областью памяти, куда спроецирован файл?

Можно было бы, конечно, завести 64-битную или более переменную, которой присваивалось бы «магическое» число при первой инициализации указателя hookinf о. Но в таком случае работоспособность нашей программы носила бы вероятностный характер.

Речь не идет о том, что в приведенном примере ловушка реализована самым оптимальным образом, просто альтернатива cGetFileMapping HReleaseFileMapping при написании программы показалась наиболее простой и легко поддающейся объяснению.

Глава 11 Сетевое взаимодействие

• Краткое описание сетевых компонентов

• Простой обмен данными

• Слежение за компьютером по сети

• Многопользовательский разговорник

Организация надежного сетевого взаимодействия между приложениями или компонентами одного приложения зачастую является задачей довольно сложной даже для программиста со значительным опытом работы. Это правда, если пытаться самостоятельно использовать API сетевого взаимодействия, предоставляемый операционной системой (в нашем случае – Windows). Однако с использованием компонентов Delphi, в которых уже реализованы рутинные операции по созданию соединений, пересылке данных, контролю ошибок и т. д., программирование сетевых приложений становится не только простым, но и увлекательным занятием. В данной главе мы рассмотрим несколько примеров создания несложных сетевых приложений, построенных с использованием архитектуры «клиент – сервер».

11.1. Краткое описание сетевых компонентов

В Delphi 7 количество компонентов для программирования самых различных сетевых приложений просто радует глаз (см. вкладки IndyQients и IndyServers). Мы рассмотрим построение приложения на базе только IdTCPServer и IdTCPCLient (написание клиент-серверных приложений с использованием всех сетевых компонентов могло бы занять всю книгу).

Итак, сначала о компоненте сервера IdTCPServer. Для использования возможностей сервера этот компонент нужно поместить на форму (компонент неотображаемый). При настройке компонента полезными являются следующие его свойства:

Поделиться:
Популярные книги

Несгибаемый граф. Тетралогия

Яманов Александр
Нет пророка в своем отечестве
Фантастика:
альтернативная история
фэнтези
5.00
рейтинг книги
Несгибаемый граф. Тетралогия

Кодекс Охотника. Книга XXII

Винокуров Юрий
22. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXII

Тринадцатый

Северский Андрей
Фантастика:
фэнтези
рпг
7.12
рейтинг книги
Тринадцатый

Травник

Назимов Константин Геннадьевич
1. Травник
Фантастика:
фэнтези
5.00
рейтинг книги
Травник

Собрание сочинений в одной книге

Лондон Джек
Приключения:
морские приключения
прочие приключения
6.25
рейтинг книги
Собрание сочинений в одной книге

Первый среди равных. Книга XII

Бор Жорж
12. Первый среди Равных
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга XII

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Скай О`Малли

Смолл Бертрис
1. Сага о Скай О`Малли
Любовные романы:
исторические любовные романы
8.64
рейтинг книги
Скай О`Малли

Трое с площади Карронад

Крапивин Владислав Петрович
Детские:
детские приключения
9.10
рейтинг книги
Трое с площади Карронад

Кодекс Крови. Книга I

Борзых М.
1. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга I

Кодекс Охотника. Книга XVIII

Винокуров Юрий
18. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVIII

На границе империй. Том 5

INDIGO
5. Фортуна дама переменчивая
Фантастика:
боевая фантастика
попаданцы
7.50
рейтинг книги
На границе империй. Том 5

Древесный маг Орловского княжества 4

Павлов Игорь Васильевич
4. Орловское княжество
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Древесный маг Орловского княжества 4

Неверный

Тоцка Тала
Любовные романы:
современные любовные романы
5.50
рейтинг книги
Неверный