Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методическое пособие - Файловые системы FAT

.pdf
Скачиваний:
94
Добавлен:
02.05.2014
Размер:
440.35 Кб
Скачать

write(' Конец раздела:номер головки:......................

');

Hd_end[index]:=buffer[offs+6];

 

writeln(Hd_end[index]);

 

write(' Конец раздела:сектор/цилиндр последнего сектора:..'); Sec_Cyl_end[index]:=buffer[offs+7]; writeln(Sec_Cyl_end[index]);

end;

Windows NT. В операционных системах этого направления возможен доступ к физическому диску. Это делается посредством функции CreateFile, с помощью которой можно выполнять не только создание нового файла, открывание существующего файла или каталога, изменение длины существующего файла, но и операции над каналами передачи данных, трубами (pipe), дисковыми устройствами и консолями. Прототип функции CreateFile выглядит следующим образом:

HANDLE CreateFile(

LPCTSTR IpFileNaroe, // адрес строки имени файла DWORD dwDesiredAccess, // режим доступа

DWORD dwShareMode, // режим совместного использования файла

LPSECURITY_ATTRIBUTES IpSecurityAttributes, // дескриптор защиты DWORD dwCreationDistribution, // параметры создания

DWORD dwFlagsAndAttributes, // атрибуты файла

HANDLE hTemplateFile); // идентификатор файла с атрибутами

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

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

Константа

Описание

 

Доступ запрещен, однако приложение может определять

0атрибуты файла или устройства, открываемого при помощи функции CreateFile

GENERIC_READ Разрешен доступ на чтение

GENERIC_WRITE Разрешен доступ на запись

С помощью параметра dwShareMode задаются режимы совместного использования открываемого объекту. Для этого параметра можно указать комбинацию следующих констант:

Константа

Описание

0

Совместное использование объекта запрещено

FILE_SHARE_READ

Другие приложения могут открывать объект с помощью

 

функции CreateFile для чтения

FILE_SHARE_WRITE

Аналогично предыдущему, но на запись

Через параметр IpSecurityAttributes необходимо передать указатель на дескриптор защиты или значение NULL, если этот дескриптор не используется.

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

Константа

Описание

 

CREATE_NEW

Если создаваемый файл уже существует,

функция

CreateFile возвращает код ошибки

 

 

 

CREATE_ALWAYS

Существующий файл перезаписывается,

при этом

содержимое старого файла теряется

 

 

 

 

Открывается существующий файл. Если файл с

OPEN_EXISTING

указанным именем не существует, функция CreateFile

 

возвращает код ошибки

 

OPEN_ALWAYS

Если указанный файл существует, он открывается. Если

файл не существует, он будет создан

 

 

 

 

Если файл существует, он открывается, после чего

TRUNCATE_EXISTING

длина файла устанавливается равной нулю. Содержимое

 

старого файла теряется. Если же файл не существует,

 

функция CreateFile возвращает код ошибки

 

Параметр dwFlagsAndAttributes задает атрибуты и флаги для файла. При этом можно использовать любые логические комбинации следующих атрибутов (кроме атрибута FILE_ATTRIBUTE_NORMAL, который можно использовать только отдельно):

Атрибут

Описание

 

FILE_ATTRIBUTE_ARCHIVE

Файл был архивирован (выгружен)

 

 

Файл, имеющий этот атрибут, динамически

 

сжимается при записи и восстанавливается при

FILE_ATTRIBUTE_COMPRESSED

чтении. Если этот атрибут имеет каталог, то для

 

всех расположенных в нем файлов и каталогов

 

также выполняется динамическое

сжатие

 

данных

 

FILE_ATTRIBUTE_NORMAL

Остальные перечисленные в этом

списке

атрибуты не установлены

 

 

 

FILE_ATTRIBUTE_HIDDEN

Скрытый файл

 

FILE_ATTRIBUTE_READONLY

Файл можно только читать

 

FILE_ATTRIBUTE_SYSTEM

Файл является частью операционной системы

В дополнение к перечисленным выше атрибутам через параметр dwFlagsAndAttributes можно передать любую логическую комбинацию флагов, перечисленных ниже:

Флаг

Описание

 

 

 

 

 

Отмена промежуточного кэширования данных для

FILE_FLAG_WRITE_THROUGH

уменьшения вероятности потери данных при

 

аварии

 

 

 

 

 

Отмена

промежуточной

буферизации

или

FILE_FLAG_NO_BUFFERING

кэширования. При использовании

этого

флага

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

 

 

кратными размеру сектора (обычно 512 байт)

 

 

Выполнение чтения и записи асинхронно. Во время

FILE_FLAG_OVERLAPPED

асинхронного чтения или записи приложение

 

может продолжать обработку данных

 

 

 

Указывает, что к файлу будет выполняться

FILE_FLAG_RANDOM_ACCESS

произвольный доступ. Флаг предназначен для

 

оптимизации кэширования

 

 

 

 

Указывает, что к файлу будет выполняться

FILE_FLAG_SEQUENTIAL_SCAN

последовательный доступ от

начала

файла

к его

концу. Флаг предназначен для оптимизации

 

 

кэширования

 

 

 

 

Файл будет удален сразу после того, как

FILE_FLAG_DELETE_ON_CLOSE

приложение закроет его идентификатор. Этот флаг

 

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

 

 

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

FILE_FLAG_BACKUP_SEMANTICS

выгрузки или восстановления. При этом

 

выполняется проверка прав доступа

 

 

FILE_FLAG_POSIX_SEMANTICS

Доступ к файлу будет выполняться в соответствии

со спецификацией POSIX

 

 

 

 

 

 

 

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

Вслучае успешного завершения функция CreateFile возвращает идентификатор созданного или открытого объекта. При ошибке возвращается значение INVALID_HANDLE_VALUE (а не NULL, как можно было бы предположить). Код ошибки можно определить при помощи функции GetLastError.

Втом случае, если файл уже существует и были указаны константа

CREATE_ALWAYS или OPEN_ALWAYS, функция CreateFile не возвращает кода ошибки. В то же время в этой ситуации функция GetLastError возвращает значение

ERROR_ALREADY_EXISTS.

Функция CloseHandle позволяет закрыть объект. Она имеет единственный параметр - идентификатор закрываемого объекта, полученный от функции CreateFile.

С помощью функций ReadFile и WriteFile приложение может выполнять соответственно чтение из объекта и запись в объект.

BOOL ReadFile(

HANDLE hFile, // идентификатор файла LPVOID IpBuffer, // адрес буфера для данных

DWORD nNumberOfBytesToRead, // количество байт, которое необходимо прочесть в буфер

LPDWORD IpNumberOfBytesRead, // адрес слова, в которое будет записано количество прочитанных байт

LPOVERLAPPED IpOverlapped); // адрес структуры типа OVERLAPPED BOOL WriteFile(

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

LPVOID IpBuffer, // адрес записываемого блока данных

DWORD nNuroberOfBytesToWrite, // количество байт, которые необходимо записать LPDWORD IpNumberOfBytesWrite, // адрес слова, в котором будет сохранено количество запи-

санных байт

LPOVERLAPPED IpOverlapped); // адрес структуры типа OVERLAPPED

