Search code examples
c++delphiwinapifilesystemsntfs

FSCTL_GET_RETRIEVAL_POINTERS failure on very small file on a NT File System


My questions is: how would it be possible to get the file disk offset if this file (very important) is small (less than one cluster, only a few bytes).

Currently I use this Windows API function:

DeviceIOControl(FileHandle, FSCTL_GET_RETRIEVAL_POINTERS, @InBuffer, SizeOf(InBuffer), @OutBuffer, SizeOf(OutBuffer), Num, Nil);
FirsExtent.Start := OutBuffer.Pair[0].LogicalCluster ;

It works perfectly with files bigger than a cluster but it just fails with smaller files, as it always returns a null offset.

What is the procedure to follow with small files ? where are they located on a NTFS volume ? Is there an alternative way to know a file offset ? This subtility doesn't seem to be documented anywhere.

Note: the question is tagged as Delphi but C++ samples or examples would be appreciated as well.


Solution

  • The file is probably resident, meaning that its data is small enough to fit in its MFT entry. See here for a slightly longer description:

    http://www.disk-space-guide.com/ntfs-disk-space.aspx

    So you'd basically need to find the location of the MFT entry in order to know where the data is on disk. Do you control this file? If so the easiest thing to do is make sure that it's always larger than the size of an MFT entry (not a documented value, but you could always just do 4K or something).