开发者

Why does boost::filesystem is_directory return different results when run as a Windows Service?

I have some code that iterates through files in a directory and does useful things with the non-directory files, like so:

namespace bfs = boost::filesystem;
for (bfs::directory_iterator iterDir(m_inPath); 
     bContinue && iterDir!=bfs::directory_iterator(); iterDir++)
{
    std::string filename = iterDir->path().filename().string();
    boost::to_lower(filename);

    if (!bfs::is_directory(*iterDir) && Condition2(filename)) {
        std::ifstream ifFile(iterDir->path().st开发者_运维知识库ring().c_str());
        DoUsefulThings(iterDir());
    }
}

This works fine in my unit tests, but when I run the full program as a service, my test directories (seemingly erroneously) get past the !bfs::is_directory check and DoUsefulThings's ifstream.good() check fails, with an errno of 13.

I tried changing !bfs::is_directory to bfs::is_regular_file (thinking that maybe there was a system condition causing it to be something else), but I got the same results. The is_regular_file condition fails on the directory in my unit test but passes when run as a service.

I also added a try/catch around my if statement to see if it was throwing an exception and verified that it wasn't (probably could use one anyway, but didn't help with this).

I considered that the problem could be related to the service's permissions level, so I changed the properties of the service to log on as the same account that I use to log in to that system. Same result. I've dabbled with PerformanceMonitor some as well to try to get some clues there, but I haven't gleaned much from it yet.

Can someone suggest why this might be happening? Errno=13 == "permission denied", right? Is there an additional check I need to perform before calling is_directory?

I'm using Windows XP, Visual Studio 2008/C++, version 1.44 of the Boost library, and version 3 of filesystem.

ETA: I added the following to test the directory manually (the direction of the slash marks didn't make a difference), and is_regular_file behaves as expected:

std::string strDir = "D:/Dir1/Dir2/Dir3/Dir4/Dir5\\Dir6";
if (bfs::is_regular_file(strDir))
    LOG("It's a regular file"); //This does not get executed
else
    LOG("Not a regular file");  //This does

I have log statements printing out both *iterDir and iterDir->path() and they both match the one I put in manually. Does this rule out permissions issues? Will continue testing, as this result doesn't really make sense to me yet.


@Ennael:

don't forget that you need traversal permissions on all the parent folders/device nodes of the folder you are trying to access. I think Roman's suggestion would be first in line to eliminate the doubt (which, of course is really irrational: Errno=13 == "permission denied").

You could start from there with a tools like

  • cacls.exe

To do commandline ACL listing/editing

  • AccessEnum v1.32 to detect any changes in permissions across a filesystem tree (has a nifty option to only warn when permissions get more restricted or more permissive)


Bah. It was a bug in my "Condition2". Thanks for the help.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