Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Задание6.doc
Скачиваний:
2
Добавлен:
13.11.2019
Размер:
251.9 Кб
Скачать

4. Выполнение задания

4.1. Подготовка ПЭВМ к работе

  1. Произвести включение ПЭВМ.

  2. Убедиться в успешной загрузке операционной системы в память.

4.2. Изучение функций Win 32 API CreateFileMapping, MapViewOfFile, OpenFileMapping, UnmapViewOfFile, CloseHandle.

Законспектировать необходимые сведения.

4.2.1. Используя содержание п. 4.2.2—4.2.7 изучить (переписать в конспект) основные сведения по назначению и применению функции Win 32 API CreateFile, CreateFileMapping, MapViewOfFile, UnmapViewOfFile, CloseHandle.

4.2.2. Функция Win 32 API CreateFile предназначена для создания и открытия объекта ядра “файл”, соответствующего тому дисковому файлу, который требуется проецировать в память. Прототип функции:

HANDLE CreateFile(LPCSTR lpFileName,

DWORD dwDesiredAccess,

DWORD dwShareMode,

LPSECURITY_ATTRIBUTES lpSecurityAttributes,

DWORD dwCreationDisposition,

DWORD dwFlagsAndAttributes,

HANDLE hTemplateFile);

где lpFileName — буфер, предназначенный для хранения имени файла, подлежащего проецированию в память, в котором указывается полный путь (при необходимости), dwDesiredAccess — указывает способ доступа к содержимому файла, dwShareMode — указывает тип совместного доступа к данному файлу.

Для параметра dwDesiredAccess возможны следующие значения:

0 — содержимое файла нельзя считывать или записывать (это значение следует указывать когда необходимо получить лишь атрибуты файла);

GENERIC_READ — чтение файла разрешена;

GENERIC_WRITE — запись в файл разрешена;

GENERIC_ READ|GENERIC_WRITE — разрешение чтения и запись.

Параметр dwShareMode может принимать такие значения:

0 — файл не подлежит открытию другими процессами;

FILE_SHARE_READ — запрещение попытки другому процессу открыть файл с флагом GENERIC_WRITE;

FILE_SHARE_WRITE — запрещение попытки другому процессу открыть файл с флагом GENERIC_READ;

FILE_SHARE_READ|FILE_SHARE_WRITE — разрешение постороннему процессу открывать файл без всяких ограничений.

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

4.2.3. Функция Win 32 API CreateFileMapping предназначена для создания объекта ядра “проекция файла” и сообщения ОС размера файла и способа доступа к нему. Прототип функции:

HANDLE CreateFileMapping(HANDLE hFile,

LPSECURITY_ATTRIBUTES lpsa,

DWORD fdwProtect,

DWORD dwMaximumSizeHigh,

DWORD dwMaximumSizeLow,

LPSTR lpszMapName);

где hFile — описатель файла, который необходимо спро­ецировать в адресное пространство процесса, который можно получить путем вызова функции CreateFile, lpsa — указатель на структуру SECURITY_ATTRIBUTES обычно для установки защиты по умолчанию ему присваивается NULL, fdwProtect — атрибуты защиты (см. табл. 1) памяти, которая используется для отображения в нее файла, dwMaximumSizeHigh и dwMaximumSizeLow указывают 64-разрядное число, значение которого определяет размер отображаемого файла, при чем в dwMaximumSizeLow записываются первые 32 разряда этого числа, в dwMaximumSizeHigh — старшие 32 бита, lpszMapName — строка с нулевым байтом в конце, в которой указывается имя данного объекта “проекция файла”, которое исполь­зуется для доступа к объекту другого процесса.

Таблица 1

Атрибут защиты

Описание

PAGE_READONLY

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

PAGE_READWRITE

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

GENERIC_READ|GENERIC_WRITE

PAGE_WRITECOPY

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

GENERIC_READ|GENERIC_WRITE

Назначение dwMaximumSizeHigh и dwMaximumSizeLow объясняется тем, что в Win 32 имеется возможность управлять файлами, размер которых выражается 64-разрядными числами. Для файлов размером 4 Гб и менее dwMaximumSizeHigh всегда равен нулю. Наличие 64-разряд­ного значения подразумевает, что операционная система способна обрабатывать файлы длиной до 18 экзабайтов (exabyte, ЕВ). (1 экзабайт равен квинтиллиону, или 1 152 921 504 606 846 976 байтам.)

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

