Наверх Системное программирование
Предыдущий раздел Оглавление Следующий раздел

ЛАБОРАТОРНАЯ РАБОТА № 2

Архитектура Windows

Цель работы: Изучение архитектуры операционной системы Windows

Методические указания к выполнению лабораторной работы

Приложение (application) Windows – это совокупность исполняемых программ и вспомогательных файлов. Например, Microsoft Word представляет собой одно из популярных приложений Windows. Процессом называется исполняемый экземпляр приложения. Заметим, что в большинстве случаев пользователь может запускать несколько экземпляров (копий) одного и того же приложения одновременно. Каждый исполняемый экземпляр – это отдельный процесс со своей собственной областью памяти.

Процессом (process) называется исполняемый экземпляр (running in-stance) приложения и комплект ресурсов, отводящийся данному исполняемому приложению.

Поток (thread) – это внутренняя составляющая процесса, которой операционная система выделяет процессорное время для выполнения кода. Именно потоки исполняют программный код, а не процессы. Каждый процесс должен иметь как минимум один поток. Конечно, основное назначение потоков – дать процессу возможность поддерживать несколько ветвей управления, то есть выполнять больше действий одновременно. В многопроцессорной конфигурации (компьютер с несколькими процессорами) Windows NT (но не Windows 9x) может распределять потоки по процессорам, реально обеспечивая параллельную обработку. В однопроцессорной конфигурации процессор должен выделять кванты времени (time slices) каждому исполняемому в данный момент потоку.

Архитектура Windows базируется на использовании множества различных объектов. Объект ядра (kernel object) – это структура данных, доступ к членам которой, имеет только ядро Windows. Далее приведены примеры объектов ядра:

  1. Process представляет процесс;
  2. Thread определяет поток;
  3. File представляет открытый файл;
  4. File-mapping представляет отображаемый в память файл (memory-mapped file), то есть файл, содержимое которого отображено непосредственно на виртуальное адресное пространство и используется как физическая память;
  5. Pipe используется для обмена данными между процессами;
  6. Event является объектом синхронизации потоков, сигнализирующим о завершении операции;
  7. Mutex представляет собой объект синхронизации потоков, который может использоваться несколькими процессами;
  8. Semaphore используется для того, чтобы учитывать ресурсы и сигнализировать потоку о доступности ресурса на данный момент.

Кроме объектов ядра, существуют также пользовательские объекты и объекты GDI, такие как меню, окна, шрифты, кисти и курсоры мыши.

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

Хотя к объектам ядра нельзя получить непосредственный доступ из пользовательского режима, в Windows API есть функции, которые можно вызывать из данного режима для управления этими объектами. Это своего рода инкапсуляция (encapsulation), защищающая объекты от непредусмотренных или неразрешенные действий. Когда создается объект ядра посредством вызова соответствующей АРI функции (CreateProcess, GreateThread, CreateFile и GreateFileMapping), функция возвращает дескриптор вновь созданного объекта. Такой дескриптор может быть передан другой API-функции для того, чтобы она могла управлять данным объектом.

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

Описания API-функций, необходимых для выполнения данной лабораторной работы приведены в [1], с. 12-23.

Например, для создания объекта файл на базе существующего файла используется следующая функция:

 
        HANDLE CreateFile(
        LPCTSTR lpFileName,
        DWORD dwDesiredAccess,
        DWORD dwShareMode,
        LPSECURITY_ATTRIBUTES lpSecurityAttributes,
        DWORD dwCreationDistribution,
        DWORD dwFlagsAndAttributes,
        HANDLE hTemplateFile
        );
    

