窗户在特定的逻辑集群上创建新文件

Windows. Create new file at specific logical cluster

本文关键字:新文件 创建 文件 窗户      更新时间:2023-10-16

相关的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=%I64xn", 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=%xn", rpb.ExtentCount);
        break;
    case STATUS_END_OF_FILE:
        DbgPrint("File Is Emptyn", rpb.ExtentCount);
        break;
    default:
        DbgPrint("ZwFsControlFile return %xn", 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, file Is Empty)