Проецируемые файлы.

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

(Джеффри Рихтер. Windows для профессионалов.)

Файлы, проецируемые (отображаемые) в память, - это один из самых замечательных сервисов, которые Win32 предоставляет программисту. Его существование стирает для программиста грань между оперативной и дисковой памятью. Действительно, с точки зрения классической теории кэш, оперативная память и дисковое пространство - это три вида памяти, отличающиеся скоростью доступа и размером. Но если заботу о перемещении данных между кэшем и ОП берут на себя процессор и ОС, то перемещение данных между ОП и диском обычно выполняет прикладной процесс с использованием функций read() и write().

Win32 действует иначе: ОС берет на себя заботу о перемещении страниц адресного пространства процесса, находящихся в файле подкачки, причем в качестве файла подкачки может быть использован любой файл. Иначе говоря, страницы ВП любого процесса могут быть помечены как выгруженные, а в качестве места, куда они выгружены, может быть указан файл. Теперь при обращении к такой странице VMM произведет ее загрузку, используя стандартный механизм свопинга. Это позволяет работать с произвольным файлом как с регионом памяти.

 

Применение проецируемых файлов:

- Для запуска исполняемых файлов (EXE) и динамически связываемых библиотек (DLL).

- Для работы с файлами.

- Для одновременного использования одной области данных двумя процессами.

 

Запуск процесса:

  1. Создать виртуальное адресное пространство процесса (размером 4Gb).
  2. Резервировать в ВАП регион размером, достаточным для размещения исполняемого файла. Начальный адрес региона определяется в заголовке EXE-модуля. Обычно он равен 0x00400000.
  3. Отобразить исполняемый файл на зарезервированное адресное пространство.
  4. Таким же образом отобразить на ВАП процесса необходимые ему динамически связываемые библиотеки. Информация о необходимых библиотеках находится в заголовке EXE-модуля. Желательное расположение региона адресов описано внутри библиотеки.

Запуск EXE-файлов и DLL-библиотек

 

 

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

Файлы данных, проецируемые в память

Проецирование файла данных в память:

1. Создается объект ядра “файл”. Для создания объекта “файл” используется функция CreateFile.

2. С помощью функции CreateFileMapping создается объект ядра “проецируемый файл”. При этом используется дескриптор файла, возвращенный функцией CreateFile.

3. Производится отображение объекта “проецируемый файл” или его части на адресное пространство процесса. Для этого применяется функция MapViewOfFile.

Завершение проецирования файла данных:

1. Выполняется открепление файла от адресного пространства процесса с помощью функции UnmapViewOfFile.

2. Выполняется уничтожение объектов “файл” и “проецируемый файл” с помощью функции CloseHandle.

Обеспечение когерентности:

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

Операционная система обеспечивает когерентность разделяемой области данных для всех процессов. Но для обеспечения когерентности процессы должны работать с одним объектом “проецируемый файл”, а не с одним файлом.

 

Создание объекта «проецируемый файл»:

HANDLE CreateFileMapping (

HANDLE hFile, // дескриптор файла

LPSECURITY_ATTRIBUTES lpAttributes, // атрибуты защиты объекта

DWORD flProtect, // атрибуты защиты

DWORD dwMaximumSizeHigh, // старшее слово размера

DWORD dwMaximumSizeLow, // младшее слово размера

LPCTSTR lpName // имя объекта

);

 

Открытие объекта «проецируемый файл»:

HANDLE OpenFileMapping (

DWORD dwDesiredAccess, // режим доступа

BOOL bInheritHandle, // флажок наследования

LPCTSTR lpName // имя объекта

);

 

Функция проецирования области:

LPVOID MapViewOfFile (

HANDLE hFileMappingObject, // дескриптор объекта проецируемый файл

DWORD dwDesiredAccess, // режим доступа

DWORD dwFileOffsetHigh, // старшее DWORD смещения

DWORD dwFileOffsetLow, // младшее DWORD смещения

SIZE_T dwNumberOfBytesToMap // число отображаемых байтов

);

 

 

Функция проецирования области по определенному адресу:

LPVOID MapViewOfFileEx (

HANDLE hFileMappingObject, // дескриптор отображаемого объекта

DWORD dwDesiredAccess, // режим доступа

DWORD dwFileOffsetHigh, // старшее DWORD смещения

DWORD dwFileOffsetLow, // младшее DWORD смещения

SIZE_T dwNumberOfBytesToMap, // число отображаемых байтов

LPVOID lpBaseAddress // начальный адрес

);

Параметр dwDesiredAccess:

Параметр dwDesiredAccess определяет требуемый режим доступа для страниц ВП, используемых для отображения:

FILE_MAP_WRITE– доступ к операциям чтения-записи, проецируемый файл должен быть создан с защитой PAGE_READWRITE.

FILE_MAP_READ – доступ только для чтения, проецируемый файл должен быть создан с защитой PAGE_READWRITE или PAGE_READONLY.

FILE_MAP_ALL_ACCESS – то же самое, что и FILE_MAP_WRITE.

FILE_MAP_COPY – копирование при доступе для записи, проецируемый файл должен создаваться с флажком защиты PAGE_WRITECOPY.

FILE_MAP_EXECUTE – доступ к исполнению кода из отображаемой памяти , проецируемый файл должен быть создан с доступом PAGE_EXECUTE_READWRITE или PAGE_EXECUTE_READ.

 

Функция отмены проецирования области:

BOOL UnmapViewOfFile (

LPCVOID lpBaseAddress // начальный адрес

);

 

Создание и использование проецируемых файлов:

Общий механизм таков: один процесс создает объект “проецируемый файл” с помощью функции CreateFileMapping, передавая в параметре lpName имя объекта, которое является глобальным в системе.

Другой процесс открывает уже созданный объект “проецируемый файл” по глобальному имени.

Теперь два процесса могут совместно использовать объект “проецируемый файл”. При этом, при помощи функции MapViewOfFile каждый процесс проецирует этот объект на свое ВАП и используют эту часть адресного пространства как разделяемую область данных.