查找文件的最后一个簇

时间:2014-06-04 18:38:38

标签: c++ winapi deviceiocontrol

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

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);

所以我真的不知道接下来该做什么。如果我从LARGE_INTEGER Lcn显示RETRIEVAL_POINTERS_BUFFER,我会得到一个代表当前范围的巨大数字。我也有一个切换错误情况,出现为NO_ERROR所以我假设所有集群数据都已成功读取。我能做些哪些Lcn号码来帮助我找到文件的最后一个簇?

1 个答案:

答案 0 :(得分:2)

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以支持稀疏文件。