Is there a situation that the function CreateFile returns INVALID_HANDLE_VALUE and GetLastError() returns ERROR_ALREADY_EXISTS

1.1k Views Asked by At

I searched MSDN about

HANDLE WINAPI CreateFile(
  _In_     LPCTSTR               lpFileName,
  _In_     DWORD                 dwDesiredAccess,
  _In_     DWORD                 dwShareMode,
  _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  _In_     DWORD                 dwCreationDisposition,
  _In_     DWORD                 dwFlagsAndAttributes,
  _In_opt_ HANDLE                hTemplateFile
);

and if dwCreationDisposition == CREATE_ALWAYS or OPEN_ALWAYS, it says

Creates a new file, always. If the specified file exists and is writable, the function overwrites the file, the function succeeds, and last-error code is set to ERROR_ALREADY_EXISTS (183). If the specified file does not exist and is a valid path, a new file is created, the function succeeds, and the last-error code is set to zero. For more information, see the Remarks section of this topic.

and

Opens a file, always. If the specified file exists, the function succeeds and the last-error code is set to ERROR_ALREADY_EXISTS (183). If the specified file does not exist and is a valid path to a writable location, the function creates a file and the last-error code is set to zero.

So I'm not sure that if the function failed, would GetLastError() be ERROR_ALREADY_EXISTS ?

Please give me an example if so.

Thanks a lot.

3

There are 3 best solutions below

0
pah On

Fast answer: No.

According to what's specified:

ERROR_ALREADY_EXISTS shall be returned by GetLastError() right after a CreateFile() call only when the file exists, dwCreationDisposition is set to CREATE_ALWAYS or OPEN_ALWAYS and the CreateFile() succeeds.

If CreateFile() fails with CREATE_ALWAYS or OPEN_ALWAYS set as dwCreationDisposition, then GetLastError() shall return the appropriate last-error code indicating the reason why the file could not be opened, but that cannot be ERROR_ALREADY_EXISTS as the user specifically requested to open or create the file, regardless if it exists or not.

This shall not be confused with the return value of GetLastError() when a call to CreateFile() with dwCreationDisposition set to CREATE_NEW fails because the file exists. In this case, GetLastError() shall return ERROR_FILE_EXISTS and never ERROR_ALREADY_EXISTS.

0
Marcin K. On

Apparently you can have the call to CreateFile with OPEN_ALWAYS fail returning NULL handle and get error 183. This happens to me when I call CreateFile with OPEN_ALWAYS specifying a file in a directory that doesn't exit.

example: C:\NonExistingDirectory\Myfile.txt

I'm not sure if this is a consistent behaviour on different Windows versions. I got it on Windows 10 using Visual Studio 2015.

0
Jana Andropov On

Yes. Intermittently.

I'm getting users complaining about an intermittent issue. I've tracked it to the following call in our code.

   HANDLE hInputFile = ::CreateFile("path_to_file_i_want_to_read", 
                        GENERIC_READ,
                  0,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_READONLY,
                  NULL);

Sometimes (I still don't understand why, not all users are reporting the problem) this call will return INVALID_HANDLE_VALUE. The error code is 183 "Cannot create a file when that file already exists". Which is silly because I'm trying to open a file that was created moments before (It exists) and I want to read it.