NtFsControlFile — Получение информации о файле

Использование NtFsControlFile для получение информации о файле на NTFS




Одной из наиболее интересных операций управления файловой системой, определённой в файле заголовка winioctl.h, является функция FSCTL_GET_NTFS_FILE_RECORD, которая возвращает из главной таблицы файлов (MFT — Master File Table) запись о файле, находящемся на томе NTFS. При вызове с этим управляющим кодом функции NtFsControlFile (или функции Win32 DeviceIoControl) её параметр InputBuffer указывает на структуру NTFS_FILE_RECORD_INPUT_BUFFER, а параметр OutputBuffer — на буфер, достаточно большой, чтобы содержать структуру NTFS_FILE_RECORD_OUTPUT_BUFFER и запись о файле.

typedef struct {
  ULONGLONG FileReferenceNumber;
} NTFS_FILE_RECORD_INPUT_BUFFER, *PNTFS_FILE_RECORD_INPUT_BUFFER;

typedef struct {
  ULONGLONG FileReferenceNumber;
  ULONG FileRecordLength;
  UCHAR FileRecordBuffer[1];
} NTFS_FILE_RECORD_OUTPUT_BUFFER, *PNTFS_FILE_RECORD_OUTPUT_BUFFER;
FileReferenceNumber состоит из 48-разрядного индекса главной таблицы файлов и 16-разрядного порядкового номера элемента в таблице повторного использования, но при использовании FSCTL_GET_NTFS_FILE_RECORD порядковый номер игнорируется. Следовательно, чтобы получить запись о файле с индексом, равным тридцати, необходимо присвоить значение 30 параметру FileReferenceNumber. Если тридцатый элемент таблицы пуст, то FSCTL_GET_NTFS_FILE_RECORD возвращает ближайший не пустой элемент. Чтобы удостовериться в получении нужного элемента таблицы, следует сравнить нижний разряд 48-го бита параметра FileReferenceNumber в буфере вывода с аналогичным значением во входном буфере.

Следующие структуры данных представляют собой дисковую структуру NTFS. Описания дисковых структур данных служат также для объяснения содержимого буфера FileRecordBuffer, возвращаемого FSCTL_GET_NTFS_FILE_RECORD.

NTFS_RECORD_HEADER

