Итак, FAT - массив информации об использовании кластеров диска, содержит списки кластеров, распределенных файлам. Номера начальных кластеров файлов хранятся в каталогах, о которых мы будем говорить в разделе "Файлы и каталоги".
В каталоге кроме всего прочего указаны номера первых кластеров, распределенных этим файлам (соответственно 11 и 12). В своей одиннадцатой ячейке таблица FAT содержит число 17 - номер второго кластера, распределенного файлу autoexec.bat. Ячейка с номером 17 содержит число 18. Это номер третьего кластера, принадлежащего файлу autoexec.bat. Последняя ячейка, которая соответствует последнему кластеру, распределенному этому файлу, содержит специальное значение - FFFF.
Таким образом, файл autoexec.bat занимает три несмежных кластера с номерами 11, 17 и 18. Что же касается файла config.sys , то в нашем примере для него отведено два смежных кластера с номерами 12 и 13.
6.17 Два формата таблицы FAT.
Таблица FAT может иметь 12- или 16-битовый формат. При этом в таблице для хранения информации об одном кластере диска используется, соответственно, 12 и 16 бит.
12-битовый формат удобен для дискет с небольшим количеством секторов - вся таблица размещения файлов помещается в одном секторе.
Если размер диска такой, что для представления всех секторов недостаточно двенадцати разрядов, можно увеличить размер кластера, например до восьми секторов.
Однако большой размер кластера приводит к неэффективному использованию дискового пространства. Это происходит из-за того что минимальный фрагмент дисковой памяти, выделяемый файлу, имеет слишком большой размер. Даже для файла размером 1 байт выделяется целый кластер. Значит, если размер кластера составляет 8 секторов, то для хранения одного байта будет использовано 4 Кбайт дисковой памяти (размер кластера составляет 512 байт).
При использовании 16-битового формата таблицы FAT операционная система MS-DOS может работать с диском, который имеет размер более 32 Мбайт.
6.18 Определение формата таблицы FAT.
Сектор загрузочной записи диска, отформатированного в MS-DOS версий 4.0 - 6.22 в поле со смещением 36h содержит строку длиной 8 байт, идентифицирующую формат FAT. Она имеет вид "FAT12" или "FAT16".
Если разделы на жестком диске создавались программой fdisk.exe , формат FAT можно определить, анализируя содержимое поля sys главной загрузочной записи (Master Boot Record). Если это поле содержит значение 1, используется 12-битовый формат, если 4, то 16-битовый.
6.19 Идентификация кластеров.
Первый байт таблицы FAT называется "Описатель среды" (Media Descriptor). Он имеет такое же значение, как и байт-описатель среды, находящийся в загрузочном секторе логического диска.
Следующие 5 байт для 12-битового формата или 7 байт для 16-битового формат всегда содержат значение 0FFh.
Остальная часть таблицы FAT состоит из 12- или 16-битовых ячеек. Каждая ячейка соответствует одному кластеру диска. Эти ячейки могут содержать следующие значения:
FAT12 | FAT16 | Что означает |
000h | 0000h | Свободный кластер |
FF0h - FF6h | FFF0h - FFF6h | Зарезервированный кластер |
FF7h | FFF7h | Плохой кластер |
FF8h - FFFh | FFF8h - FFFFh | Последний кластер в списке |
002h - FEFh | 0002h - FFEFh | Номер следующего кластера в списке |
6.20 Чтение таблицы FAT.
Непосредственный доступ к FAT может потребоваться вам для организации сканирования каталогов при поиске файлов, для чтения каталогов как файлов, для организации защиты информации от несанкционированного копирования. Общая схема использования FAT такая:
Обычно FAT располагается сразу после загрузочного сектора (логический сектор с номером 1). Для точного определения начального сектора FAT следует прочитать в память загрузочный сектор и проанализировать содержимое блока параметров BIOS. В поле ressecs записано количество зарезервированных секторов, которые располагаются перед FAT. Поле fatsize содержит размер FAT в секторах. Кроме того, следует учитывать, что на диске может находиться несколько копий FAT. Операционная система использует только первую копию, но обновляет вторую. Другие копии FAT нужны для утилит восстановления содержимого диска, таких как scandisk.exe . Количество копий FAT находится в поле fatcnt загрузочного сектора.
Процедура извлечения номера кластера из FAT зависит от формата таблицы размещения файлов.
16-битовую таблицу FAT можно представить как массив 16-битовых чисел. Для определения номера следующего кластера вам надо просто извлечь 16-битовое значение из FAT, использовав в качестве индекса номер предыдущего кластера.
Для 12-битовой таблицы FAT процедура значительно сложнее. Необходимо выполнить следующие действия:
Используя описанные выше процедуры просмотра FAT , вы сможете для каждого файла определить цепочку занимаемых им кластеров. Для чтения файла при помощи прерывания INT 25h вам будет нужно установить соответствие между номерами кластеров и номерами секторов, в которых располагаются эти кластеры. Для того чтобы это сделать, необходимо определить расположение и размер корневого каталога. Поэтому следующий раздел книги будет посвящен каталогам и файлам. Там же будут приведены примеры программ для работы с FAT.
6.21 Файлы и каталоги.
Вы, конечно, знаете, что файловая система MS-DOS имеет древовидную структуру. В корневом каталоге располагаются 32-байтовые элементы, которые содержат информацию о файлах и других каталогах. Для чтения корневого каталога необходимо определить его расположение и размер.
6.22 Расположение и размер корневого каталога.
Корневой каталог находится сразу за последней копией FAT . Количество секторов, занимаемых одной копией FAT, находится в блоке параметров BIOS в загрузочном секторе (поле fatsize), а количество копий FAT - в поле fatcnt блока BPB . Следовательно, перед корневым каталогом находится один загрузочный сектор и fatcnt * fatsize секторов таблицы размещения файлов FAT.
Размер корневого каталога можно определить исходя из значения поля rootsize. При форматировании диска в это поле записывается максимальное количество файлов и каталогов, которые могут находиться в корневом каталоге. Для каждого элемента в каталоге отводится 32 байта, поэтому корневой каталог имеет длину 32 * rootsize байт.
Корневой каталог занимает непрерывную область фиксированного размера. Размер корневого каталога задается при форматировании и определяет максимальное количество файлов и каталогов, которые могут быть в нем описаны.
Для определения количества секторов, занимаемых корневым каталогом, можно воспользоваться следующей формулой:
RootSecs = sectsize / (32 * rootsize)
В этой формуле sectsize - размер сектора в байтах, он может быть получен из соответствующего поля загрузочного сектора.
6.22 Область файлов и подкаталогов.
Вслед за корневым каталогом на логическом диске находится область файлов и подкаталогов корневого каталога.
Область данных разбита на кластеры, причем нумерация кластеров начинается с числа 2. Кластеру с номером 2 соответствуют первые секторы области данных.
Теперь мы можем привести формулу, которая позволит нам связать номер кластера с номерами секторов, занимаемых им на логическом диске:
SectNu = DataStart + ((ClustNu - 2) * clustsize)
В этой формуле использованы следующие обозначения:
SectNu | номер первого сектора, распределенного кластеру с номером ClustNu; |
DataStart | начало области данных, вычисляется по формуле: ressecs + (fatsize * fatcnt) + (32 * rootsize/ sectsize); |
ClustNu | номер кластера, для которого необходимо определить номер первого сектора; |
clustsize | количество секторов, занимаемых кластером; находится в блоке параметров BIOS. |
6.23 Дескрипторы файлов.
Как мы уже говорили, любой каталог содержит 32-байтовые элементы - дескрипторы, описывающие файлы и другие каталоги. Приведем формат дескриптора:
Смещение | Размер | Содержимое |
0 | 8 | Имя файла или каталога, выровненное на левую границу и дополненное пробелами |
8 | 3 | Расширение имени файла, выровненное на левую границу и дополненное пробелами |
11 | 1 | Байт атрибутов файла |
12 | 10 | Зарезервировано |
22 | 2 | Время создания файла или время его последней модификации |
24 | 2 | Дата создания файла или дата его последней модификации |
26 | 2 | Номер первого кластера, распределенного файлу |
28 | 4 | Размер файла в байтах |
В любом каталоге, кроме корневого, два первых дескриптора имеют специальное назначение. Первый дескриптор содержит в поле имени строку: ". ". Этот дескриптор указывает на содержащий его каталог. То есть каталог имеет ссылку сам на себя.