Через параметр hFile этим функциям необходимо передать идентификатор объекта, полученный от функции CreateFile.

Параметр lpBuffer должен содержать адрес буфера, в котором будут сохранены прочитанные данные (для функции ReadFile) или из которого будет выполняться запись данных (для функции WriteFile).

Параметр nNumberOfBytesToRead используется для функции ReadFile и задает количество байт данных, которые должны быть прочитаны в буфер IpBuffer. Аналогично параметр nNumberOfBytesToWrite задает функции WriteFile размер блока данных, имеющего адрес IpBuffer, который должен быть записан в объект.

Так как в процессе чтения возможно возникновение ошибки или достижение конца файла, количество прочитанных или записанных байт может отличаться от значений, заданных соответственно параметрами nNumberOfBytesToRead и nNumberOfBytesToWrite. Функции ReadFile и WriteFile записывают количество действительно прочитанных или записанных байт в двойное слово с адресом соот-

ветственно lpNumberOfBytesRead и lpNumberOfBytesWrite.

Параметр lpOverlapped используется в функциях ReadFile и WriteFile для организации асинхронного режима чтения и записи. Если запись выполняется синхронно, в качестве этого параметра следует указать значение NULL.

Если функции ReadFile и WriteFile были выполнены успешно, они возвращают значение TRUE. При возникновении ошибки возвращается значение FALSE. В последнем случае вы можете получить код ошибки, вызвав функцию GetLastError.

