(apparently you can get this without actually calling GetLastError by examining the DWORD at offset 0x34 in the thread environment block pointed to by FS:[18h]).
Unless that is a published interface unlikely to change, I'd rather call GetLastError(). An offset also might change in a 64-bit Windows environment, which we are likely to be having to deal with soon.
Absolutely, I mentioned that only because (in some debuggers apparently) it let's you inspect the result of GetLastError in the debugger, even if your code doesn't actually call it.
So if GetFileAttributes can fail for reasons other than the file not existing, then the return value of GetLastError should also be checked to verify that the reason for the failure really was that the file does not exist: Looks like error codes of ERROR_FILE_NOT_FOUND or ERROR_PATH_NOT_FOUND would be returned in this case.
That sounds right to me.
GetFileAttributes() is also used by is_directory(), and GetFileAttributesEx() is used a couple of places. I don't know if those usages also need to be changed. It may be the code is OK but the docs need to mention the case where attributes are unaccessible.
I've taken a quick look, and they all throw exceptions if the call fails, that looks OK to me, it's just exists() that has to produce a true/false result with no exceptions.
John, could you take a look at boost-root/libs/filesystem/src/operations_posix_windows.cpp and make any changes you think are necessary? I'm out-of-action for personal reasons for awhile, so can't do it myself.
OK, patch applied below, note the changes to the stat() code as well - that API can also fail for reasons other than the file not existing. John. diff -u -r1.32 operations_posix_windows.cpp --- operations_posix_windows.cpp 20 Mar 2004 18:24:48 -0000 1.32 +++ operations_posix_windows.cpp 30 Mar 2004 15:06:44 -0000 @@ -310,9 +310,23 @@ { # ifdef BOOST_POSIX struct stat path_stat; - return ::stat( ph.string().c_str(), &path_stat ) == 0; + if(::stat( ph.string().c_str(), &path_stat ) != 0) + { + if((errno == ENOENT) || (errno == ENOTDIR)) + return false; // stat failed because the path does not exist + // for any other error we assume the file does exist and fall through, + // this may not be the best policy though... (JM 20040330) + } + return true; # else - return ::GetFileAttributesA( ph.string().c_str() ) != 0xFFFFFFFF; + if(::GetFileAttributesA( ph.string().c_str() ) == 0xFFFFFFFF) + { + if((::GetLastError() == ERROR_FILE_NOT_FOUND) || (::GetLastError() == ERROR_PATH_NOT_FOUND)) + return false; // GetFileAttributes failed because the path does not exist + // for any other error we assume the file does exist and fall through, + // this may not be the best policy though... (JM 20040330) + } + return true; # endif }