0

I have a win32 app opening a log file on a network share using CreateFile and WriteFile (non overlapped) to write records. What I am seeing when the network share is lost, WriteFile reports an error (59 or 53), but an empty record (zero bytes) of the correct size is written to the file. When the share comes back online, I can see the valid data previously written and the empty records for the time that the share was lost. At the same time as the share disconnect, GetFileSize and SetFilePointer can't see any errors, but instead report the changed files as new records get added.

How does WriteFile fail when a shared file is offline ?

Happens on server 2012 ,2019, mapped drive.

Opening of the file:

hFile=CreateFile(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL);
    if (hFile==INVALID_HANDLE_VALUE && GetLastError()==ERROR_FILE_NOT_FOUND)
        hFile=CreateFile(filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,CREATE_NEW,0,NULL);

Writing data:

if (!WriteFile(hFile,(LPCVOID)&data,sizeof(data),&bytes,NULL) || bytes==0)
{
    lasterror=GetLastError();

The file is kept open all the time.

New contributor
Paul Marriott is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1
  • 1
    I don't have an answer for you, just an observation - your double-call of CreateFile() introduces a TOCTOU race condition. You don't need 2 calls, just 1 call will suffice using OPEN_ALWAYS instead of OPEN_EXISTING+CREATE_NEW separately. Commented Nov 18 at 20:37

1 Answer 1

0

The empty records happen because Windows caches network writes. When the share goes offline, WriteFile fails but space is already reserved, creating zeroed records.

Fixes:

  1. Use FILE_FLAG_WRITE_THROUGH to bypass cache:
hFile = CreateFile(filename, GENERIC_READ|GENERIC_WRITE,
                   FILE_SHARE_READ|FILE_SHARE_WRITE,
                   NULL, OPEN_EXISTING,
                   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH, NULL);
  1. Flush after each write:
WriteFile(hFile, &data, sizeof(data), &bytes, NULL);
FlushFileBuffers(hFile);
  1. Handle errors and retry or queue locally.
New contributor
Muhammad Awais is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.