I have to fix a bug deeply buried in legacy code. This code makes a call to FtpFindFirstFileW to collect info about files on an FTP server. It then iterates over the files using InternetFindNextFile, puts the info into a vector and returns this vector.
The problem, however, is that the "path" passed to FtpFindFirstFileW could also be the path to a single file. FtpFindFirstFileW is fine with that an just returns info about this single file. But afterwards I see no possibility to reliably get the full path to the file (i.e. the path passed to FtpFindFirstFileW in the first place). The WIN32_FIND_DATA structure only contains the filename without its path.
My method could be called with a path like
- empty path (e.g. list files in current directory)
- path/to/some/subdir
- path/to/file.txt
- file.txt (e.g. just a filename)
If ever possible I would like to just change this single method to reduce the risk of breaking the legacy code.
WIN32_FIND_DATA FileData;
FtpFindFirstFile(hFTP, Path.c_str(), &FileData, 0, 0);
do
{
auto PathToFile = Path + FileData.cFileName; // wrong result if Path is full path to file (e.g. Path = path/to/file.txt and FileData.cFileName = file.txt)
auto PathToFile = Path; // wrong result if Path is path to directory (e.g. Path = path/ and FileData.cFileName = file.txt)
auto PathToFile = FileData.cFileName; // wrong result if Path path to directory (e.g. Path = path/ and FileData.cFileName = file.txt)
} while(InternetFindNextFile(Hdl,&FileData));
I dont see methods to check if a path is a directory/file or to get the full path to a file in the Windows-FTP-API.
EDIT
Regarding the comments suggesting to use FileData.dwFileAttributes to distinguish between files and directories:
If I call FtpFindFirstFile with the path /foo/bar
I might get a single result with FileData.cFilename = bar
. If FileData.dwFileAttributes
has the FILE_ATTRIBUTE_DIRECTORY
bit not set I don't see a way to know if this is because /file/bar
is a file or because /file/bar
is a directory and there is a file /foo/bar/bar
.