Reputation: 79
I am failing to create a file in windows using the CreateFile
API, GetLastError
returns the error code 80 which means the file exists, but actually the file was not existing.
hFile = CreateFile((LPCTSTR) FILEPATH, // name of the write
GENERIC_READ|GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
CREATE_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
printf("GET LAST ERROR VALUE IS: %d\n", GetLastError());
What am I doing wrong?
Upvotes: 2
Views: 3810
Reputation: 613451
Your error checking is wrong. The documentation says:
Return value
If the function succeeds, the return value is an open handle to the specified file, device, named pipe, or mail slot.
If the function fails, the return value is
INVALID_HANDLE_VALUE
. To get extended error information, callGetLastError
.
In other words, failure is determined by the return value. You cannot use GetLastError
to determine failure. You must check the return value and compare against INVALID_HANDLE_VALUE
. When you do so I predict that you will find that the return value is not equal to INVALID_HANDLE_VALUE
.
In fact, this API uses the last error value to convey extra information even when the function succeeds.
From the documentation of CREATE_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).
And from the documentation of CREATE_NEW
:
Creates a new file, only if it does not already exist. If the specified file exists, the function fails and the last-error code is set to ERROR_FILE_EXISTS (80).
And so on.
The golden rule, one that you must burn into your memory, is that error checking varies from function to function and that you must read the documentation from top to tail.
Note that I am rather sceptical of your (LPCTSTR)
cast. That's just asking for trouble. If the path is the wrong type, the compiler will save you from yourself, unless you use that cast. That cast just tells the compiler to shut up. But here it knows better. That cast will allow you to pass ANSI text to a wide API and vice versa. You really should remove it.
Upvotes: 7
Reputation: 19282
GetLastError
can cause trouble.
Note the docs say
"If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError."
So, first, only call GetLastError
if you get and INVALID_HANDLE_VALUE
handle back from CreateFile
.
Second, the last error code can be the , well, liertally, last error code - i.e. the most recent call may be OK, but something previously failed: again from the docs
"If the function is not documented to set the last-error code, the value returned by this function is simply the most recent last-error code to have been set; some functions set the last-error code to 0 on success and others do not."
Upvotes: 2