I have this code and it displays the folder with the directory itself and not its contents. I want to display its contents. I don\'t want to use boost::filesystem.
HANDLE hFind = FindFirstFile("C:\\semester2", &data); // DIRECTORY
You got the directory because that's what you asked for. If you want the files, ask for them:
HANDLE hFind = FindFirstFile("C:\\semester2\\*", &data); // FILES
(You can instead use *.*
if you prefer, but apparently this only works because of a backwards compatibility hack so should probably be avoided. See comments and RbMm's answer.)
Let me take some notes about "*.*"
vs "*"
. These filers are not equal.
2 different files can exist in our folder: somefile
and somefile.
.
If we used the low level api ZwQueryDirectoryFile with "*.*"
as a search expression (this is the 10th parameter - FileName [in, optional]
) - we would get somefile.
only. But if we used "*"
we'd get both files - somefile
and somefile.
If we try FindFirstFile("C:\\semester2\\*.*", &data);
we can note than both files somefile
and somefile.
are returned. So here "*.*"
vs "*"
have the same effect - no difference in usage.
Why does this happen? Because inside FindFirstFileEx
in kernelbase
(kernel32
) do special check for "*.*"
mask and if it true - replace to ""
(An empty name which have the same effect as "*"
).
I think this is done to fix a very common error when users pass "*.*"
instead of the correct "*"
and for backward compatability with legacy code.
.
and..
aren't actually part of the directory as it is stored on disk, but are added by the Win32 API.
This is not true.
FAT
-style file system this is really stored on FAT directory as 2 first entry. NTFS
there are no such entries, but NTFS.sys
artificially add this 2 entries if they in mask. So this is done not at Win32 API level, but in kernel - on driver level.
In conclusion, "*.*"
will work correct with Win32 API how minimum now - but the correct and clean way is to use "*"
here.
"*.*"
will be mistake with ZwQueryDirectoryFile api.
Harrys answer will actually yield files and folders having an extension in your desired folder "C:\\semester2"
.
So for example if you have a folder named "C:\\semester2\\math.course"
it will also be found by the above example. Moreover if you will have a file named "C:\\semester2\\math_scores"
(notice it not having an extension) it will not be found.
Taking the above into consideration I would suggest the following solution:
HANDLE hFind = FindFirstFile("C:\\semester2\\*", &data);
This will list the entire listing of items under the directory. Filtering the directories can be done in the following way:
if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// directory
}
else
{
// file
}
The following can be used for references: FileAttributes constants, FIND_DATA struct, FindFirstFile API