В параметре lpszMapName обычно передают NULL.

После применения функции CreateFileMapping система создает объект “проекция файла” и возвращает его описатель в вызвавший функцию поток. Если объект создать не удалось, возвращается нулевой описатель (NULL).

4.2.4. Функция Win 32 API MapViewOfFile предназначена для резервирования региона адрес­ного пространства под данные, находящиеся в файле, передачи их как физическую память, отображенную на регион. Прототип функции:

LPVOID MapViewOfFile(HANDLE hFileMappingObject,

DWORD dwDesiredAccess,

DWORD dwFileOffsetHigh,

DWORD dwFileOffsetLow,

DWORD dwNumberOfBytesToMap);

где hFileMappingObject — имеет значение описателя объекта “проекция файла”, который возвращается функцией CreateFileMapping, dwDesiredAccess — идентифицирует вид доступа к дан­ным, возможные значения которого перечислены в табл. 2, dwFileOffsetHigh и dwFileOffsetLow — имеют старшие и младшие разряды 64-разрядного числа с помощью которого указывается смещение в памяти, куда спроецирован файл, начиная с которого возможен доступ к данным, dwNumberOfBytesToMap — указывает размер представления, т. е. сколько байтов файла данных должно быть спроецировано на адресное пространство.

Параметры относятся к резервированию региона адресного простран­ства и к отображению на него физической памяти. При этом не обязательно проецировать на адресное пространство весь файл сразу. Можно спроецировать лишь малую его часть, которая в таком случае называется представлением (view) — отсюда произошло название функции MapViewOfFile.

Если при вызове MapViewOfFile указан флаг FILE_MAP_COPY, система передаст фи­зическую память из страничного файла.

Функция MapViewOfFile возвращает адрес региона, выделенного для проецирования файла.

4.2.5. Функция Win 32 API OpenFileMapping предназначена для (открытия объекта "проекция файла") обеспечения возможности использования объекта "проекция файла", уже созданного функцией CreateFileMapping. Иначе — эта функция предназначена для обеспечения совместного доступа к одному и тому же объекту "проекция файла", например для совместного доступа к данным. Прототип функции:

HANDLE OpenFileMapping(DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPSTR lpName);

Первый параметр функции, dwDesiredAccess, определяет права доступа (FILE_MAP, READ, FILE_MAP_WRITE, FILE_MAP_ALL_ACCESS или FILE_MAP_COPY), а второй — bInheritHandle — указывает, должны ли порождаемые процессы автоматически наследовать описатель данного объекта "проекция файла". Значение, возвращаемое функцией, — "процессозависимый" описатель объекта "проекция файла", созданного первым процессом, т. е. накануне.

Если OpenFileMapping не обнаружит объект "проекция файла" с указанным именем, она вернет NULL. Если же возвращается допустимый описатель, то для проецирования данных в адресное пространство процессу остается всего лишь вызвать MapViewOfFile. Закончив работу с открытым объектом, необходимо вызвать фун­кцию CloseHandle.

4.2.6. Функция Win 32 API UnmapViewOfFile предназначена для отключения региона памяти на который был спроецирован файл (для освобождения региона). Прототип функции:

BOOL UnmapViewOfFile(LPVOID lpBaseAddress);

Таблица 2

Атрибут защиты

Описание

FILE_MAP_WRITE

Файловые данные можно считывать и записывать. При этом необходимо передавать в функцию CreateFileMapping атрибут PAGE_READWRITE

FILE_MAP_READ

Файловые данные можно только считывать. При этом необходимо передавать в функцию CreateFileMapping любой из следующих атрибутов:

PAGE_READONLY, PAGE_READWRITE или

PAGE_WRITECOPY

FILE_MAP_ALL_ACCESS

То же, что и FIEE_MAP_READ

FIEE_MAP_COPY

Файловые данные можно считывать и записывать. Запись приводит к созданию закрытой копии страницы. При этом необходимо передавать в функцию CreateFileMapping любые из следующих атрибутов: PAGE_READONLY, PAGE_READWRITE или

PAGE_WRITECOPY

где lpBaseAddress — базовый адрес региона, который использован для проецирования файла. Этот адрес получают за счет вызова функции MapViewOfFile. Функцию UnmapViewOfFile необходимо вызывать всегда, когда процесс, использующий файл спроецированный на регион с начальным адресом lpBaseAddress, завершается.