Используя перечисленные функции для чтения MBR можно создать на языке Си следующую функцию:

#pragma pack(1)

typedef struct tagPartitionInfo

{

UCHAR ucActivePartFlag; // Индикатор активного раздела

UCHAR ucDH;

// Начало CHS, в формате Int13h

UCHAR ucCL;

 

UCHAR ucCH;

 

UCHAR ucType;

// тип раздела

UCHAR ucEndDH;

// конец CHS, в формате Int13h

UCHAR ucEndCL;

 

UCHAR ucEndCH;

 

DWORD dwLba;

//начало раздела

DWORD dwSize;

// размер раздела

} PART_INFO, *PPART_INFO; typedef struct tagMBR

{

UCHAR ucBootProgramAndData[0x1be]; // код загрузки PART_INFO PartInfo[4]; // Таблица разделов

USHORT usSignature; // MBR сигнатура 0xaa55 }MBR, *PMBR;

#pragma pack() void ReadMBR(void)

{

HANDLE hPhysicalDrive;

hPhysicalDrive = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); // открываем устройство,

// представляющее первый жесткий диск if(hPhysicalDrive != INVALID_HANDLE_VALUE)

{

MBR data;

DWORD dwBytesRead;

// Читаем 1-й сектор диска...

ReadFile(hPhysicalDrive, &data, 512, &dwBytesRead, NULL);

// закрываем устройство

CloseHandle(hPhysicalDrive);

}

}

Структура FAT16

Как нам уже известно, самый первый сектор логического диска занимает загрузочная запись (Boot Record). Для FAT16, кроме программы начальной загрузки операционной системы, в загрузочной записи находятся параметры, описывающие характеристики данного логического диска. Все эти параметры располагаются в самом начале сектора, в его так называемой форматированной области. Формат области показан в таблице 4.

В самом начале загрузочной записи располагается команда внутрисегментного перехода JMP. Она нужна для обхода форматированной зоны сектора и передачи управления загрузочной программе, располагающейся со смещением (+62).

Название фирмы-производителя не используется операционной системой. Поле со смещением (+38) всегда содержит символ ')'. Этот символ означает, что

используется формат расширенной загрузочной записи. До MS-DOS 4.0 использовался другой формат записи.

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

Загрузочная запись

Таблица 4

Смещение

Размер

Содержимое

(+0)

3

Команда JMP xxxx - переход типа NEAR на программу

 

 

начальной загрузки

(+3)

8

Название фирмы-производителя операционной системы и

 

 

версия, например: "IBM 4.0"

(+11)

25

BPB – блок параметров BIOS

(+36)

1

Физический номер дисковода (0 –флоппи, 80h – жесткий диск)

(+37)

1

Зарезервировано

(+38)

1

Символ ')' - признак расширенной загрузочной записи

(+39)

4

Серийный номер диска (Volume Serial Number), создается во

время форматирования диска

(+43)

11

Метка диска (Volume Label)

 

 

Зарезервировано, обычно содержит запись типа 'FAT16 ',

(+54)

8

которая идентифицирует формат таблицы размещения файлов

 

 

FAT

Метка диска формируется при форматировании и может быть изменена командой операционной системы LABEL. Одновременно метка диска помещается в корневой каталог.

Блок параметров BIOS FAT16

Таблица 5

(0)2 sect_siz Количество байтов в одном секторе диска.

(+2)

1

clustsiz

Количество секторов в одном кластере.

(+3)

2

res_sect

Количество зарезервированных секторов.

(+5)

1

fat_cnt

Количество таблиц FAT.

(+6)

2

root_siz

Максимальное количество дескрипторов файлов, содержащихся

