Управление памятью в операционной системе WINDOWS, страница 11

·  Режим защиты памяти. Различные уровни защиты перечислены в табл.1. Чаще всего при выделении памяти используется значение PAGE_READWRITE, чтобы можно было инициализировать выделенную память начальным значением. Позже уровень защиты участка памяти можно изменить при помощи функции VirtualProtect.                                                

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

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

Если участок памяти больше не нужен, необходимо вызвать VirtualFree для того, чтобы освободить его. Этой функции необходимо передать адрес участка памяти, его размер (в байтах), а также флаг, определяющий тип операции. Если флаг равен MEM_RELEASE, адрес должен быть адресом начала участка памяти, ранее выделенного функцией VirtualAlloc, а размер должен равняться нулю. В этом случае VirtualFree полностью освобождает ранее выделенную память.

Значение флага может быть МЕМ_ОЕСОММ1Т, При этом выделенная физическая память освобождается, но соответствующее адресное пространство остается в зарезервированном состоянии. Функция VirtualFree округляет начальный адрес вниз, до ближайшей границы страниц, а размер участка — вверх таким образом, чтобы получилось целое количество страниц. Если вы освобождаете память, которая была зарезервирована, но не выделена, это не считается ошибкой.

Изменение уровня защиты страниц

Если вы получили с собственное распоряжение участок памяти и заполнили его начальными данными, у вас появляется возможность изменить атрибуты безопасности этого участка (см. табл. 1). Например, вы можете перевести этот участок в режим только для чтения или полностью запретить к нему любой доступ. Смена уровня защиты участка памяти осуществляется при помощи функции VirtualProtect. Этот вызов принимает четыре параметра. Первый параметр — это адрес страницы, атрибуты безопасности которой вы намерены изменить. Далее следует указать количество байт, атрибуты которых будут изменены. Вызов VirtualProtect работает с целым количеством страниц. Таким образом, если вы хотите изменить атрибуты одного байта, на самом деле будут изменены атрибуты целой страницы, к которой принадлежит этот байт.

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

Получение информации об уровне защиты страниц

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