Search code examples
windowswinapistorageioctlfileapi

Is there any way to read a fragmented file from the Harddisk without moving it's clusters?


I have been writing a program to read the contents of a file directly from the Harddisk. I have been mostly successful with non-fragmented files, using the FSCTL_GET_RETRIEVAL_POINTERS, I get the location of the file on the harddisk and then using SetFilePointerEx, i start reading the file directly from the harddisk. Since the file is not fragmented, I read the harddisk till the file size.

for example: if the file size is 120345 bytes, I read 120345 bytes from the hard disk.

The problem arises when the file is fragmented, now I know where each fragment of the file starts, but I don't know till where each fragment ends, I was hoping to read only the individual fragments and concatenate the resultant data to get my output. The problem becomes multi-fold if the volume is a spanned volume since I would have to deal with multiple hard disks as well.

Are there any APIs or IOCTLs that could be used in synchronous to tackle this problem?


Solution

  • So I solved the issue. Somehow my Extents array is still showing a single extent but to get all of the fragmented data I had to call FSCTL_GET_RETRIEVAL_POINTERS multiple times.

    If I call this function:

    DeviceIoControl(handle,
                    FSCTL_GET_RETRIEVAL_POINTERS,
                    &StartingVCNK,
                    sizeof(STARTING_VCN_INPUT_BUFFER),
                    prpb,
                    sizeof(RETRIEVAL_POINTERS_BUFFER),
                    &nRead,
                    NULL);
    

    it would return ERROR_MORE_DATA if the file was fragmented and there are more extents. So I had to call DeviceIoControl() until it returned ERROR_HANDLE_EOF. Also I had to update StartingVCNK to the NextVCN of the previous extent.