в корневом каталоге диска.

(+8)

2

tot_sect

Общее количество секторов на носителе данных (в разделе).

(+10)

1

media

Байт-описатель среды носителя данных.

(+11)

2

fat_size

Количество секторов, занимаемых одной копией FAT.

(+13)

2

sectors

Количество секторов на дорожке.

(+15)

2

heads

Количество сторон.

(+17)

2

hidden_l

Количество скрытых секторов для раздела, который по размеру

меньше 32 мегабайтов.

(+19)

2

hidden_h

Количество скрытых секторов для раздела, превышающего по

размеру 32 мегабайта.

(+21)

4

tot_secs

Общее количество секторов на логическом диске для раздела,

превышающего по размеру 32 мегабайта.

Блок параметров BIOS. Со смещением (+11) располагается BPB - блок параметров BIOS. Этот блок содержит некоторые характеристики логического диска и

используется дисковыми драйверами. В FAT16 BPB имеет формат, изображенный в таблице 5.

Блок параметров BIOS содержит байт-описатель среды media. Этот байт может служить для идентификации носителя данных, для жесткого диска он имеет значе-

ние F8h.

FAT. Сразу после загрузочного сектора на логическом диске находятся сектора,

содержащие таблицу размещения файлов FAT (File Allocation Table). Назначение этой таблицы станет понятным, если учесть, что файловая система FAT разрабатывалась во время широкого использования либо последовательного доступа к файлам, при котором файлы хранятся друг за другом, либо распределения под файл фиксированного значения кластеров.

При последовательном доступе, прежде чем загрузить файл, требовалось осуществить его поиск (рис.4), заключающийся в последовательном чтении заголовков файлов, начиная с первого, и проверки совпадения имени искомого файла с именем, содержащемся в заголовке. А это увеличивает время доступа к файлу. Кроме того, при увеличении размера файла сохранить его можно только за файлом, хранящимся последним (если хватить места), иначе испортится следующий за вновь сохраняемым файлом файл. Этот недостаток способствует образованию больших объемов неиспользуемых участков диска.

 

 

Файл 1

 

 

Файл 2

 

 

Файл 3

 

Файл 4

 

 

Кластеры

1

 

2

3

4

5

 

6

7

 

8

9

10

11

12

13

14

15

16

17

18

Рис.4. Поиск файла при последовательном доступе

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

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

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

Все свободные кластеры в FAT помечены нулями. Если файл занимает несколько кластеров, то эти кластеры связаны в список. Для связанных в список кластеров

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

Номер

12

13

14

15

16

17

18

19

20

21

22

23

24

25

ячейки

Значение в

13

 

 

20

ffff

16

17

18

 

 

ffff

0

21

 

 

ffff

0

fff7

25

 

ffff

ячейке

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

File 1

 

 

 

File 2

File 3

 

 

 

 

 

 

 

 

 

 

 

 

 

 

File 4

 

 

Рис.5. Организация в FAT информации о распределении кластеров под файлы (но-

мера ячеек FAT соответствуют номерам кластеров)

Первый байт FAT называется Описатель среды” (Media Descriptor) или байт ID идентификации FAT. Он имеет такое же значение, как и байт-описатель среды, находящийся в загрузочной записи логического диска. Следующие 7 байтов всегда содержат значение 0ffh. Остальная часть FAT состоит из 16-битовых ячеек, каждая ячейка соответствует одному кластеру диска. Эти ячейки могут содержать значения, указанные в таблице 6.

Возможные значения ячейки FAT

Таблица 6

FAT16

Что означает

 

0000h

Свободный кластер

 

fff0h - fff6h

Зарезервированный кластер

 

fff7h

Плохой кластер

 

fff8h - ffffh

Последний кластер в списке

 

0002h - ffefh

Номер следующего кластера в списке

 

Например, из рис. 5 видно, что File 1 использует кластеры 12, 13, 20 и 21, File 2 использует один 14-ый кластер, а в кластере 23 испорчены сектора, и он помечен, как плохой.

