Эта информация доступна через Defrag API. Сторонние инструменты дефрагментации могут раскрыть его. В последних системах Windows (8.1 работает, 7 не тестировалось) вы можете использовать fsutil
для запроса:
C:\>fsutil file queryextents example.txt
VCN: 0x0 Clusters: 0x2 LCN: 0x18f85e
Существует также другая подкоманда, которая выводит всю информацию для всех потоков данных в файле:
C:\>fsutil volume filelayout example.exe
********* File 0x01390000000008dd *********
File reference number : 0x01390000000008dd
File attributes : 0x00000020: Archive
...
Stream : ::$FILE_NAME
Attributes : 0x00000000: *NONE*
Flags : 0x0000000c: Resident | No clusters allocated
Size : 80
Allocated Size : 80
Stream : ::$DATA (the main data stream)
Attributes : 0x00000000: *NONE*
Flags : 0x00000000: *NONE*
Size : 1681920
Allocated Size : 1683456
Extents : 1 Extents
: 1: VCN: 0 Clusters: 411 LCN: 8527618
В выходных данных обеих команд для каждого "экстента" (непрерывного диапазона кластеров) вы получаете "номер виртуального кластера" (смещение от начала файла), количество кластеров в экстенте и "номер логического кластера" ( смещение от начала тома).
Примечание. Крошечные файлы, которые помещаются в базовую запись MFT, сохраняются ("резидентные") в своей записи MFT и будут иметь нулевые экстенты. Для этого вам нужно использовать другие способы, чтобы копаться в самом MFT. (Кроме того, в некоторых случаях файл может быть разреженным и иметь только небольшую часть, выделенную на диске; остальная часть просто считается нулевыми байтами.)
Кластеры находятся на уровне файловой системы, поэтому вам необходимо преобразовать их в сектора уровня устройства; моя система имеет 8 секторов на кластер:
C:\>fsutil fsinfo ntfsinfo c:
...
Bytes Per Sector : 512
Bytes Per Cluster : 4096
...
C:\>set/a 0x18f85e * (4096 / 512)
13091568
C:\>set/a 0x18f85e * 4096
6702882816
Это означает, что вы можете открыть \\.\C:
с HxD или другим, и найдите начало файла в секторе 13091568 (или байт 6702882816).