如何在c ++中找到MFT记录文件数?

时间:2016-09-03 16:37:36

标签: windows winapi ntfs-mft

在linux中,fstat系统调用提供了inodefiledescriptor的编号。

是否有任何系统调用或winapi函数可以从MFT Record Number或文件路径中提供给定文件的HANDLE

如果没有任何功能或系统调用,那么我该如何访问MFT Record中文件的MFT Table

1 个答案:

答案 0 :(得分:1)

对于给定文件的获取MFT Record Number

需要使用FileInternalInformation - 此处返回FILE_INTERNAL_INFORMATION。实际上这是48位低位MftRecordIndex和16位高位SequenceNumber

struct 
{
    LONGLONG    MftRecordIndex : 48;
    LONGLONG    SequenceNumber : 16;
};

也看MFT_SEGMENT_REFERENCE - 这是相同的结构

然后获取MFT Record使用FSCTL_GET_NTFS_FILE_RECORD作为输入数据 - FileReferenceNumber - 这是FILE_INTERNAL_INFORMATION.IndexNumber但是(!)只有低48位(MftRecordIndex)所以您需要零高16位(SequenceNumber),然后使用FILE_INTERNAL_INFORMATION到位NTFS_FILE_RECORD_INPUT_BUFFER知道NTFS_FILE_RECORD_OUTPUT_BUFFER大小 - 您需要首先获得NTFS_VOLUME_DATA_BUFFER帮助{{ 3}}并使用NTFS_VOLUME_DATA_BUFFER.BytesPerFileRecordSegment

NTSTATUS Test(POBJECT_ATTRIBUTES poa)
{
    HANDLE hFile, hVolume = 0;
    IO_STATUS_BLOCK iosb;

    NTSTATUS status = NtOpenFile(&hFile, SYNCHRONIZE, poa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT);

    if (0 <= status)
    {
        union 
        {
            FILE_INTERNAL_INFORMATION fii;

            NTFS_FILE_RECORD_INPUT_BUFFER nfrib;

            struct  
            {
                LONGLONG MftRecordIndex : 48;
                LONGLONG SequenceNumber : 16;
            };
        };

        if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fii, sizeof(fii), FileInternalInformation)))
        {
            //need open '\Device\HarddiskVolume<N>' or '<X>:'
            status = OpenVolume(hFile, &hVolume);
        }

        NtClose(hFile);

        if (0 <= status)
        {
            NTFS_VOLUME_DATA_BUFFER nvdb;

            if (0 <= (status = NtFsControlFile(hVolume, 0, 0, 0, &iosb, FSCTL_GET_NTFS_VOLUME_DATA, 0, 0, &nvdb, sizeof(nvdb))))
            {
                DWORD cb = FIELD_OFFSET(NTFS_FILE_RECORD_OUTPUT_BUFFER,
                    FileRecordBuffer[nvdb.BytesPerFileRecordSegment]);

                PNTFS_FILE_RECORD_OUTPUT_BUFFER pnfrob = (PNTFS_FILE_RECORD_OUTPUT_BUFFER)alloca(cb);

                SequenceNumber = 0;

                if (0 <= (status = NtFsControlFile(hVolume, 0, 0, 0, &iosb, 
                    FSCTL_GET_NTFS_FILE_RECORD, &nfrib, sizeof nfrib, pnfrob, cb)))
                {
                    NTFS_FILE_RECORD_HEADER* pnfrh = (NTFS_FILE_RECORD_HEADER*)pnfrob->FileRecordBuffer;;
                }
            }

            NtClose(hVolume);
        }
    }

    return status;
}

NTFS_FILE_RECORD_HEADER - 这是FSCTL_GET_NTFS_VOLUME_DATA(我从FILE_RECORD_SEGMENT_HEADER获取自我结构名称)