Solved

Windows: Problem with FindFirstFile() on X:\path mapped to network disk -- VS 2005 and 2008 differs.

Posted on 2010-09-02
4
1,930 Views
Last Modified: 2012-05-10
Hi,

This questtion is very specific to MS Windows, probably narrowed to Windows 7 and Windows Vista, possibly with some newer version of the MS Server.  It started as som innocent code:

bool isfile(const std::string & path)
{
        struct _stat stat;

        if (_stat(path.c_str(), &stat))
            return false;

        return (stat.st_mode & _S_IFREG) != 0;
}

It stopped to work probably with Windows Vista, definitely with Windows 7 (I currently have 64-bit version).  The _stat() variant is translated to _stat64i32().  The path looks like this 'x:\demo\file.txt' where the x: is mapped via "net use x: \\myserver\moutpoint". The equivalent UNC path is '\\myserver\moutpoint\demo\file.txt' (intentionally enclosed in single quotes to emphasize that the problem is not in doubling backslashes inside the string literal).

Now the fun... When the code is compiled by VC++ 8 (VS 2005), it does says that "it is not a file".  When the same code is compiled by VC++ 9 (VS 2008), then it says "it is a file".  The problem appears only when the disk letter was mapped to the network directory and only when compiled with VC++ 8.

When debugging, the FindFirstFile() seems to be the most deep core of the problem that I am able to find.  In VC++ 8 result it returns INVALID_HANDLE_VALUE (i.e. -1), in the program compiled with VC++ 9 it returns some valid handle.  Some info that may help:

Microsoft Visual Studio 2005
Version 8.0.50727.867  (vsvista.050727-8600)
Microsoft .NET Framework
Version 2.0.50727 SP2
Installed Edition: Professional

Microsoft Visual Studio 2008
Version 9.0.30729.1 SP
Microsoft .NET Framework
Version 3.5 SP1
Installed Edition: Professional

Both executable variants work fine when the disk letter is related to the local disk, or when the path has the UNC form.

No furter ideas on my side.  Help, please. ;)

Otherwise, have a nice time.
   Petr
0
Comment
Question by:pepr
  • 2
4 Comments
 
LVL 86

Assisted Solution

by:jkr
jkr earned 50 total points
ID: 33587003
>>No furter ideas on my side.  Help, please. ;)

Why not using the Windows API (http://msdn.microsoft.com/en-us/library/aa364944%28VS.85%29.aspx - "GetFileAttributes Function") directly? I.e.
bool isfile(const std::string & path)
{
        DWORD dwAtt = GetFileAttributesA(path.c_str());

        if ( INVALID_FILE_ATTRIBUTES == dwAtt) return false;

        if ( (dwAtt | FILE_ATTRIBUTE_DIRECTORY) ||
             (dwAtt | FILE_ATTRIBUTE_REPARSE_POINT)
           ) return false; // may be check for FILE_ATTRIBUTE_DEVICE also

        return true;
}

Open in new window

0
 
LVL 7

Accepted Solution

by:
JimBeveridge earned 450 total points
ID: 33589905
Since your problem is tied tightly to drive letters under Vista/Win7, it sounds like you have an Administrator permissions problem. I'm guessing that you are running VS2005 as an Administrator and you are not running VS2008 as an Admin. In Vista/Win7, Administrators do not have access to drive letters created by non-Administrators.  Anything mapped from Explorer is considered non-Administrator.

To see this in action, open a command prompt with right-click / Run As Administrator.  Now try 'DIR x:\demo\file.txt'.  The command will fail, just like your code does. If you now map y: from this command line to the same UNC, then this command will work: 'DIR y:\demo\file.txt'

More details and workaround: http://support.microsoft.com/kb/937624
0
 
LVL 29

Author Comment

by:pepr
ID: 33594174
@JimBeveridge: I do have administrator privileges.  I have created the X: via "net use X: ..."  Both versions of the executable are run in the same time (one after another).  When debugging, both VS 2005 and VS2008 run in parallel (i.e. I can switch to the the other instantly.  The application must not require the "Run as administrator" as it will be used by normal users.

But you are 100 % right! When I do "net use x: \\server\mountpoint" with leveraged privileges (right click, "Run as admin") it is visible only when being with leveraged privileges and not visible (from cmd window) when using the same admin account without leveraged privileges, and vice versa.

I did not use the workaround, but it clearly describes the same situation.


@jkr: Thanks, I was thinking about something like that.  But it does not work.  Or better to say, it gives the same results as the _stat().  The reason is that the x: really does not exist in some situations.

Summary: The reason why it works from VS 2008 and not from VS 2005 is that VS 2008 is newer and does not require running with leveraged privileges.  The VS 2005 must be launched with leveraged privileges because of some compatibility reasons.  If I recall correctly, it had to be done manually earlier (or via checking some compatibility switches in the shortcut properties).  It seems that now (probably after some Windows Updates patches) there is some launcher that starts the VS 2005 with leveraged privilege without the user intervention (he or she only have to confirm that by pushing the Yes button in the small UAC window).

This way, I was searching the bug at the place where it seemed to be (different behaviour), but it was caused by different access tokens (even though belonging to the same login name).
0
 
LVL 29

Author Closing Comment

by:pepr
ID: 33594190
Thanks a lot
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

How to record audio from input sources to your PC – connected devices, connected preamp to record vinyl discs, streaming media, that play through your audio card: Vista, Windows 7, Windows 8, Windows 8.1 and Windows 10 – both 32 bit & 64.
An article on effective troubleshooting
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

749 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question