2016年10月31日月曜日

FindFirstFile にルートパスを指定した場合の挙動について

FindFirstFile(FindFirstFileEx) 関数の lpFileName にルートパスは指定できません。
MSDN でそのように記載されています。
FindFirstFile 関数
FindFirstFile の lpFileName パラメータでは、最後に円記号(\)を付けるかどうかにかかわりなく、ルートディレクトリを指定することはできません。




指定できないのはわかりましたが、実際に指定してしまった場合にどうなるのか検証したところ、厄介な挙動だったので備忘録として残しておきます。

検証にしようしたコードはこちら。

#include <windows.h>
#include <tchar.h>
void FindFirstFileTest()
{
_tprintf(_T("FindFirstFile\n"));
TCHAR buf[3] = _T("c:");
for( TCHAR letter = _T('c'); letter <= _T('z'); letter += 1 )
{
WIN32_FIND_DATA fd;
buf[0] = letter;
HANDLE hFind = FindFirstFile(buf, &fd);
if( hFind == INVALID_HANDLE_VALUE )
{
_tprintf(_T("%s = INVALID\n"), buf);
}
else
{
_tprintf(_T("%s = %s\n"), buf, fd.cFileName);
FindClose(hFind);
}
}
}
void FindFirstFileExTest(FINDEX_INFO_LEVELS finfoLevelId)
{
_tprintf(_T("FindFirstFileEx\n"));
TCHAR buf[3] = _T("c:");
for( TCHAR letter = _T('c'); letter <= _T('z'); letter += 1 )
{
WIN32_FIND_DATA fd;
buf[0] = letter;
HANDLE hFind = FindFirstFileEx(buf, finfoLevelId, &fd, FindExSearchNameMatch, NULL, 0);
if( hFind == INVALID_HANDLE_VALUE )
{
_tprintf(_T("%s = INVALID\n"), buf);
}
else
{
_tprintf(_T("%s = %s\n"), buf, fd.cFileName);
FindClose(hFind);
}
}
}
void TestAll()
{
FindFirstFileTest();
//FindFirstFileExTest(FindExInfoStandard);
//FindFirstFileExTest(FindExInfoBasic);
}
int main()
{
TCHAR current_drive_letter = _T('C');
{
TCHAR cd[MAX_PATH];
GetCurrentDirectory(MAX_PATH, cd);
current_drive_letter = cd[0];
_tprintf(_T("Current Directory: %s\n"), cd);
}
TestAll();
{
TCHAR cd[MAX_PATH] = _T("C:\\");
cd[0] = current_drive_letter;
SetCurrentDirectory(cd);
GetCurrentDirectory(MAX_PATH, cd);
_tprintf(_T("Current Directory: %s\n"), cd);
}
TestAll();
return 0;
}


これを実行するとこのような出力になります。

カレントディレクトリがルートパスでない場合

このように INVALID_HANDLE ではなく Find が成功し、しかもなぜかカレントディレクトリ名が取得できます。


これが、カレントディレクトリがルートパスだった場合

期待?通り INVALID_HANDLE が返ります。


ちなみに、FindFirstFileExTest がコメントアウトされていますが、FindFirstFileEx でも同じ挙動を示しました。
(Windows 10 HOME version 1607 build 14393.321)
古い OS での検証はできていないので、もしかしたら挙動が異なるかもしれません。

0 件のコメント:

コメントを投稿