структура одного элемента списка отрезков
Покажем, как с этим работать на практике. Допустим, мы имеем следующий run-list, соответствующий нормальному не фрагментированному файлу (что может быть проще!): "21 18 34 56 00". Попробуем его декодировать?
Начнем с первого байта – 21h. Младший полубайт (01h) описывает размер поля длины отрезка, старший (02h) – размер поля начального кластера. Следующие несколько байт представляют поле длины отрезка, размер которого в данном случае равен одному байту – 18h. Два других байта (34h 56h) задают номер начального кластера отрезка. Нулевой байт на конце сигнализирует о том, что это последний отрезок в файле. Итак, наш файл состоит из одного-единственного отрезка, начинающегося с кластера 5634h и заканчивающегося кластером 5634h+ 18h == 564Ch.
Рассмотрим более сложный пример фрагментированного файла со следующим списком отрезков: "31 38 73 25 34 32 14 01 E5 11 02 31 42 AA 00 03 00". Извлекаем первый байт – 31h. Один байт приходится на поле длины и три байта на поле начального кластера. Таким образом, первый отрезок (run 1) начинается с кластера 342573h и продолжается вплоть до кластера 342573h + 38 == 3425ABh. Чтобы найти смещение следующего отрезка в списке мы складываем размер обоих полей с их начальным смещением: 3 + 1 == 4. Отсчитываем четыре байта от начла run-list'а и переходим к декодированию следующего отрезка: 32h – два байта на поле длины отрезка (равное в данном случае 0114h) и три байта на поле номера начального кластера (0211E5h). Следовательно, второй отрезок (run 2) начинается с кластера 0211E5h и продолжается вплоть до кластера 0211E5h + 114h == 212F9h. Третий отрезок (run 3): 31h – один байт на поле длины и три байта на поле начального кластера, равные 42h и 0300AAh соответственно. Поэтому, третий отрезок (run 3) начинается с кластера 0300AAh и продолжается вплоть до кластера 0300AAh + 42h == 300ECh. Завершающий нуль на конце run-list'а сигнализирует о том, что это последний отрезок в файле.
Таким образом, подопытный файл состоит из трех отрезков, разбросанных по диску в следующем живописном порядке: 342573h – 3425ABh; 0211E5h – 212F9h; 0300AAh – 300ECh. Остается только прочитать его с диска!
Начиная с версии 3.0 NTFS поддерживает разряженные (sparse) атрибуты, т. е. такие, которые не записывают на диск кластеры, содержащие одни нули. При этом поле номера начального кластера отрезка может быть равным нулю, что означает, что данную отрезку не выделен никакой кластер. Поле длины содержит количество кластеров, заполненных нулями. Их не нужно считывать с диска. Вы должны самостоятельно изготовить их в памяти. Кстати говоря, далеко не все дисковые доктора знают о существовании разряженных атрибутов (если атрибут разряжен его флаг равен 8000h), и интерпретируют нулевую длину поля номера начального кластера весьма странным образом. Последствия такого "лечения" обычно оказываются очень печальны.