【问题标题】:Finding the last cluster of a file查找文件的最后一个簇
【发布时间】:2014-06-04 18:38:38
【问题描述】:

我正在尝试查找目标文件的最后一个簇并从中读取二进制数据。我从 CreateFile() 开始,并在 DeviceIoControl() 中使用了控制代码 FSCTL_GET_RETRIEVAL_POINTERS 的结果。

hfile = CreateFile(result,                          
        GENERIC_READ | GENERIC_WRITE,   
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,                           
        OPEN_EXISTING,                  
        FILE_ATTRIBUTE_NORMAL,          
        NULL);

RETRIEVAL_POINTERS_BUFFER retrievalBuffer;  
const DWORD Clusters = 1000;
const DWORD rpBufferSize = sizeof(RETRIEVAL_POINTERS_BUFFER) + (2 * (Clusters - 1) *sizeof(LARGE_INTEGER));
BYTE output[rpBufferSize];
STARTING_VCN_INPUT_BUFFER startVcn;
startVcn.StartingVcn.QuadPart = 0;

returns = DeviceIoControl(hfile,
            FSCTL_GET_RETRIEVAL_POINTERS,
            &startVcn,
            sizeof(startVcn),
            &output,
            sizeof(output),
            &bytesReturned,
            NULL);

所以我真的不知道下一步该做什么。如果我从RETRIEVAL_POINTERS_BUFFER 显示LARGE_INTEGER Lcn,我会得到一个代表当前范围的巨大数字。我也有一个开关错误情况,它显示为NO_ERROR,所以我假设所有集群数据都已成功读取。 Lcn号怎么办才能帮我找到文件的最后一个簇?

【问题讨论】:

    标签: c++ winapi deviceiocontrol


    【解决方案1】:

    retrievalBuffer 应该是一个指针:

    RETRIEVAL_POINTERS_BUFFER *retrievalBuffer = (RETRIEVAL_POINTERS_BUFFER *) output;
    

    所以最后一个范围开始于

    DWORD lastExtentN = retrievalBuffer->ExtentCount - 1;
    LARGE_INTEGER extentLcn = retrievalBuffer->Extents[ lastExtentN ].Lcn;
    

    范围大小为

    LARGE_INTEGER extentClusters = retrievalBuffer->Extents[ lastExtentN ].NextVcn
        - lastExtentN ? retrievalBuffer->Extents[ lastExtentN - 1 ].NextVcn
                      : retrievalBuffer->StartingVcn;
    

    因此,文件的最后一个逻辑簇号(LCN)是:

    LARGE_INTEGER lastLcn = extentLcn + extentClusters - 1;
    

    现在您可以使用CreateFile() 打开逻辑卷并使用ReadFile() 读取此集群

    注意:您需要检查 extentLcn-1 以支持稀疏文件。

    【讨论】:

    • 我尝试了你的方法,并且出于某种原因在 LARGE_INTEGER lastExtentN = retrieveBuffer->ExtentCount - 1;它说 ExtentCount 应该是无符号长的?同样在范围大小中,您是指使用 NextVcn 而不是 Vcn?
    • 现在似乎还有另一个错误,因为您在尝试找出范围大小时尝试从大 INTERGER 中减去 DWORD。我有点迷失在逻辑中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-24
    • 1970-01-01
    • 2023-03-12
    • 2022-01-21
    相关资源
    最近更新 更多