3

I am calling ReadFile() WinAPI to copy the file contents to a char array, inside my VC++ code. Have placed GetLastError() immediately after ReadFile().

for( read some n no: of files)
{
FileRead(fp,destCharArray,ByesToRead,NoOfBytesRead,NULL);
int ret = GetLastError();
}

GetLastError() is returning 183 only when 1st file is read. For all other file reads its returning 183. But eventhough 183 is returned the contents of file are copied to charArray. And the problem is that the file read does not happen for some 28th file (here too return status is 183). Irrespective of successful or unsuccessful file read, 183 is returned!

According to http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

error code 183 means "ERROR_ALREADY_EXISTS".

What does the above error status signify in ReadFile() context.?

Can anyone kindly help me in figuring out why?

Gilles 'SO- stop being evil'
  • 92,660
  • 35
  • 189
  • 229
codeLover
  • 3,557
  • 10
  • 56
  • 105
  • Are you doing anything in the thread before this - `createfile` for example - that could set the error? The return from `getlasterror` is only valid in this context if `readfile` returns 0, which you aren't checking for – Alex K. Feb 03 '12 at 12:36

2 Answers2

8

Your code is incorrectly calling GetLastError. You should only call GetLastError if the immediately prior Win32 API call failed, and that API returns status information through GetLastError.

Here the API in question is ReadFile. The documentation says:

Return value

If the function succeeds, the return value is nonzero (TRUE).

If the function fails, or is completing asynchronously, the return value is zero (FALSE). To get extended error information, call the GetLastError function.

In other words you must only call it if ReadFile returns FALSE.

Your code should look something like this:

if (!ReadFile(fp,destCharArray,ByesToRead,NoOfBytesRead,NULL))
{
    DWORD err = GetLastError();
    // handle error probably by raising exception
}

Your code is returning the error code for an earlier failure that is unrelated to the call to ReadFile.

Community
  • 1
  • 1
David Heffernan
  • 572,264
  • 40
  • 974
  • 1,389
  • Thanks David. But I observe that the return value of ReadFile is 1 even if no bytes are read into destCharArray!! i.e NoOfBytesRead == 0 and still ReadFile is returning 1. Didnt understand why is this so?? – codeLover Feb 03 '12 at 13:30
  • I can't say without seeing your real code. The code in the question is not the real code. The API is called ReadFile rather than FileRead. And the 4th parameter is a pointer. You appear to be passing by value. I can't comment on specifics until I can see the actual code. – David Heffernan Feb 03 '12 at 13:36
  • 2
    When you get to the end of the file ReadFile() succeeds and sets the number of bytes read to 0. – Luke Feb 03 '12 at 14:46
0

The last error might result from calling CreateFile prior. This function sets the last error value to ERROR_ALREADY_EXISTS if you specify CREATE_ALWAYS or CREATE_NEW for dwCreationDisposition.

It is important to know that the last error can be set by any function. You should always check the return value of the function which indicates if the function failed.

Norbert Willhelm
  • 2,397
  • 1
  • 16
  • 27
  • The correct approach is to check the return value of the function and only call `GetLastError` if the function has failed. Exactly what indicates failure does vary from call to call mind you so it's always a struggle with the MSDN docs. – David Heffernan Feb 03 '12 at 13:14