I was testing NtReadFile() function on my Win7 against NTFS volume and noticed that in following code (handle was opened with FILE_SYNCHRONOUS_IO_NONALERT flag):
IO_STATUS_BLOCK io;
NTSTATUS r = NtReadFile(h, NULL, NULL, NULL, &io, buf, buf_size, &pos, NULL);
io.Information (which supposed to contain number of bytes received) gets populated only if r == STATUS_SUCCESS. If r == STATUS_END_OF_FILE io.Information contains original garbage and (it seems) no data was read in that call.
So, can I assume if r == STATUS_SUCCESS and io.Information < buf_size -- we've reached end of file? Or should I keep calling NtReadFile until it returns STATUS_END_OF_FILE? (i.e. short read is possible).
On one hand Microsoft claims short reads aren't possible:
NtReadFile ... terminates the read operation under one of the following conditions:
- The buffer is full because the number of bytes specified by the Length parameter has been read. Therefore, no more data can be placed into the buffer without an overflow.
- The end of file is reached during the read operation, so there is no more data in the file to be transferred into the buffer.
... and I would like to avoid unnecessary NtReadFile call. On the other hand, my experience suggests to never trust Microsoft 100%.