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?
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.