Корневой каталог находится. Корневой каталог находится сразу за последней копией FAT. Количество секторов, занимаемых одной копией FAT, находится в блоке параметров BIOS в загрузочной записи в поле fatsize, количество копий FAT - в поле fatcnt блока BPB. Следовательно, перед корневым каталогом находится один сектор загрузочной записи и (fatcnt_*_fatsize) секторов таблицы размещения файлов FAT.

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

512.

 

 

Корневой каталог

 

Подкаталог

Подкаталог

Подкаталог

программ

 

текстов

 

картинок

 

Подкаталог

Подкаталог

 

 

книг

статей

 

 

Рис.6. Древовидная структура каталогов

 

Формат элемента каталога

Таблица 7

Смещение

Размер

 

Содержимое

(+0)

8

Имя файла или каталога, выровненное на левую границу

 

 

и дополненное пробелами.

 

(+8)

3

Расширение имени файла, выровненное на левую

 

 

границу и дополненное пробелами.

(+11)

1

Атрибуты файла.

 

(+12)

10

Зарезервировано.

 

(+22)

2

Время создания файла или время его последней

 

 

модификации.

 

 

(+24)

2

Дата создания файла или дата его последней

 

 

модификации.

 

 

(+26)

2

Номер первого кластера, распределенного файлу.

(+28)

4

Размер файла в байтах.

 

Существует два типа каталогов: корневой каталог, о котором говорилось выше, и подкаталоги. Подкаталоги размещаются в области данных, в точности так же, как обычный файл. Размер подкаталога не фиксирован. Подкаталог всегда прикреплен к каталогу-предку, который может быть либо корневым каталогом, либо также подкаталогом. Таким образом формируется древовидная структура (рис. 6).

Любой каталог содержит 32-байтовые элементы - дескрипторы, описывающие файлы и другие каталоги. Формат дескриптора приведен в таблице 7.

Байт атрибутов является принадлежностью каждого файла. Биты этого байта могут иметь значения представленные в таблице 8.

Формат поля времени показан на рис.7. Старшие пять битов содержат значение часа модификации файла, шесть битов с номерами 5-10 содержат значение минут модификации файла, и, наконец, в младших 5 битах хранится значение секунд, деленное на 2. Для того, чтобы время обновления файла уместилось в шестнадцати битах, пришлось пойти на снижение точности времени до двух секунд.

Формат даты обновления файла напоминает формат времени (рис.8).

Для того, чтобы получить значение года обновления файла, необходимо прибавить к величине, хранимой в старших семи битах, значение 1980. Поля месяца и дня каких-либо особенностей не имеют, они полностью соответствуют календарной дате.

 

Возможные значения байта атрибутов файла

Таблица 8

 

 

 

Разряд

Величина,

Что означает

7

6

5

4

3

2

1

0

шестнадц.

 

 

 

 

 

 

 

 

 

1

1h

Разрешено только чтения

 

 

 

 

 

 

1

 

2h

Скрытый

 

 

 

 

 

 

1

 

 

4h

Системный

 

 

 

 

 

1

 

 

 

8h

Метка тома

 

 

 

 

1

 

 

 

 

10h

Подкаталог

 

 

 

1

 

 

 

 

 

20h

Архив

 

 

1

 

 

 

 

 

 

40h

Не используется

 

1

 

 

 

 

 

 

 

80h

Не используется

 

Каталог-предок содержит по одному дескриптору для каждого подкаталогапотомка. Элемент подкаталога отличается от дескриптора обычного файла в двух пунктах: во-первых, в поле атрибутов установлен бит “подкаталог”, во-вторых, в поле размера стоит 0.

Разряд

15

14

 

13

12

11

 

10

9

8

7

6

 

5

4

3

2

 

1

0

Содержимое

 

Часы (0..23)

 

 

Минуты (0..59)

 

Секунды (0..29)

 

 

 

Рис.7. Формат поля времени

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Разряд

15

14

 

13

12

11

 

10

9

8

7

6

 

5

4

3

2

 

1

0

Содержимое

 

Год (0..119)

 

 

Месяц(1..1

ень(1..31

 

 

 

 

 

 

 

 

 

 

 

 

2)

 

 

 

 

 

)

 

Рис.8. Формат поля даты