4.2.7. Функция Win 32 API CloseHandle предназначена для закрытия объектов операционной системы. Такими объектами могут быть в том числе и объекты “файл” и “проекция файла”. Прототип функции:

BOOL CloseHandle(dwHandle);

где dwHandle — описатель того объекта, который необходимо закрыть. Объекты закрываются всегда, когда они не используются процессом (когда процесс завершается). Описатели объектов можно получить путем вызова функции открытия объекта, как например функцией:

nFile = CreateFile(...);

которая возвращает описатель nFile.

4.3. Ознакомиться с легендой программы FileRev.

Программа FileRev демонстрирует, как с помощью механизма проецирования расположить в обратном порядке содержимое текстового ANSI- или Unicode-файла. После запуска программы появляется окно, в котором выбрав имя файла (Browse) и нажав на кнопку Reverse File Contents (обратить содержимое файла) активизируется функция, которая меняет порядок символов в файле на обратный. Программа корректно работает только с текстовыми файлами. Для работы необходимо выбирать файл Reverse в папке проекта.

После щелчка кнопки Reverse File Contents программа создает копию файла с именем FILEREV.DAT. Делается это для того, чтобы не испортить исходный файл, изменив в нем порядок следования байтов на обратный. Далее программа вызывает функцию FileReverse — она меняет порядок байтов на обратный и после этого вызывает CreateFile, открывая FILEREV.DAT для чтения и записи.

Поскольку текстовые файлы не заканчиваются нулевым символом, программа FileRev дописывает нулевой байт в конец файла. Для этого сначала вызывается функция GetFileSize:

DwFileSize = GetFileSize(hFile, NULL);

Теперь, зная длину файла, можно создать объект “проекция файла”, вызвав CreateFileMapping. При этом размер объекта равен dwFileSize плюс размер “широкого” символа, чтобы учесть дополнительный нулевой символ в конце файла. Создав объект “проекция файла”, программа проецирует на свое адресное пространство представление этого объекта. Переменная lpvFile содержит значение, возвращенное функцией MapViewOfFile, и указывает на первый байт текстового файла. Следующий шаг — запись нулевого символа в конец файла и реверсия строки:

((LPSTR) lpvFile)[dwFileSize / sizeof(CHAR)] = 0;

_strrev (lpvFile) ;

Закончив обработку файла, программа прекращает отображение на адресное про­странство представления объекта “проекция файла” и закрывает описатели всех объектов ядра. Кроме того, программа должна удалить нулевой символ, добавленный в конец файла (функция _strrev не меняет позицию этого символа). Если бы программа не убрала нулевой символ, то полученный файл оказался бы на 1 символ длиннее, и тогда повторный запуск програм­мы FileRev не позволил бы вернуть этот файл в исходное состояние. Чтобы удалить конце­вой нулевой символ, надо спуститься на уровень ниже и воспользоваться функциями, пред­назначенными для работы с файлами.

4.4. Разработать программный проект для решения задачи комплексного управления системными ресурсами операционной системы с помощью механизма проецирования (отображения) файлов в память в операционной системе Windows NT на базе функций Win 32 API CreateFileMapping, MapViewOfFile, UnmapViewOfFile, CloseHandle.

4.4.1. В соответствии с алгоритмом (п. 3) разработать программный проект и отладить его.

4.4.2. Убедиться, что функции работают правильно. Для этого использовать средства отладки, с помощью которых, применяя адресное обращение к памяти (указатели), инспектировать процесс выделения памяти объекту "проекция файла". В соответствующем участке памяти (буфере) должны находиться данные введенные с клавиатуры.

4.4.3. Запустить первую копию программы (процесса, в котором происходит проецирование и передача данных в память) командой системы программирования.

4.4.4. Запустить вторую копию программы, используя "Проводник".

4.4.5. Расположить окна этих приложений в поле видимости.

4.4.6. Перейти в первую копию программы и выполнить ввод данных с клавиатуры.

4.4.7. Перейти во вторую копию программы и получить данные спроецированные в память первым процессом. (Если программа разработана как консольное приложение, то для этого желательно, что бы в текущем процессе до того, как данные первым процессом будут спроецированы в память, была пауза (задержка), которую легко организовать элементарным вводом.) Завершить работу программ.

Получить результат работы программы.

4.4.8. Запустить программу (в системе разработки), используя трассировку.

Получить адрес региона и значения данных, спроецированных в него. Записать данные в конспект.

Сделать выводы.

Рис. 1.

Рис. 2.

Рис. 3.