00000020: 00 00 00 00-00 00 00 00-06 00 06 00-00 00 47 11 ..............G.
...
000001F0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 06 00 ................
<-- конец первого сектора FILE Record
...
000003F0: 07 СС E1 0D-00 09 00 00-FF FF FF FF-82 79
<-- конец второго сектора FILE Record
Сигнатура FILE
указывает на начало файловой записи, следовательно, по смещению 04h
байт будет расположен 16-разрядный указатель на номер последовательности обновления. В данном случае он равен 002Ah
. Очень хорошо! Переходим по смещению 002Ah
и видим, что здесь лежит слово 0006h
. Перемещаемся в конец сектора и сверяем его с последними двумя байтами. Как и предполагалось, они совпадают. Повторяем ту же самую операцию со следующим сектором. Собственно говоря, количество секторов может и не равняться двум. Чтобы не гадать на кофейной гуще, необходимо извлечь 16-разрядное значение, расположенное по смещению 06h
от начала файловой записи (в данном случае оно равно 0003h
) и вычесть из него единицу. Действительно, получается два (сектора).
Теперь нам необходимо найти массив последовательности обновления, хранящий оригинальное значение последнего слова каждого из секторов. Смещение массива обновления равно значению указателя на последовательность обновления увеличенной на два, т.е. в данном случае 002Ah + 02h == 002Ch
. Извлекаем первое слово (в данном случае равное 00h 00h
) и записываем его в конец первого сектора. Извлекаем следующее слово (47h 11h
) и записываем его в конец второго сектора.
В результате восстановленный сектор будет выглядеть, как показано в листинге 6.3.
Листинг 6.3. Восстановленная файловая запись
--> Начало первого сектора файловой записи
00000000: 46 49 4C 45-2A 00 03 00-7C 77 1A 04-02 00 00 00 FILE*...|w......
00000010: 01 00 02 00-30 00 01 00-28 02 00 00-00 04 00 00 ....0...(.......
00000020: 00 00 00 00-00 00 00 00-06 00 06 00-00 00 47 11 ..............G.
...
000001F0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00 ................
<-- Конец первого сектора файловой записи
000003F0: 07 СС E1 0D-00 09 00 00-FF FF FF FF-82 79 47 11 .Іа..... ВyG.
<-- Конец второго сектора файловой записи
FILE Record
, INDEX Record
, RCRD Record
или RSTR Record
искажены последовательностями обновления и в обязательном порядке должны быть восстановлены перед их использованием, в противном случае вместо актуальных данных вы получите мусор!
Атрибуты
Структурно всякий атрибут состоит из 08h
байт от начала атрибутного заголовка, равно нулю, то атрибут считается резидентным, а если единице, то атрибут нерезидентен. Любые другие значения недопустимы.
Первые четыре байта атрибутного заголовка определяют его тип. Тип атрибута, в свою очередь, определяет формат представления тела атрибута. В частности, тело атрибута данных (тип: 80h
— $DATA
) представляет собой "сырую" последовательность байт. Тело атрибута стандартной информации (тип: 10h
— $STANDARD_INFORMATION
) описывает время его создания, права доступа и т.д. Более подробно эта тема будет рассмотрена далее в данной главе.
Следующие четыре байта заголовка содержат длину атрибута, выражаемую в байтах. Длина нерезидентного атрибута равна сумме длин его тела и заголовка, а длина резидентного атрибута равна длине его заголовка. Если к смешению атрибута добавить его длину, мы получим указатель на следующий атрибут (или маркер конца, если текущий атрибут — последний в цепочке).