Here’s the code. This app writes data to a file on a network drive, sets the file to read-only, and then runs a sanity check on the file size. What would you expect the result of this program to be?
The code happens to be written in Delphi, but would apply to any Win32 language. .NET, interestingly enough, appears to contain a workaround for the problem.
That’s hint #1, by the way: the bug is not in the code itself; it’s in the Windows API. (There’s an easy workaround, but you’ll never find it by reading the Windows API docs.)
program Project1; {$APPTYPE CONSOLE} {$WARN SYMBOL_PLATFORM OFF} uses Windows, SysUtils, Classes; var FileName: string; Stream: TFileStream; I: Integer; B: Byte; DesiredSize: Integer; begin FileName := 'H:\Foo.dat'; DesiredSize := 123456; Stream := TFileStream.Create(FileName, fmCreate or fmShareDenyWrite); try for I := 0 to DesiredSize - 1 do begin B := Byte(I); Stream.Write(B, SizeOf(B)); end; Windows.SetFileAttributes(PChar(FileName), faReadOnly); finally FreeAndNil(Stream); end; WriteLn('Desired size: ', DesiredSize); Stream := TFileStream.Create(FileName, fmOpenRead); try WriteLn('Actual size: ', GetFileSize(Stream.Handle, nil)); finally FreeAndNil(Stream); end; WriteLn('Press ENTER to continue'); ReadLn; end.
Hint #2: The results depend not just on your operating system, but on which service packs you have installed.
Hint #3: The results are nondeterministic.
And here’s hint #4.
To quote my boss: “Those guys.”