hex.pp.ua

Файловые операции с использованием Native API

Использование функций Native API для выполнения операций над файлами




Библиотека ntdll.dll содержит все необходимые функции для выполнения операций над файлами и каталогами. Во всех файловых функциях Native API требуется передавать полный путь. Существует функция, помогающая хранить значение текущего каталога, но сцеплять это значение с именем файла нужно самостоятельно.

Функции для установки и получения текущего каталога определены так:

NTSYSAPI ULONG NTAPI RtlGetCurrentDirectory_U(
    ULONG MaximumLength,
    PWSTR Buffer
);

NTSYSAPI NTSTATUS NTAPI RtlSetCurrentDirectory_U(
    IN PUNICODE_STRING name
);

Для доступа к файлам и каталогам используется NT-формат пути. Это полный путь к файлу с буквой диска и префиксом \??\. Например, путь до файла C:\boot.ini будет выглядеть как \??\C:\boot.ini. Привычный формат пути без префикса называется в терминологии Native API «DOS-путь». Для конвертации пути из формата DOS в NT существует функция:

NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(
    IN PCWSTR DosPathName,
    OUT PUNICODE_STRING NtPathName,
    OUT PCWSTR *NtFileNamePart,
    OUT CURDIR *DirectoryInfo
);

Целесообразно сохранять путь в DOS-формате. Его можно показывать без изменений пользователю, если он хочет увидеть текущий каталог. При каждой файловой операции придётся формировать полный NT-путь к файлу вызовом соответствующей функции, или прямой склейкой пути с префиксом.

Одна из операций, которая может понадобиться это вывод списка содержимого каталога. Чтобы его вывести, программа должна получить список файлов и каталогов текущей директории. Прежде всего, надо открыть каталог функцией NtCreateFile с опцией FILE_LIST_DIRECTORY и указанием флага FILE_DIRECTORY_FILE. Полученный хэндл скармливается функции NtQueryDirectoryFile, которой передается константа FileBothDirectoryInformation и указатель на буфер данных типа FILE_BOTH_DIR_INFORMATION. Структура этого типа позволяет узнать о файлах и каталогах все их важные параметры: имя, атрибуты, размер и время создания.

typedef struct _FILE_BOTH_DIR_INFORMATION
{
    ULONG NextEntryOffset;
    ULONG FileIndex;
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    LARGE_INTEGER EndOfFile;
    LARGE_INTEGER AllocationSize;
    ULONG FileAttributes;
    ULONG FileNameLength;
    ULONG EaSize;
    CCHAR ShortNameLength;
    WCHAR ShortName[12];
    WCHAR FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

При вызове функции NtQueryDirectoryFile можно использовать параметр ReturnSingleEntry = TRUE, тогда за один вызов функции в буфер будет помещена только одна структура FILE_BOTH_DIR_INFORMATION, а вызвать функцию в цикле придётся столько раз, сколько файлов в каталоге. При установке того же параметра в FALSE функция будет вызвана всего один раз, а в буфере окажется массив структур. Перемещаться по нему можно, сдвигая указатель на структуру по смещению, указанному в поле NextEntryOffset. У последнего элемента массива значение этого поля будет NULL.

Функции для стандартных файловых операций, таких как чтение из файла, запись в файл и удаление файла документированы в MSDN. Их названия NtReadFile, NtWriteFile, NtDeleteFile и их использование мало чем отличается от привычных функций WinAPI. Открывать файл можно функцией NtCreateFile. Чтобы скопировать файл, нужно просто прочитать его из одного места и записать копию в другом месте. А вот переименование файла – более комплексная операция, поэтому стоит рассмотреть её более подробно.

Переименование файла

Существует функция NtSetInformationFile, которая может производить множество различных операций над файлом. Прототип функции выглядит так:

NTSYSCALLAPI NTSTATUS NTAPI NtSetInformationFile(
    IN HANDLE FileHandle,
    IN PIO_STATUS_BLOCK IoStatusBlock,
    IN PVOID FileInformation,
    IN ULONG Length,
    IN FILE_INFORMATION_CLASS FileInformationClass
);

В параметре FileInformationClass передаётся константа FileRenameInformation, означающая операцию переименования. В сочетании с этой константой, функция получает в параметре FileInformation указатель на структуру FILE_RENAME_INFORMATION.

typedef struct _FILE_RENAME_INFORMATION
{
    BOOLEAN ReplaceIfExists;
    HANDLE  RootDirectory;
    ULONG FileNameLength;
    WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;

Структура FILE_RENAME_INFORMATION имеет переменную длину, зависящую от длины нового имени файла. Нужно выделить для структуры достаточное количество памяти. Предположим, у тебя есть буфер NewFileName с новым именем файла и его размер в переменной FileNameSize.

PFILE_RENAME_INFORMATION FileRenameInfo;

FileRenameInfo = RtlAllocateHeap(RtlGetProcessHeap(),
  HEAP_ZERO_MEMORY, sizeof(FILE_RENAME_INFORMATION) + FileNameSize);

После выделения памяти следует скопировать буфер NewFileName в поле структуры FileName и проинициализировать другие её поля. Поле ReplaceIfExists определяет, заменять ли существующий файл, если его имя совпадает с новым именем файла при переименовании. В параметре RootDirectory может содержаться хэндл другой директории, в которой должен оказаться файл после перемещения. Проще оставить это поле равным NULL, ведь для перемещения файла в другой каталог достаточно указать в поле FileName полный путь к новому расположению файла в NT-формате. Если осуществляется переименование файла, а не перемещение, в FileName должно быть только имя файла. После инициализации структуры остается только вызвать функцию для осуществления операции:

Status = NtSetInformationFile(
  FileHandle,
  &IoStatusBlock,
  FileRenameInfo,
  sizeof(FILE_RENAME_INFORMATION)+ FileNameSize,
  FileRenameInformation 
);

Размер буфера FileRenameInfo нельзя считать равным sizeof(FILE_RENAME_INFORMATION), ведь в определении структуры не учтена переменная длина поля FileName. Поэтому в четвёртом параметре Length следует передать длину структуры, к которой прибавлен размер строки FileName.

система комментирования CACKLE

Автор: амдф
Дата: 15.04.2011


Разделы сайта
Главная
Блог
Native API
NTFS и ReFS
Микроконтроллеры
Справочник NTDLL
Коды NTSTATUS
Разное

Избранное
NTFS Stream Explorer
Native Shell
Тенгвар

Остальное
nvpnhcknn (архив)
English pages
Контакты

Ленты atom
Лента Atom сайта Лента Atom блога



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