Системное программирование в среде Win32

Автор работы: Пользователь скрыл имя, 25 Марта 2014 в 14:49, лекция

Краткое описание

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

Прикрепленные файлы: 1 файл

Win32_лек_часть1.doc

— 811.00 Кб (Скачать документ)

Для получения информации о разбивке диска на сектора и кластеры может быть использована функция GetDiskFreeSpace(), которая, кстати, что следует из названия функции, помимо информации о разбивке тома, возвращает и информацию о свободном пространстве на диске.

BOOL GetDiskFreeSpace(

 

    LPCTSTR lpRootPathName,

    LPDWORD lpSectorsPerCluster,

   LPDWORD lpBytesPerSector, 

    LPDWORD lpNumberOfFreeClusters,

    LPDWORD lpTotalNumberOfClusters

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

Первый аргумент, lpRootPathName, указывает на наименование корневой директории того диска, информацию о котором мы хотим получить. Если этот параметр равен NULL, используется корневая директория текущего диска.

Второй аргумент, lpSectorsPerCluster, указывает на двойное слово, в которое система запишет количество секторов в одном кластере.

Аргумент третий, lpBytesPerSector, является указателем на двойное слово, в которое будет записано количество байтов в одном секторе.

Четвёртый аргумент, lpNumberOfFreeClusters, содержит указатель на двойное слово, предназначенное для записи в него количества свободных кластеров на диске.

И, наконец, последний аргумент, lpTotalNumberOfClusters, указывает на двойное слово, в которое система запишет общее число кластеров на диске.

Если возвращённое функцией значение равно TRUE, то это означает, что функция завершила свою работу нормально. Если же функция вернула FALSE, то это является признаком того, что при выполнении функции возникла ошибка.

 

 

5. Дополнительные методы работы с файлами и каталогами

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

5.1. Указатели файлов

Windows поддерживает для каждого открытого файла указатель файла, обозначающий позицию текущего байта в файле. Каждая следующая операция WriteFile или ReadFile начинает последовательное перемещение данных в файл или из файла с этой позиции и увеличивает указатель файла на количество переданных байтов. При открытии файла функцией CreateFile указатель обнуляется, указывая на начало файла, и продвигается вперед с каждой последующей операцией чтения или записи. Первое, что необходимо для прямого доступа к файлу, - это возможность установить указатель файла на произвольную позицию. Для этого предназначена функция  SetFilePointer.

 

DWORD SetFilePointer (HANDLE hFile,  LONG lDistanceToMove,

PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)

Возвращаемое значение: младшая часть (DWORD без знака) нового указателя файла. Старшая часть нового указателя передается значению DWORD, на которое указывает lpDistanceToMoveHigh (если это не пустой указатель). В случае ошибки функция возвращает значение  0x FFFFFFFF.

Параметры функции SetFilePointer:

hFile – дескриптор  открытого файла с доступом  для чтения или записи (или для обеих операций).

lDistanceToMove  - значение, на которое перемещается  указатель (типа LONG со знаком), или  позиция файла  (без знака), в  зависимости от значения dwMoveMethod. 

lpDistanceToMoveHigh указывает на старшую часть  значения перемещения. Если этот указатель равен NULL, функция может работать только с файлами, длина которых не превышает 232 – 2. Этот параметр используется также для возврата старшей части указателя файла. Младшая часть – это возвращаемое значение функции.

dwMoveMetod определяет  один из следующих режимов  перемещения:

    • FILE_BEGIN –позиция нового указателя отсчитывается от начала файла,  и DistanceToMove интерпретируется как число без знака.
    • FILE_CURRENT – указатель перемещается вперед или назад от текущей позиции на расстояние, определяемое DistanceToMove, которое интерпретируется как число со знаком. Положительное значение соответствует перемещению вперед.
    • FILE_END – позиция отсчитывается назад или вперед от конца файла.

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

5.2. Определение размера файла

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

 

DWORD GetFileSize (HANDLE hFile, LPDWORD lpdwFileSizeHigh)

Возвращаемое значение: младший компонент размера файла. Значение 0xFFFFFFFF указывает на возможную ошибку. Старшие 32 разряда размера файла находятся в двойном слове, на которое указывает второй параметр функции.  Функция  требует, чтобы файл имел открытый дескриптор, который передается функции в качестве первого параметра.

Установка размера и инициализация файла

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

В системе FAT файлы не инициализируются автоматически нулевыми значениями. Согласно документации Microsoft, содержимое файла нельзя предсказать, и это подтверждается экспериментально. Поэтому, если инициализация требуется для нормальной работы, приложения должны инициализировать файл последовательностью операций WriteFile. В NTFS файлы инициализируются, поскольку уровень безопасности С2, который обеспечивается в Windows  2000/NT, требует, чтобы содержимое удаленного файла нельзя было прочесть.

Функция SetEndOfFile не единственный способ расширения файла. Его также можно расширить последовательными операциями записи, но это приведет к более фрагментированному размещению файла, тогда как SetEndOfFile позволяет операционной системе выделять большие непрерывные блоки дискового пространства.

5.3. Атрибуты файлов и работа с  каталогами

В каталоге можно искать файлы и другие каталоги, удовлетворяющие указанному образцу имени, а также получать атрибуты файлов. Для этого необходим дескриптор поиска, который возвращается функцией FindFirstFile. Для получения нужных файлов служит функция FindNextFile, а для завершения поиска – FindClose.

HANDLE FindFirstFile (LPCSTSTR lpszSearchFile,

LPWIN32_FIND_DATA  lpffd)

 

Возвращаемое значение: дескриптор поиска; в случае неудачи – INVALID_HANDLE_VALUE.

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

Параметры функции:

  • lpszSearchFile указывает на каталог или полное имя, которое может содержать подстановочные знаки (?  и *);
  • lpffd указывает на структуру  WIN32_FIND_DATA, которая содержит информацию о найденном файле или каталоге.

Структура WIN32_FIND_DATA определена следующим образом:

typedef struct  _WIN32_FIND_DATA {

Dword dwFileAttributes;

FILETIME ftCreationTime;

FILETIME ftLastAccessTime;

FILETIME ftLastWriteTime;

Dword nFileSizeHigh;

Dword nFileSizeLow;

Dword dwReserved0;

Dword dwReserved1;

TCHAR  cFileName [MAX_PATH];

TCHAR  cAlternateFileName [14];

} WIN32_FIND_DATA;

 

dwFileAttributes можно  проверить на соответствие значениям, приведенным в описании CreateFile. Далее следуют три значения времени (время создания файла, время последнего доступа и последней записи). Поля размера файла содержат его текущую длину. CfileName -  это не полное имя файла, а собственно имя файла.  CAlternateFileName – версия имени файла для DOS формата 8.3 (включая точку). Это тоже сокращение имени файла, которое отображается в проводнике Windows. Оба имени – строки с завершающим нулем.

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

BOOL FindNextFile (HANDLE hFindFile,

LPWIN32_FIND_DATA  lpffd)

Эта функция возвращает значение FALSE либо при недопустимых параметрах, либо если соответствие данному образцу уже нельзя найти. В последнем случае GetLastError возвращает ERROR_NO_MORE_FILES.

Когда поиск закончен, следует закрыть дескриптор поиска. Для этого нельзя использовать функцию CloseHandle.  Для закрытия дескриптора поиска предназначена функция

BOOL FindClose (HANDLE hFindFile)

Функция GetFileInformationByHandle позволяет получить ту же информацию для определенного файла, указав его открытый дескриптор.

Другие методы получения атрибутов файлов и каталогов

Функции FindFirstFile и FindNextFile позволяют получить следующую информацию об атрибутах файла: флаги атрибутов, три штампа времени и размер файла.  Для работы с атрибутами есть несколько других функций, которые могут работать непосредственно с дескриптором открытого файла без просмотра каталога или указания имени файла. Функции GetFileSize и  SetEndOfFile уже были рассмотрены. Другие функции служат для получения остальных атрибутов. Например, для получения штампов времени открытого файла предназначена следующая функция:

BOOL GetFileTime (HANDLE hFile, LPFILETIME  lpftCreation,

LPFILETIME  lpftLastAccess,

LPFILETIME  lpftLastWrite)

Значения времени здесь и в структуре WIN32_FIND_DATA  - 64-разрядные целые числа без знака, указывающие 100-наносекундных единиц (107 единиц в секунду), прошедших с исходного времени (1 января 1601 г.), в форме всеобщего скоординированного времени (Universal Coordinataed Time – UTC). Существует несколько удобных функций работы со временем.

  • FileTimeToSystemTime выражает время файла в более привычных единицах – от лет до секунд и миллисекунд.
  • SystemTimeToFileTime производит обратное преобразование: времени, выраженного в этих единицах, во время файла.
  • CompareFileTime определяет, новее ли один файл, чем другой (-1), старше ли (+1) или их возрасты равны (0). 
  • SetFileTime изменяет штампы времени; временные параметры, которые не надо изменять, указываются в вызове функции как 0. NTFS поддерживает все три временных параметра, но FAT дает точный результат только для времени последнего доступа.
  • FileTimeToLocalFileTime и  LocalFileTimeToTime преобразуют UTC в местное время и обратно.

 

Функция GetFileType позволяет различать дисковые файлы, символьные файлы (фактически это устройство наподобие принтеров и консолей) и каналы. Файл также указывается своим дескриптором.

Функция

DWORD GetFileAttributes (LPCTSTR lpszFileName)

возвращает по указанному имени файла и каталога только атрибуты. В случае неудачи возвращает  0хFFFFFFFF.

Атрибуты можно проверить на соответствие комбинациям определенных значений. Значения атрибутов могут быть следующими:

FILE_ATTRIBUTE_DIRECTIRY

FILE_ATTRIBUTE_NORMAL

FILE_ATTRIBUTE_READONLY

FILE_ATTRIBUTE_TENPORARY

 

Функция SetFileAttribute изменяет эти атрибуты в указанном по имени файле.

 

Имена временных файлов

Следующая функция создает имена для временных файлов.

UNIT GetTempFileName (LPCTSTR lpszPath,

LPCTSTR lpszPrefix,

UNIT uUnique,

LPCTSTR plszTempFile)

 

Эта функция выдает уникальное имя файла с расширением .tmp в указанном каталоге и может создавать такой файл. Параметры функции:

lpszPath –  каталог для временного файла. Символ «.» обычно обозначает текущий каталог. Можно также указать каталог, предназначенный для временных файлов. Его имя выдает функция Win32  GetTempPath.

lpszPrefix – префикс имени временного файла; допускаются только символы ANSI.

uUnique обычно  равно нулю; в этом  случае функция  генерирует уникальное четырехразрядное  число и создает файл. Если  это значение отлично от нуля, файл не создается.

plszTempFile указывает на буфер, который содержит имя временного файла. Длина буфера в байтах должна быть не меньше MAX_PATH. Полученное в результате полное имя – конкатинация пути, префикса, четырехразрядного шестнадцатеричного числа и расширения .tmp.

 

5.4. Блокировка файлов

Важный вопрос в любой системе с несколькими процессами – координация и синхронизация доступа к совместно используемым объектам, например, файлам.

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

Функция LockFile блокирует область байтов в открытом файле для совместного  (несколько читающих процессов) или монопольного (один читающий и пишущий процесс) доступа:

BOOL LockFile(HANDLE hFile,

DWORD  dwFileOffsetLow,

DWORD  dwFileOffsetHigh,

DWORD  nNumberOfBytesToLockLow,

DWORD  nNumberOfBytesToLockHigh)

 

Параметры функции:

hFile – дескриптор открытого файла; должен иметь права доступа либо GENERIC_READ,  либо GENERIC_READ и GENERIC_WRITE.

DWORD  dwFileOffsetLow,DWORD  dwFileOffsetHigh младшие и старшие 32 разряда  смещения той части файла, которую необходимо блокировать .

DWORD  nNumberOfBytesToLockLow и DWORD  nNumberOfBytesToLockHigh младшие и  старшие 32 разряда числа, определяющего размер блокируемой области файла в байтах.

Разблокировка производится функцией:

UnlockFile (HANDLE hFile,

DWORD  dwFileOffsetLow,

DWORD  dwFileOffsetHigh,

DWORD  nNumberOfBytesToLockLow,

DWORD  nNumberOfBytesToLockHigh)

Назначение параметров этой функции аналогично параметрам функции  LockFile.

При блокировке следует учитывать следующее.

- Снятие  блокировки относится точно к  той же области, что и предшествующая блокировка. Не допускается разблокировать две заблокированные ранее области или часть заблокированной области. При попытке разблокировать область, которая не точно соответствует существующей блокировке, функция вернет значение FALSE, и системное сообщение укажет, что блокировки не существует. 

 

 

 

6. Структурная обработка исключений

Структурная обработка исключительных ситуаций (Structured Exception Handling — SEH) в Win32 представляет собой надежный механизм, позволяющий приложениям отвечать на неожиданные события, такие как исключительные ситуации при адресации, сбои при выполнении арифметических операций и системные ошибки. Кроме того, SEH делает возможным завершение программы из любой точки в блоке кода, а также автоматически выполняет указанные программистом действия и восстановление при ошибках.

Главное, почему Microsoft ввела в Windows подержку SEH, было ее стремление упростить разработку операционной системы и повысить ее надежность. Разработчику же использование SEH  позволит повысить надежность создаваемых приложений.

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

Информация о работе Системное программирование в среде Win32