locked
FindFirstFile not listing folders or files from "Documents and Settings" folder RRS feed

  • Question

  • Im using code based from this webpage: http://msdn.microsoft.com/en-us/library/aa365200(v=VS.85).aspx

     

    but when i try to list the files and folders in c:\Documents and Settings folder nothing comes up.

     

    There are other "special" folders that don't work either, like "My Documents".

    any ideas?

     

    WIN32_FIND_DATA ffd;
        LARGE_INTEGER filesize;
        TCHAR szDir[MAX_PATH];
        size_t length_of_arg;
        HANDLE hFind = INVALID_HANDLE_VALUE;
        DWORD dwError=0;

        // If the directory is not specified as a command-line argument,
        // print usage.

        // Check that the input path plus 3 is not longer than MAX_PATH.
        // Three characters are for the "\*" plus NULL appended below.

        if (m_sPath.length() > (MAX_PATH - 3))
        {
            return;
        }

        // Prepare string for use with FindFile functions.  First, copy the
        // string to a buffer, then append '\*' to the directory name.

        StringCchCopy(szDir, MAX_PATH, m_sPath.c_str());
        StringCchCat(szDir, MAX_PATH, TEXT("\\*"));

        // Find the first file in the directory.

        hFind = FindFirstFile(szDir, &ffd);

        if (INVALID_HANDLE_VALUE == hFind)
        {
            return;
        }

        for(int y = 0; y < TOTAL_CLIPS; y++)
            m_pFileBrowserFolderEntry[y].m_bSet = false;

        // List all the files in the directory with some info about them.
        int m_iEntryIndex = 0;
        do
        {
            if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            {
                if (m_iEntryIndex < TOTAL_CLIPS)
                    m_pFileBrowserFolderEntry[m_iEntryIndex].SetText(ffd.cFileName);

                m_iEntryIndex++;
            }
            else
            {
                filesize.LowPart = ffd.nFileSizeLow;
                filesize.HighPart = ffd.nFileSizeHigh;
                _tprintf(TEXT("  %s   %ld bytes\n"), ffd.cFileName, filesize.QuadPart);
            }

        }
        while (FindNextFile(hFind, &ffd) != 0);
    Sunday, January 9, 2011 9:10 PM

Answers

  • This makes me think that you are running this application on Windows Vista or newer. The reason why this fails is because Documents and Settings isn't a directory, it is a junction point which links to users.

    14/07/2009 05:08  <JUNCTION>   Documents and Settings [C:\Users]

    And if you look at it's security settings then you will see why. Everyone is blocked from listing contents etc.

    This is in place for compatability with older versions of Windows. So you should also deal with it appropriately. Since it is just a link to Users then it is possible to just ignore the junction, otherwise it is possible to read the junction point information and instead of going into Documents and Settings, you change the directory to Users instead.

    For the other special directories which also don't work, you will find that they are mainly inside users profiles. Again, these are all junction points so you should be able to treat them the same as Documents and Settings.


    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    • Proposed as answer by Nikita Leontiev Saturday, January 15, 2011 10:45 PM
    • Marked as answer by lucy-liu Monday, January 17, 2011 8:51 AM
    Sunday, January 9, 2011 9:24 PM

All replies

  • This makes me think that you are running this application on Windows Vista or newer. The reason why this fails is because Documents and Settings isn't a directory, it is a junction point which links to users.

    14/07/2009 05:08  <JUNCTION>   Documents and Settings [C:\Users]

    And if you look at it's security settings then you will see why. Everyone is blocked from listing contents etc.

    This is in place for compatability with older versions of Windows. So you should also deal with it appropriately. Since it is just a link to Users then it is possible to just ignore the junction, otherwise it is possible to read the junction point information and instead of going into Documents and Settings, you change the directory to Users instead.

    For the other special directories which also don't work, you will find that they are mainly inside users profiles. Again, these are all junction points so you should be able to treat them the same as Documents and Settings.


    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    • Proposed as answer by Nikita Leontiev Saturday, January 15, 2011 10:45 PM
    • Marked as answer by lucy-liu Monday, January 17, 2011 8:51 AM
    Sunday, January 9, 2011 9:24 PM
  • Thanks for  the info, im using windows 7.

    Does anyone have any code, im getting a little confused by these new "junction points".

     

    how can I test when using FindFirstFile if it is a junction point?

    and then how can I find it's real folder?

     

    there must be some code around as it's a common thing, folder and file enum.

     

    I would use the standard windows file dialogs but ive created my own archive file format, these files contain multiple files so i would like my file browser to be able to search inside the archive files too as if they are folders.

    Sunday, January 9, 2011 9:57 PM
  • You can detect the Junction Points and use real path in your code. The following document contains the information you need.

    http://msdn.microsoft.com/en-us/library/bb968829%28v=vs.85%29.aspx

     

    These junction points can be identified as follows:

     

        * They have the FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_HIDDEN, and FILE_ATTRIBUTE_SYSTEM file attributes set.

    * They also have their access control lists (ACLs) set to deny read access to everyone. 

    That’s why you cannot visit. 


    Senior Technical Consultant. Helping Others, Grow Yourself!
    Monday, January 10, 2011 1:56 PM
  • Well, junction points are not new, they have been available since Windows 2000. So that is around 10 years already. The reason they were used though was for compatability reasons.

    Anyway, to deal properly with junction points, first check the dwFileAttributes and check if the FILE_ATTRIBUTR_REPARSE_POINT flag is set. If it is then you know that you have a reparse point at least. But this is where things get tricky because a reparse point could be a symbolic link, junction point (yes, they are different) or volume mount point. Then just check the dwReserved0 and see if it is IO_REPARSE_TAG_MOUNT_POINT or IO_REPARSE_TAG_SYMLINK. If it is not either of these then it is a reparse point you can't deal with.

    You then have two choices, you can try to open the file with CreateFile and specify no access to it. You can't do too much with the handle but you can try GetFinalPathNameByHandle to see if it will give the path of the directory it is pointing to. Otherwise there is only one other choice.

    You would then have to do something which people find scary, use DeviceIoControl and use FSCTL_GET_REPARSE_POINT to get the data for the junction. In the information given check the mount point information and that should get you where the junction is pointing to. (I may be wrong on this, but I am sure that junctions are based on mount points). For symbolic links you should obviously check the symbolic link information instead.

    It can be scary since you are using a function like DeviceIoControl. But it is a pretty easy function to use.


    Any samples given are not meant to have error checking or show best practices. They are meant to just illustrate a point. I may also give inefficient code or introduce some problems to discourage copy/paste coding. This is because the major point of my posts is to aid in the learning process.
    Visit my (not very good) blog at
    http://ccprogramming.wordpress.com/
    Monday, January 10, 2011 6:40 PM