Соответствующий документ Microsoft:
https://msdn.microsoft.com/en-us/library/aa363911.aspx
Но в нем описано, как переместить существующий фрагментированный файл в новые непрерывные логические блоки.
Я хочу создать новый файл без фрагментации. Сначала я получаю бесплатные логические блоки по FSCTL_GET_VOLUME_BITMAP. Как записать файл в конкретный свободный логический блок сейчас?
использование ZwCreateFile — Параметр AllocationSize. если есть файловая система, попробуйте найти первые непрерывные свободные кластеры, запущенные с RtlFindClearBits. это решение
я делаю небольшой тест
void PrintAllocSize(HANDLE hFile)
{
IO_STATUS_BLOCK iosb;
FILE_STANDARD_INFORMATION fsi;
if (0 <= ZwQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation))
{
DbgPrint("AllocationSize=%I64x, EndOfFile=%I64x\n", fsi.AllocationSize.QuadPart, fsi.EndOfFile.QuadPart);
}
STARTING_VCN_INPUT_BUFFER vcn = {};
RETRIEVAL_POINTERS_BUFFER rpb;
NTSTATUS status = ZwFsControlFile(hFile, 0, 0, 0, &iosb, FSCTL_GET_RETRIEVAL_POINTERS, &vcn, sizeof(vcn), &rpb, sizeof(rpb));
switch (status)
{
case STATUS_SUCCESS:
case STATUS_BUFFER_OVERFLOW:
DbgPrint("ExtentCount=%x\n", rpb.ExtentCount);
break;
case STATUS_END_OF_FILE:
DbgPrint("File Is Empty\n", rpb.ExtentCount);
break;
default:
DbgPrint("ZwFsControlFile return %x\n", status);
}
}
void DoTest(POBJECT_ATTRIBUTES poa)
{
HANDLE hFile;
IO_STATUS_BLOCK iosb;
LARGE_INTEGER AllocationSize = { 0x100000 };
if (0 <= ZwCreateFile(&hFile, FILE_APPEND_DATA|SYNCHRONIZE, poa, &iosb, &AllocationSize, 0, 0, FILE_SUPERSEDE, FILE_SYNCHRONOUS_IO_NONALERT, 0, 0))
{
PrintAllocSize(hFile);
ZwClose(hFile);
}
DbgPrint("===============================\n");
if (0 <= ZwOpenFile(&hFile, SYNCHRONIZE, poa, &iosb, 0, FILE_SYNCHRONOUS_IO_NONALERT))
{
PrintAllocSize(hFile);
ZwClose(hFile);
}
ZwDeleteFile(poa);
}
и вывод
AllocationSize=100000, EndOfFile=0
ExtentCount=1
===============================
AllocationSize=0, EndOfFile=0
File Is Empty
когда мы создаем файл с ненулевым AllocationSize — резервное пространство файловой системы, но размер файла по-прежнему 0 — (AllocationSize = 100000, EndOfFile = 0, ExtentCount = 1), если мы закрываем дескриптор, без записи данных — в файловой системе свободные выделенные кластеры ( AllocationSize = 0, EndOfFile = 0, файл пуст)