typedef struct {
  ULONG Type;
  USHORT UsaOffset;
  USHORT UsaCount;
  USN Usn;
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
  • Type
    Тип записи NTFS. Значение Type рассматривается как последовательность четырёх однобайтовых символов, и обычно содержит акроним типа.
  • Заранее заданные значения:
    
    ‘FILE’
    ‘INDX’
    ‘BAAD’
    ‘HOLE’
    ‘CHKD’
    
    
  • UsaOffset
    Смещение в байтах от начала структуры до начала массива номеров обновлений (update sequence array).
  • UsaCount
    Количество значений в массиве номеров обновлений.
  • Usn
    Порядковый номер обновления записи NTFS.

FILE_RECORD_HEADER

typedef struct {
  NTFS_RECORD_HEADER Ntfs;
  USHORT SequenceNumber;
  USHORT LinkCount;
  USHORT AttributesOffset;
  USHORT Flags; // 0x0001 = Используется, 0x0002 = Каталог
  ULONG BytesInUse;
  ULONG BytesAllocated;
  ULONGLONG BaseFileRecord;
  USHORT NextAttributeNumber;
} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
  • Ntfs
    Структура NTFS_RECORD_HEADER с типом Type равным значению ‘FILE’.
  • SequenceNumber
    Число повторного использования элемента MFT.
  • LinkCount
    Количество ссылок каталогов на элемент MFT.
  • AttributeOffset
    Смещение в байтах, от начала структуры до первого атрибута элемента MFT.
  • Flags
    Битовый массив флагов, задающих свойства элемента MFT. Определены следующие значения:
    
    InUse 0x0001 // Элемент MFT используется
    Directory 0x0002 // Элемент MFT представляет собой каталог
    
    
  • BytesInUse
    Количество байт, используемых элементом MFT.
  • BytesAllocated
    Количество байт, выделенных для элемента MFT.
  • BaseFileRecord
    Если элемент MFT содержит атрибуты, которые выходят за пределы базового элемента MFT, то этот параметр содержит номер ссылки на файл базового элемента, в противном случае он содержит нуль.
  • NextAttributeNumber
    Номер, который будет присвоен следующему атрибуту, добавленному к элементу MFT.

В MFT элемент состоит из заголовка записи о файле FILE_RECORD_HEADER, сопровождаемого последовательностью атрибутов.

ATTRIBUTE

typedef struct {
  ATTRIBUTE_TYPE AttributeType;
  ULONG Length;
  BOOLEAN Nonresident;
  UCHAR NameLength;
  USHORT NameOffset;
  USHORT Flags;
  USHORT AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;
  • AttributeType
    Тип атрибута. Определены следующие значения (см. список значений и определения структур, которые они обозначают):
    typedef enum {
      AttributeStandardInformation = 0x10,
      AttributeAttributeList = 0x20,
      AttributeFileName = 0x30,
      AttributeObjectId = 0x40,
      AttributeSecurityDescriptor = 0x50,
      AttributeVolumeName = 0x60,
      AttributeVolumeInformation = 0x70,
      AttributeData = 0x80,
      AttributeIndexRoot = 0x90,
      AttributeIndexAllocation = 0xA0,
      AttributeBitmap = 0xB0,
      AttributeReparsePoint = 0xC0,
      AttributeEAInformation = 0xD0,
      AttributeEA = 0xE0,
      AttributePropertySet = 0xF0,
      AttributeLoggedUtilityStream = 0x100
    } ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
    
  • Length
    Размер в байтах резидентной части атрибута.
  • Nonresident
    Если значением параметра является True, то значение атрибута нерезидентно.
  • NameLength
    Размер в символах имени атрибута (если оно есть).
  • NameOffset
    Смещение в байтах от начала структуры до имени атрибута. Имя атрибута хранится в виде строки Unicode.
  • Flags
    Битовый массив флагов, определяющих свойства атрибута. Определены следующие значения:
    
    Compressed 0x0001 // Атрибут сжат
    Encrypted  0x4000 // Атрибут зашифрован
    Sparse     0x8000 // Атрибут разрежен
    
    
    AttributeNumber
    Числовой идентификатор для экземпляра атрибута.

RESIDENT_ATTRIBUTE

typedef struct {
  ATTRIBUTE Attribute;
  ULONG ValueLength;
  USHORT ValueOffset;
  USHORT Flags; // 0x0001 = Indexed
} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;

Структура ATTRIBUTE содержит элементы, являющиеся общими для резидентных и нерезидентных атрибутов.

  • ValueLength
    Размер в байтах значения атрибута.
  • ValueOffset
    Смещение в байтах от начала структуры до значения атрибута.
  • Flags
    Битовый массив флагов, определяющих свойства атрибута. Определены следующие значения:
    
    0x0001  Атрибут индексирован
    
    

NONRESIDENT_ATTRIBUTE

typedef struct {
  ATTRIBUTE Attribute;
  ULONGLONG LowVcn;
  ULONGLONG HighVcn;
  USHORT RunArrayOffset;
  UCHAR CompressionUnit;
  UCHAR AlignmentOrReserved[5];
  ULONGLONG AllocatedSize;
  ULONGLONG DataSize;
  ULONGLONG InitializedSize;
  ULONGLONG CompressedSize; // Только при сжатии
} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;
  • Attribute
    Структура ATTRIBUTE содержит элементы, являющиеся общими для резидентных и нерезидентных атрибутов.
  • LowVcn
    Самый нижний допустимый виртуальный номер кластера (VCN — Virtual Cluster Number) этой части значения атрибута. Если значение атрибута не фрагментировано (для описания протяженных атрибутов необходим соответствующий список), то существует только одна часть значения атрибута, а значение параметра LowVcn равно нулю.
  • HighVcn
    Самый верхний допустимый VCN этой части значения атрибута.
  • RunArrayOffset
    Смещение в байтах от начала структуры до начала массива, содержащего соответствия между виртуальными и логическими номерами кластеров (LCN — Logical Cluster Number).
  • CompressionUnit
    Модуль сжатия атрибута, выраженный как логарифм по основанию два от количества кластеров в модуле сжатия. Если элемент CompressionUnit равен нулю, то атрибут не сжат.
  • Allocated Size
    Размер в байтах дискового пространства, выделенного для содержания значения атрибута.
  • Data Size
    Размер в байтах значения атрибута. Если значение атрибута сжато или разрежено, то он может быть больше, чем указано в AllocatedSize.
  • InitializedSize
    Размер в байтах инициализированной части значения атрибута.
  • CompressedSize
    Размер в байтах значения атрибута после сжатия. Этот элемент присутствует только в том случае, если атрибут сжат.

См. также

Список типов атрибутов дисковой структуры NTFS

По теме NTFS также есть следующее:


При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.