Как уже обсуждалось, основная информация о файле содержится в файловой записи (File Record) размером 1 КБ таблицы MFT, а небольшие файлы целиком хранятся в файловой записи.
Файловая запись состоит из заголовка (Header) и набора атрибутов (Attribute). В заголовке содержится служебная информация о файловой записи, например, её тип и размер. Все данные, относящиеся непосредственно к файлу, хранятся в виде атрибутов. Названия атрибутов, так же как и системных файлов, начинаются с «$». Например, отдельными атрибутами являются имя файла ($FILE_NAME), информация о его свойствах ($STANDARD_INFORMATION), данные файла ($DATA). Типичная файловая запись представлена на рис. 3.
Рис. 3. Файловая запись
На диске файловая запись всегда расположена в начале сектора, первые байты файловой записи кодируют слово «FILE» (ASCII-коды: 46 49 4C 45). Конец записи определяется 4‑байтовой последовательностью FF FF FF FF.
Физически атрибут файла хранится в виде потока байтов (stream) – простой последовательности байтов. Такое представление позволяет одинаковым образом работать с разнотипными атрибутами, а также добавлять нестандартные пользовательские атрибуты.
Каждый атрибут состоит из заголовка (attribute header), определяющего тип атрибута и его свойства, и тела (attribute body), содержащего основную информацию атрибута.
Более подробная структура файловой записи представлена на рис. 4.
Рис. 4. Структура файловой записи
По расположению относительно MFT атрибуты бывают резидентные и нерезидентные. Резидентные атрибуты (resident attributes) полностью помещаются в файловую запись MFT, нерезидентные атрибуты (nonresident attributes) хранятся вне MFT. Область, в которой расположен нерезидентный атрибут, называется группой (run). Поскольку нерезидентных атрибутов в файле может быть несколько, то и групп бывает тоже несколько. Множество групп файла называется списком групп (RunList). Файловая запись при наличии нерезидентных атрибутов содержит ссылку на расположение группы на диске (см. пример на рис. 2 «Главная таблица файлов MFT»).
Некоторые поля заголовка файловой записи, а также резидентных и нерезидентных атрибутов представлены на рис. 5. На том же рисунке справа показан пример файловой записи с конкретными значениями рассматриваемых полей. Числа слева от полей записи обозначают шестнадцатеричное смещение поля от начала записи.
Рис. 5. Поля заголовка и атрибутов файловой записи
В начале файловой записи находится признак её начала – слово «FILE» (46 49 4C 45). По смещению 0x14 расположено двухбайтовое поле, в котором записано смещение первого атрибута относительно начала файловой записи. В примере в этом поле записано 38, т. е. первый атрибут расположен по смещению 38.
В следующем поле хранится тип файловой записи: значение 01 обозначает файл, 02 – каталог (directory). В примере файловая запись соответствует файлу (значение 01 по смещению 16).
Ещё одно поле в заголовке содержит размер всей записи. В примере на рис. 5 в этом поле записано 1A0, т. е. размер записи составляет 416 байт.
Каждый атрибут имеет поля, указывающие тип, длину и резидентность атрибута. Все типы атрибутов имеют свои численные значения, например, атрибуту $FILE_NAME соответствует значение 0x30, атрибуту $STANDARD_INFORMATION – 0x10, атрибуту $DATA – 0x80.
Если атрибут резидентный, в поле резидентности записывается 0x00, иначе – 0x01. В случае нерезидентного атрибута предусмотрены поля для хранения номеров кластеров, в которых располагается группа или несколько групп, выделенных для размещения файла.
В примере на рис. 5 показаны два атрибута. Первый атрибут имеет тип $STANDARD_INFORMATION (значение 10), длина атрибута 96 байт (6016 = 9610), атрибут является резидентным (00). У второго атрибута тип $DATA (80), длина – 72 байта (4816 = 7210), атрибут является нерезидентным (01).
Для обозначения кластеров используются два типа номеров: LCN и VCN. При помощи первого типа, LCN (Logical Cluster Number – логический номер кластера), нумеруются все кластеры на диске, от первого до последнего. LCN применяются, чтобы найти начальный кластер группы. Номера VCN (Virtual Cluster Number – виртуальный номер кластера) обозначают порядковый номер кластера внутри группы. Схема нумерации кластеров LCN‑VCN проиллюстрирована на рис. 6.
Рис. 6. Схема нумерации кластеров с использованием LCN‑VCN
В случае нерезидентных атрибутов в заголовке атрибута содержатся следующие поля: номер VCN первого кластера группы (обычно равен 0х00), номер VCN последнего кластера группы и список групп (RunList), описывающий расположение групп на диске.
Рассмотрим пример описания расположения групп, приведенный на рис. 5 (справа). В этом примере значения полей следующие:
· первый VCN = 0x00;
· последний VCN = 0x3F;
· список групп (RunList) = 0x21 40 55 20 00.
Расположение кластеров для данного примера приведено на рис. 7.
Рис. 7. Расположение кластеров группы для примера на рис. 5
В этом примере значение для списка групп
0x21 40 55 20 00
обозначает следующее:
· 0x21 – первый байт кодирует размер двух полей, которые за ним следуют:
o младший полубайт обозначает размер поля (в байтах), в котором хранится длина группы в кластерах; в данном случае значение 1 указывает, что на длину группы отводится один байт;
o старший полубайт обозначает размер поля (в байтах), в котором расположен номер LCN первого кластера группы; в данном случае значение 2 указывает на двухбайтовое поле;
· 0x40 – длина группы. Поскольку в первом байте размер поля длины группы определен в один байт, в качестве длины группы рассматриваем однобайтовое поле; в данном примере оно равно 0x40 (64 кластера);
· 0x2055 – LCN‑номер первого кластера. В первом байте размер поля номер первого кластера определен в два байта, поэтому в качестве LCN‑номера первого кластера рассматривается двухбайтовое поле, которое в примере равно 0x2055 (обратите внимание, байты на диске записываются в обратном порядке: сначала младшие – 55, затем старшие – 20);
· 0x00 – признак окончания описания списка групп.
Указанные обозначения проиллюстрированы на рис. 8.
Рис. 8. Список группы
Отметим, что в рассмотренном примере нерезидентный атрибут содержится всего в одной группе; в общем случае групп может быть несколько.