Окна. Создать новый файл в определенном логическом кластере

Соответствующий документ Microsoft: https://msdn.microsoft.com/en-us/library/aa363911.aspx

Но он описывает, как переместить существующий фрагментированный файл в новые непрерывные логические блоки. Я хочу создать новый файл без фрагментации. Сначала я получаю бесплатные логические блоки по FSCTL_GET_VOLUME_BITMAP. Как записать файл в конкретный свободный логический блок сейчас?

1 ответ

Используйте 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, файл пуст)

Другие вопросы по тегам