Sierra Sierra - 4 months ago 31
C Question

SetFilePointer without FILE_FLAG_NO_BUFFERING

Consider this program:

#include <stdio.h>
#include <windows.h>
int main(int argc, char** argv) {
if (argc != 2)
return 1;
HANDLE j = CreateFile("\\\\.\\F:", FILE_GENERIC_READ, FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL);
int k = SetFilePointer(j, atoi(argv[1]), NULL, FILE_BEGIN);
printf("%d\n", k);
}


I am getting these results:

> a 512
512

> a 513
-1

> a 1024
1024


So I can only move the file pointer in multiples of the volume sector size. This
is the behavior that would be expected with the FILE_FLAG_NO_BUFFERING
flag. However I am not using that flag, so why am I getting these results?

Answer

The file system (FAT32 in this case) may forbid caching/buffering, regardless of specified options. When this happens seeks, reads and writes must be in mulitples of sector size. If you wanted to read some bytes in a sector you could do:

DWORD opt;
char sector[512];
char buffer[10];
ReadFile(file, sector, sizeof sector, &opt, NULL);
memcpy(buffer, sector + 100, sizeof buffer);

Note that this example ignores the requirement that buffer addresses be sector-aligned. Depending on the disk, this requirement may not be enforced.