boost::filesystem::exists() & GetfileAttributesA
Hi, I am experiencig a problem with exists() and its Windows implementation with GetFileAttributes API. I am using exists() prior to the scan of a directory to see if it exists; the fact is that on W2K (just tested it on that OS) after a day or two GetFileAttributesA() returns INVALID_FILE_ATTRIBUTES but the path does exists (it is a UNC-style path). After a restart of the app, all works fine. So, should I use exists() this way ? I don't know why not. Or just use directory_iterator and scan the hot-folder right away catching any exceptions ?. I don't want to iterate over a direcotry that doesn't exists if I could knew that in advance; besides, I don't know if that will work anyway. Does anyone know somthing about this GetFileAttributesA/boost::exists() behavior ? Thanks in advance, Sebastian.
IIRC, We had a similar problem in one of our apps with GetFileAttributesA. The solution was to switch to FindFirstFile, FindClose, giving raise to the suspicion that some implementations of GetFileAttributes are broken. Regards, Simon. -----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Sebastian Orfino Sent: 23 March 2004 16:07 To: boost-users@lists.boost.org Subject: [Boost-users] boost::filesystem::exists() & GetfileAttributesA Hi, I am experiencig a problem with exists() and its Windows implementation with GetFileAttributes API. I am using exists() prior to the scan of a directory to see if it exists; the fact is that on W2K (just tested it on that OS) after a day or two GetFileAttributesA() returns INVALID_FILE_ATTRIBUTES but the path does exists (it is a UNC-style path). After a restart of the app, all works fine. So, should I use exists() this way ? I don't know why not. Or just use directory_iterator and scan the hot-folder right away catching any exceptions ?. I don't want to iterate over a direcotry that doesn't exists if I could knew that in advance; besides, I don't know if that will work anyway. Does anyone know somthing about this GetFileAttributesA/boost::exists() behavior ? Thanks in advance, Sebastian. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users **************** Confidentiality Notice & Disclaimer ****************** Information in this message (including attachments) is confidential and may be legally privileged. It is intended solely for the person to whom it is addressed. If you are not the intended recipient, you are hereby notified that any unauthorised disclosure, copying, distribution or use of this information is strictly prohibited. If you receive this transmission in error, please notify the sender and then delete this e-mail immediately. Any views or opinions presented are solely those of the author and do not necessarily represent those of Computair Limited. E-mails received by employees of Computair Limited may be monitored and read by employees other than those to whom it is addressed.
At 11:50 AM 3/23/2004, Simon Hammett wrote:
IIRC,
We had a similar problem in one of our apps with GetFileAttributesA. The solution was to switch to FindFirstFile, FindClose, giving raise to the suspicion that some implementations of GetFileAttributes are broken.
That would be a truly horrible bug. GetFileAttributes() isn't just some minor, rarely used function. It is critical to the correct operation of a number of Boost.Filesystem functions, and I'd guess many tens of thousands of other applications. It is hard to imagine a Windows system staying stable if GetFileAttributes() failed very often. I'm going to be travelling over the next few days and can't research this. Could someone post a description on microsoft.public.win32.programmer.kernel and see if those folks have any insights? You can use google groups via http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&group=microsoft.public.win32.programmer.kernel Thanks, --Beman
We had a similar problem in one of our apps with GetFileAttributesA. The solution was to switch to FindFirstFile, FindClose, giving raise to the suspicion that some implementations of GetFileAttributes are broken.
That would be a truly horrible bug. GetFileAttributes() isn't just some minor, rarely used function. It is critical to the correct operation of a number of Boost.Filesystem functions, and I'd guess many tens of thousands of other applications. It is hard to imagine a Windows system staying stable if GetFileAttributes() failed very often.
There is some information in MSDN on this: First off I found an "Under the Hood" article from the September 2000 issue of MSDN Magazine, where GetFileAttributes was periodically failing due to an access permissions problem. The secret was to determine the value of GetLastError after the call (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]). 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. John.
We had a similar problem in one of our apps with GetFileAttributesA. The solution was to switch to FindFirstFile, FindClose, giving raise to
suspicion that some implementations of GetFileAttributes are broken.
That would be a truly horrible bug. GetFileAttributes() isn't just some minor, rarely used function. It is critical to the correct operation of a number of Boost.Filesystem functions, and I'd guess many tens of thousands of other applications. It is hard to imagine a Windows system staying stable if GetFileAttributes() failed very often.
There is some information in MSDN on this: First off I found an "Under
At 06:30 AM 3/25/2004, John Maddock wrote: the the
Hood" article from the September 2000 issue of MSDN Magazine, where GetFileAttributes was periodically failing due to an access permissions problem. The secret was to determine the value of GetLastError after the call
(apparently you can get this without actually calling GetLastError by examining the DWORD at offset 0x34 in the thread environment block
Makes sense. 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.
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. 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. Thanks, --Beman
(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 }
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 -
At 10:29 AM 3/30/2004, John Maddock wrote: that
API can also fail for reasons other than the file not existing.
Thanks, John, much appreciated. --Beman
participants (4)
-
Beman Dawes
-
John Maddock
-
Sebastian Orfino
-
Simon Hammett