Контекстное пространство объекта платформы
Пространство контекста объекта — это дополнительное пространство памяти, которое драйвер может выделить и назначить объекту. Каждый драйвер на основе платформы может создавать одно или несколько контекстных пространств для каждого объекта платформы, который получает или создает драйвер.
Драйверы на основе платформы должны хранить все данные, относящиеся к конкретному объекту, либо по значению, либо по указателю, в контекстном пространстве объекта, к которому принадлежат данные.
Например, драйвер для USB-устройств может создавать контекстное пространство для объектов устройств платформы. В контекстном пространстве драйвер может хранить такие сведения, относящиеся к устройству, как USB_DEVICE_DESCRIPTOR устройства и структуры USB_CONFIGURATION_DESCRIPTOR , а также дескриптор объекта коллекции , представляющего каналы интерфейса устройства.
Платформа не передает объекты платформы из одного драйвера в другой, поэтому нельзя использовать контекстное пространство объекта для передачи данных между двумя драйверами.
Чтобы определить контекстное пространство объекта, необходимо создать одну или несколько структур. Каждая структура представляет отдельное контекстное пространство. Драйвер будет использовать каждый элемент структуры для хранения фрагмента информации, относящегося к объекту. Кроме того, драйвер должен попросить платформу создать метод доступа для каждой структуры. Этот метод доступа принимает дескриптор объекта в качестве входных данных и возвращает адрес контекстного пространства объекта.
Всякий раз, когда драйвер вызывает метод создания объекта, например WdfDeviceCreate, этот метод при необходимости выделяет пространство контекста. Все методы создания объектов принимают в качестве входных данных необязательную структуру WDF_OBJECT_ATTRIBUTES . Эта структура описывает контекстное пространство, которое платформа будет выделять для объекта .
Чтобы добавить дополнительное контекстное пространство к объекту после вызова драйвера метода создания объекта, драйвер может вызвать метод WdfObjectAllocateContext , который, как и методы создания объекта, принимает WDF_OBJECT_ATTRIBUTES структуру в качестве входных данных.
Когда платформа выделяет контекстное пространство для объекта, она также ноль инициализирует пространство контекста.
Когда платформа или драйвер удаляет объект платформы, платформа удаляет все контекстное пространство объекта.
Если драйвер использует контекстное пространство для хранения указателей на буферы, которые драйвер выделяет при создании объекта, драйвер должен предоставить функцию EvtCleanupCallback , которая освобождает буферы при удалении объекта.
Чтобы определить структуру контекстного пространства объекта и метод доступа для объектов, создаваемых драйвером, драйвер должен выполнить следующие действия:
Определите структуру, описывающую данные, которые требуется сохранить. Например, если вы хотите создать данные контекста для объектов устройства драйвера, драйвер может определить структуру с именем MY_DEVICE_CONTEXT.
Используйте макрос WDF_DECLARE_CONTEXT_TYPE или WDF_DECLARE_CONTEXT_TYPE_WITH_NAME . Оба макроса выполняют следующие действия.
- Создание и инициализация структуры WDF_OBJECT_CONTEXT_TYPE_INFO .
- Определите метод доступа, который позже будет использоваться драйвером для доступа к контексту объекта. Возвращаемое значение метода доступа является указателем на контекстное пространство объекта.
Макрос WDF_DECLARE_CONTEXT_TYPE создает имя метода доступа на основе имени вашей структуры. Например, если имя структуры контекста — MY_DEVICE_CONTEXT, макрос создает метод доступа с именем WdfObjectGet_MY_DEVICE_CONTEXT.
Макрос WDF_DECLARE_CONTEXT_TYPE_WITH_NAME позволяет указать имя метода доступа. Например, можно указать GetMyDeviceContext в качестве имени метода доступа контекста для объектов устройств.
Вызовите WDF_OBJECT_ATTRIBUTES_INIT для инициализации структуры WDF_OBJECT_ATTRIBUTES объекта.
Используйте макрос WDF_OBJECT_ATTRIBUTES_SET_CONTEXT_TYPE , чтобы задать для элемента ContextTypeInfo структуры WDF_OBJECT_ATTRIBUTES адрес структуры WDF_OBJECT_CONTEXT_TYPE_INFO.
Вызовите метод создания объекта, например WdfDeviceCreate.
После создания объекта драйвер может в любое время вызвать WdfObjectAllocateContext , чтобы добавить к объекту дополнительное контекстное пространство.
Так как шаги 1 и 2 определяют глобальные структуры данных и создают вызываемую процедуру драйвера, драйвер должен выполнить эти действия в области драйвера, которая объявляет глобальные данные( обычно это файл заголовка). Эти действия не должны выполняться в рамках процедур вашего водителя.
Драйвер должен выполнить шаги 3, 4 и 5 из подпрограммы драйвера, которая создает объект, например функцию обратного вызова EvtDriverDeviceAdd , которая вызывает WdfDeviceCreate.
Платформа может создавать два типа объектов — объекты запроса платформы и объекты файлов платформы — от имени драйвера. Драйвер может зарегистрировать контекстное пространство для этих объектов, вызвав WdfDeviceInitSetRequestAttributes и WdfDeviceInitSetFileObjectConfig соответственно. Драйвер также может вызвать WdfObjectAllocateContext , чтобы выделить контекстное пространство для этих объектов.
После создания объекта драйвер может получить указатель на контекстное пространство объекта с помощью любого из следующих методов:
Вызовите метод доступа контекста, созданный на шаге 2 предыдущей процедуры, с помощью макроса WDF_DECLARE_CONTEXT_TYPE или WDF_DECLARE_CONTEXT_TYPE_WITH_NAME .
Вызовите WdfObjectGetTypedContext, указав имя структуры контекста, определяемой драйвером.
Если у драйвера есть указатель контекстного пространства, он может найти объект, к которому принадлежит контекстное пространство, вызвав WdfObjectContextGetObject.