One article suggests: "You have to call SetFilePointer
before calling SetEndOfFile
" but the documentation for SetFilePointer
explicitly states: "The file pointer that is identified by the value of the hFile parameter is not used for overlapped read and write operations.".
Edit: I opened a file with FILE_FLAG_OVERLAPPED
, did a SetFilePointer
to 4MB and called SetEndOfFile
. I then did SetFilePointer
to zero bytes from FILE_BEGIN
and then wrote to it with OVERLAPPED
structure's Offset
and OffsetHigh
flag set to 0xFFFFFFFF
. The write happened at the end of the file i.e. starting from the 4MB mark.
"The file pointer that is identified by the value of the hFile parameter is not used for overlapped read and write operations."
yes. this is correct. but not for all I/O operations, but only for read and write ( and several others), but not for SetFilePointer ( NtSetInformationFile
with FilePositionInformation
)
at first - what is file pointer ? look at FILE_OBJECT
structure - the CurrentByteOffset - member that specifies the file offset, in bytes, associated with the file object - and so called file pointer in win32
note, that this member basically managed by I/O manager itself and not by (filesystem) driver.
we can get and set this member by call NtQueryInformationFile
and NtSetInformationFile
with FilePositionInformation
despite here noted :
The caller must have opened the file with FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT flag specified in the CreateOptions parameter.
this is not exactly true, even if file opened without this flags ( i.e. with FILE_FLAG_OVERLAPPED
) - usually this work (depend drom driver implementation). simply if file opened as synchronous - this operation handled by I/O manager itself (driver even not called). in case asynchronous file - request passed to driver. the filesystem drivers(fastfat, ntfs) handle this request by update CurrentByteOffset
too.
why this for read/write ? because look for signature of this api - it have (optional for synchronous handles) ByteOffset
parameter - and if it present - it used, otherwise it taked from CurrentByteOffset
in FILE_OBJECT
. for asynchronous handles - ByteOffset
is mandatory parameter - it always must be not 0 ( or system return error invalid parameter) - so CurrentByteOffset
in asynchronous read/write I/O never used. but this is not related to NtSetInformationFile
what is SetFilePointer
do ? it call NtSetInformationFile
with FilePositionInformation
( really it also call and NtQueryInformationFile
too).
what is SetEndOfFile
do ? it first call NtQueryInformationFile
with FilePositionInformation
- for get value of CurrentByteOffset
(which you set by SetFilePointer
) and then call NtSetInformationFile
with FileEndOfFileInformation
and FileAllocationInformation
( this call is optimization only).
so SetFilePointer
with SetEndOfFile
will be work for any files. but not efficient. i suggest never use SetFilePointer
at all. for concrete task - simply call NtSetInformationFile
(the best) or if you not like ntapi - use SetFileInformationByHandle
with FileEndOfFileInfo
+ FileAllocationInfo
FILE_END_OF_FILE_INFO eof = { * };
SetFileInformationByHandle(hFile, FileEndOfFileInfo, &eof, sizeof(eof));
SetFileInformationByHandle(hFile, FileAllocationInfo, &eof, sizeof(eof));