logo
Профилировщик приложений

3.2 Пользовательское приложение

Пользовательское приложение включает в себя два класса: CDialog и CDriver. Как понятно из названий эти классы отвечают соответственно за взаимодействие с пользователем через диалоговое окно приложения и взаимодействие с драйвером преимущественно через IOCTL-запросы.

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

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

Далее создаётся таймер, работа которого никак не связана с работой таймера драйвера. Этот таймер отвечает за периодичный вывод полученной от драйвера информации на форму диалога.

Эта информация получается через драйвера, как уже говорилось, с помощью API-вызова DeviceIoControl:

BOOL DeviceIoControl

(HANDLE hDevice,

DWORD dwIoControlCode,

LPVOID lpInBuffer, DWORD nInBufferSize,

LPVOID lpOutBuffer, DWORD nOutBufferSize,

LPDWORD lpBytesReturned,

LPOVERLAPPED lpOverlapped);

HANDLE hDevice - описатель устройства, которому посылается запрос;

DWORD dwIoControlCode - код IOCTL-запроса;

LPVOID lpInBuffer - адрес входного буфера;

DWORD nInBufferSize - длина входного буфера;

LPVOID lpOutBuffer - адрес выходного буфера;

DWORD nOutBufferSize - длина выходного буфера;

LPDWORD lpBytesReturned - количество переданных байтов;

LPOVERLAPPED lpOverlapped - структура, необходимая при использовании асинхронного выполнения запроса, чего нет в данном приложении.

Использование этого API-вызова полностью инкапсулировано в классе CDriver, в котором для выполнения каждого запроса реализован отдельный метод с именем, близким к названию IOCTL-запроса, что обеспечивает интуитивное понимание интерфейса этого класса.

Также этот класс инкапсулирует в себя использование Менеджера управления сервисами (SCM - Service Control Manager), с помощью которого осуществляется динамическая установка, запуск, останов и удаление драйвера.