Программирование драйверов Windows

       

Вызовы для выделения и освобождения областей виртуальной памяти


Для манипуляций с областями памяти (выделение и освобождение) в режиме ядра используются специальные системные вызовы, отличающиеся от API вызовов режима ядра: ExAllocatePool, ExAllocatePoolWithTag, ExFreePool. В режиме ядра возможно выделение и освобождение области физически непрерывной памяти, что выполняется при помощи вызовов MmAllocateContiguousMemory

и, соответственно, MmFreeContiguousMemory. Эти вызовы рассмотрены ниже.

Таблица 7.2. Прототип вызова ExAllocatePool



PVOID ExAllocatePool IRQL &#60 DISPATCH_LEVEL
Параметры Выполняет выделение области памяти
IN POOL_TYPE PoolType Тип виртуальной памяти, в которой следует выделять область. Наиболее употребительны значения:

PagedPool &#8212 страничная

NonPagedPool

&#8212 нестраничная, тогда данную функцию можно вызывать при любом уровне IRQL

IN ULONG NumberOfBytes Размер запрашиваемой области
Возвращаемое значение Указатель на выделенную область либо NULL (в случае, если память выделить невозможно). Выделенная область всегда выравнивается на 8 байт. В случае, если запрашиваемый размер превышает PAGE_SIZE, то выделяемая область выравнивается на размер страницы.

Таблица 7.3. Прототип вызова ExAllocatePoolWithTag

PVOID ExAllocatePoolWithTag IRQL &#60 DISPATCH_LEVEL
Параметры Выполняет выделение области памяти
IN POOL_TYPE PoolType См. описание ExAllocatePool

выше.

IN ULONG NumberOfBytes Размер запрашиваемой области
IN ULONG Tag Метка (тег) для данной области, можно задавать как 4 символа, например, 'ABCD'. Удобно для отладки.
Возвращаемое значение См. описание ExAllocatePool

выше.

Таблица 7.4. Прототип вызова ExFreePool

VOID ExFreePool IRQL &#60 DISPATCH_LEVEL
Параметры Выполняет освобождение области памяти
IN PVOID pBuffer Указатель на освобождаемую область памяти, выделенную вызовами ExAllocatePool или ExAllocatePoolWithTag. Если освобождается нестраничная память, вызов может быть сделан из кода на уровне DISPATCH_LEVEL IRQL
Возвращаемое значение void
<
Таблица 7.5. Прототип вызова MmAllocateContiguousMemory

PVOID MmAllocateContiguousMemory IRQL == PASSIVE_LEVEL
Параметры Выполняет выделение физически непрерывной области памяти
IN ULONG NumberOfBytes Размер запрашиваемой области
IN PHYSICAL_ADDRESS maxAcceptableAddress Верхний предел адресов для запрашиваемой области. Поле HighPart=0, поле LowPart принимает значения, например:

• 0x000FFFFF (до 1 МБ)

• 0x00FFFFFF (до 16 МБ)

• 0xFFFFFFFF(до 4ГБ)
Возвращаемое значение Виртуальный адрес или NULL (при неудаче).

(Для повышения вероятности успешного завершения рекомендуется выполнять вызов в DriverEntry, поскольку память при работе системы быстро становится сильно дефрагментированной)
Таблица 7.6. Прототип вызова MmFreeContiguousMemory

VOID MmFreeContiguousMemory IRQL == PASSIVE_LEVEL
Параметры Выполняет освобождение области памяти
IN PVOID pBuffer Указатель на область памяти, выделенную ранее с использованием системного вызова MmAllocateContiguousMemory
Возвращаемое значение void
Таблица 7.7. Прототип вызова MmIsAddressValid

BOOLEAN MmlsAddressValid IRQL &#60= DISPATCH_LEVEL
Параметры Выполняет проверку виртуального адреса
IN PVOID VirtualAddress Виртуальный адрес, который следует проверить
Возвращаемое значение TRUE &#8212 если присутствует в оперативной памяти

FALSE &#8212 если вызовет прерывание PAGE FAULT

Замечание. Если адрес не находится в нестраничной памяти (или не зафиксирован в оперативной памяти), возврат TRUE не гарантирует отсутствие проблем при работе на повышенных уровнях IRQL (поскольку к моменту использования данного виртуального адреса ситуация может измениться).
Таблица 7.8. Прототип вызова MmGetPhysicalAddress

PHYSICAL_ADDRESS MmGetPhysicalAddress IRQL &#8212 любой
Параметры Определяет физический адрес, соответствующий данному виртуальному
IN PVOID VirtualAddress Анализируемый виртуальный адрес
Возвращаемое значение Физический адрес. Перед данным вызовом следует воспользоваться MmlsAddressValid

Содержание раздела