Рассмотрим параметры этой API- функции:

  • lpFileName – имя открываемого файла;
  • dwDesiredAccess – GENERIC_READ, чтобы разрешить чтение с устройства. GENERIC_WRITE, чтобы разрешить запись на устройство (константы можно объединить). Ноль, чтобы разрешить только получение информации об устройстве;
  • dwShareMode – 0 для запрета общего доступа, FILE_SHARE_READ и/или FILE_SHARE_WRITE для разрешения общего доступа к файлу;
  • lpSecurityAttributes – указатель на структуру, определяющую атрибуты безопасности файла (если они поддерживаются операционной системой);
  • dwCreationDistribution – одна из следующих констант:
    • CREATE_NEW: создать файл. Если файл существует, происходит ошибка;
    • CREATE_ALWAYS: создать файл. Предыдущий файл перезаписывается;
    • OPEN_EXISTING: открываемый файл должен существовать (обязательно используется для устройств)
    • OPEN_ALWAYS: создать файл, если он не существует TRUNCATE_EXISTING: существующий файл усекается до нулевой длины;
  • dwFlagsAndAttributes Long – комбинация следующих констант:
    • FILE_ATTRIBUTE_ARCHIVE: установить архивный атрибут;
    • FILE__ATTRIBUTE_COMPRESSED: помечает файл как подлежащий сжатию или задает сжатие для файлов каталога по умолчанию;
    • FILE_ATTRIBUTE_NORMAL: другие атрибуты файла не заданы;
    • FILE_ATTRJBUTE_HIDDEN: файл или каталог является скрытым;
    • FILE_ATTRIBUTE_READONLY: файл доступен только для чтения;
    • FILE_ATTRIBUTE_SYSTEM: файл является системным;
    • FILE_FLAG_WRITE_THROUGH: операционная система не откладывает операции записи в файл;
    • FILE_FLAG_OVERLAPPED: разрешить перекрывающиеся операции с файлом;
    • FILE_FLAG_NO_BUFFERING: запретить промежуточную буферизацию файла. Адреса буферов должны выравниваться по границам секторов для текущего тома; FILE_FLAG_RANDOM_ACCESS: буферизация файла оптимизируется для произвольного доступа;
    • FILE_FLAG_SEQUENTIAL_SCAN: буферизация файла оптимизируется для последовательного доступа;
    • FILE_FLAG_DELETE_ON_CL0SE: при закрытии последнего открытого дескриптора файл удаляется. Идеально подходит для временных файлов;
  • hTemplateFile – если параметр не равен нулю, он содержит дескриптор файла, с которого будут скопированы расширенные атрибуты нового файла. Возвращаемое значение – дескриптор файла в случае успеха. INVALID_HANDLE_VALUE при ошибке. Устанавливает информацию GetLastError. Даже если функция завершилась успешно, но файл существовал и был задан флаг CREATE_ALWAYS или OPEN_ALWAYS, GetLastError возвращает ERROR_ALREADY_EXISTS.

Задание для выполнения лабораторной работы

  1. Разработать программу, реализующую следующую задачу:
    1. Создать текстовый файл (можно с использованием notepad).
    2. Создасть объект File на базе созданного в предыдущем пункте файла, используя АРI-функцию CreateFile. Вывести значение дескриптора объекта File.
    3. Используя дескриптор объекта File-mapping, а также API-функцию MapViewOfFile отобразить части файла в память. Данная функция назначает область виртуальной памяти, выделяемой этому файлу. Базовый адрес выделенной области памяти является дескриптором представления этой области в виде отображения файла.
    4. Используя базовый адрес и функцию CopyMemory прочитайте информацию из отображаемого файла. Согласно варианту измените текстовый файл и запишите информацию в этот же файл:
      № варианта Задание
      1 Изменить регистр содержимого файла
      2 Изменить язык содержимого файла
      3 Представить зеркальное отображение содержимого файла
      4 Отсортировать по убыванию содержимое числового файла
      5 Отсортировать по возрастанию содержимое числового файла
      6 Найти минимальное число в файле, содержащем числа
      7 Найти максимальное число в файле, содержащем числа
      8 Упорядочить буквы по алфавиту
      9 Упорядочить буквы в обратном алфавитном порядке
      10 Посчитать количество строчных и прописных букв
      11 Посчитать количество русских и латинских букв в тексте
      12 Посчитать количество цифр в тексте, содержащем буквенно-цифровую информацию
      13 Удалить все буквы а из текста. В конец файла записать, сколько букв было удалено.
      14 Заменить все буквы на коды ASCII
      15 Заменить все строчные русские буквы на прописные
    5. Закрыть все дескрипторы.

    На экране должны фиксироваться все этапы работы созданного приложения.

Видео выполнения работы

Ход выполнения лабораторной работы

  1. В соответствии с заданием определить необходимые системные функции;
  2. Создать дескриптор на файл используя функцию CreateFile;
  3. Получить размер файла с помощью функции GetFileSize, используя полученный дескриптор;
  4. Создать файловое отображение файла, сохранить полученный на него дескриптор, используя дескриптор на файл;
  5. Отобразить объект файлового отображения в адресное пространство текущего процесса с помощью функции MapViewOfFile, которая возвращает начальный адрес отображения в памяти;
  6. Скопировать в символьный массив отображенные данные с помощью функции CopyMemory, где первым параметром является указатель на временный массив, вторым - указатель на отображение файла в памяти;
  7. В соответствии с заданием провести необходимые операции с данными, полученными из файлового отображения;
  8. Скопировать результат из временного массива обратно в отображенную память с помощью функции CopyMemory;
  9. Освободить память с помощью функции UnmapViewOfFile;
  10. Завершить работу с файловым отображением и файлом с помощью функции CloseHandle.
Предыдущий раздел Оглавление Следующий раздел