Функция WdfCommonBufferCreate (wdfcommonbuffer.h)

[Применяется только к KMDF]

Метод WdfCommonBufferCreate создает буфер памяти, к которому одновременно могут обращаться драйвер и устройство с прямым доступом к памяти (DMA).

Синтаксис

NTSTATUS WdfCommonBufferCreate(
  [in]           WDFDMAENABLER          DmaEnabler,
  [in]           size_t                 Length,
  [in, optional] PWDF_OBJECT_ATTRIBUTES Attributes,
  [out]          WDFCOMMONBUFFER        *CommonBuffer
);

Параметры

[in] DmaEnabler

Дескриптор объекта включения DMA, полученного драйвером при предыдущем вызове WdfDmaEnablerCreate.

[in] Length

Требуемый размер (в байтах) нового буфера. Максимальный допустимый размер буфера составляет (MAXULONG — PAGE_SIZE) байтов.

[in, optional] Attributes

Указатель на структуру WDF_OBJECT_ATTRIBUTES , указывающую атрибуты объекта для общего объекта буфера. (Элемент ParentObject структуры должен иметь значение NULL.) Этот параметр является необязательным и может быть WDF_NO_OBJECT_ATTRIBUTES.

[out] CommonBuffer

Указатель на переменную типа WDFCOMMONBUFFER, которая получает дескриптор общего объекта буфера.

Возвращаемое значение

WdfCommonBufferCreate возвращает STATUS_SUCCESS, если операция выполнена успешно. В противном случае этот метод может вернуть одно из следующих значений:

Код возврата Описание
STATUS_INVALID_PARAMETER
Драйвер предоставил недопустимый параметр.
STATUS_INSUFFICIENT_RESOURCES
Платформа не может выделить общий объект буфера или система не может выделить буфер.
 

Ошибка проверка возникает, если драйвер предоставляет недопустимый дескриптор объекта.

Комментарии

Метод WdfCommonBufferCreate выделяет память и сопоставляет ее таким образом, чтобы драйвер и устройство могли получить к ней одновременный доступ для операций DMA. После вызова WdfCommonBufferCreate драйвер должен:

  • Вызовите WdfCommonBufferGetAlignedVirtualAddress , чтобы получить виртуальный адрес буфера, который может использовать драйвер.
  • Вызовите WdfCommonBufferGetAlignedLogicalAddress , чтобы получить логический адрес буфера, который может использовать устройство.
Драйвер обычно вызывает WdfCommonBufferCreate из функции обратного вызова EvtDriverDeviceAdd .

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

Чтобы создать общий буфер с требованием выравнивания, отличным от требования к выравниванию, заданного драйвером wdfDeviceSetAlignmentRequirement, драйвер может вызвать WdfCommonBufferCreateWithConfig вместо WdfCommonBufferCreateCreate.

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

На компьютерах с процессорами x86, x64 и Itanium включена кэшированная память. На компьютерах с процессорами arm или ARM 64 операционная система не включает кэшированную память для всех устройств автоматически. Система использует метод ACPI_CCA для каждого устройства, чтобы определить, является ли устройство согласованным в кэше.

Объект enabler DMA, который указывает параметр DmaEnablerWdfCommonBufferCreate , становится родительским объектом для нового общего объекта буфера. Драйвер не может изменить этот родительский элемент, а член ParentObjectструктуры WDF_OBJECT_ATTRIBUTES должен иметь значение NULL. Платформа удаляет каждый общий объект буфера при удалении родительского объекта включения DMA. Кроме того, можно явно удалить общий объект буфера, вызвав WdfObjectDelete.

Дополнительные сведения об общих буферах см. в разделе Использование общих буферов.

Примеры

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

DevExt->CommonBufferSize = sizeof(COMMON_BUFFER_STRUCT);  // Your structure size
status = WdfCommonBufferCreate(
                               DevExt->DmaEnabler,
                               DevExt->CommonBufferSize,
                               WDF_NO_OBJECT_ATTRIBUTES,
                               &DevExt->CommonBuffer
                               );
if (status == STATUS_SUCCESS) {
    DevExt->CommonBufferBaseVA = 
        WdfCommonBufferGetAlignedVirtualAddress(DevExt->CommonBuffer);
    DevExt->CommonBufferBaseLA =
        WdfCommonBufferGetAlignedLogicalAddress(DevExt->CommonBuffer); 
}

Требования

Требование Значение
Целевая платформа Универсальное
Минимальная версия KMDF 1,0
Верхняя часть wdfcommonbuffer.h (включая WdfCommonBuffer.h)
Библиотека Wdf01000.sys (см. раздел Управление версиями библиотеки платформы).
IRQL PASSIVE_LEVEL
Правила соответствия DDI DriverCreate(kmdf), KmdfIrql(kmdf), KmdfIrql2(kmdf), KmdfIrqlExplicit(kmdf)

См. также раздел

EvtDriverDeviceAdd

WDF_OBJECT_ATTRIBUTES

WdfCommonBufferCreateWithConfig

WdfCommonBufferGetAlignedLogicalAddress

WdfCommonBufferGetAlignedVirtualAddress

WdfDeviceSetAlignmentRequirement

WdfDmaEnablerCreate