Поделиться через


Использование объекта обратного вызова Driver-Defined

Чтобы использовать объект обратного вызова, определенный другим драйвером, драйвер открывает объект , а затем регистрирует подпрограмму для вызова при активации обратного вызова, как показано на следующем рисунке. Драйвер, запрашивающий уведомление, должен знать имя объекта обратного вызова и понимать семантику аргументов, передаваемых в подпрограмму обратного вызова.

схема, иллюстрирующая регистрацию для уведомления о обратном вызове.

Прежде чем открыть объект, драйвер должен вызвать InitializeObjectAttributes , чтобы создать блок атрибута, указав имя объекта. Получив указатель на блок атрибута, он вызывает ExCreateCallback, передавая указатель атрибута, расположение для получения дескриптора обратного вызова и значение FALSE для параметра Create , указывая, что требуется существующий объект обратного вызова.

Затем драйвер может вызвать ExRegisterCallback с возвращенным дескриптором, чтобы зарегистрировать свою процедуру обратного вызова.

Подпрограмма обратного вызова имеет следующий прототип:

typedef VOID (*PCALLBACK_FUNCTION ) (
    IN PVOID CallbackContext,
    IN PVOID Argument1,
    IN PVOID Argument2
    );

Параметр CallbackContext — это указатель контекста, который передается в подпрограмму обратного вызова при каждом вызове. Как правило, этот параметр является указателем на блок контекстных данных, который вызывающий объект должен выделить из непагрегированного пула, если подпрограмму можно вызвать в DISPATCH_LEVEL. Два аргумента определяются компонентом, создающим обратный вызов. Как правило, аргументы предоставляют сведения об условиях, активировав обратный вызов.

Когда создатель обратного вызова активирует уведомление, система вызывает зарегистрированную подпрограмму, передав указатель на контекст и два аргумента. Значения аргументов предоставляются компонентом, создающим обратный вызов. Подпрограмма обратного вызова вызывается в том же irQL, при котором создается уведомление драйвера, которое всегда имеет значение IRQL <= DISPATCH_LEVEL.

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

Если драйвер больше не требует уведомления, он должен вызвать ExUnregisterCallback , чтобы удалить свою подпрограмму из списка зарегистрированных обратных вызовов и удалить ссылку на объект обратного вызова.