如何使用 GetFileInformationByHandleEx 读取连接点目录中的文件?
How to read files in a junction point directory, using GetFileInformationByHandleEx?
如果 path
指向常规目录,我的代码运行良好:
#include <windows.h>
#include <stdio.h>
int main()
{
wchar_t path[1024] = L"C:\MyPath\MyDir";
auto h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
{
printf("CreateFile error: 0x%08X\n", GetLastError());
return 0;
}
FILE_ID_INFO id = {};
if (!GetFileInformationByHandleEx(h, FILE_INFO_BY_HANDLE_CLASS::FileIdInfo, &id, sizeof(id)))
{
printf("FileIdInfo error: 0x%08X\n", GetLastError());
}
unsigned char buffer[4096];
do
{
if (!GetFileInformationByHandleEx(h, FILE_INFO_BY_HANDLE_CLASS::FileIdExtdDirectoryInfo, buffer, ARRAYSIZE(buffer)))
{
auto gle = GetLastError();
if (gle == ERROR_NO_MORE_FILES)
break;
printf("FileIdExtdDirectoryInfo error: 0x%08X\n", gle);
break;
}
auto current = buffer;
do
{
auto info = (FILE_ID_EXTD_DIR_INFO*)current;
wprintf(L"name: %.*s\n", info->FileNameLength / 2, info->FileName);
if (!info->NextEntryOffset)
break;
current += info->NextEntryOffset;
} while (true);
} while (true);
CloseHandle(h);
}
但是如果目录指向一个连接点,它returns(ERROR_INVALID_PARAMETER
无效参数)
FileIdInfo error: 0x00000057
FileIdExtdDirectoryInfo error: 0x00000057
所以,我已经为 CreateFile
试过了
auto h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
现在,我没有错误,但它只显示 "."
和 ".."
条目,而不是我可以使用 cmd.exe[=19 读取的目录中的所有文件=]
C:\MyPath\MyDir>dir
Volume in drive C has no label.
Volume Serial Number is AEA6-688A
Directory of C:\MyPath\MyDir
20/10/2017 14:08 (157) My Icon.ico
11/04/2018 09:08 321 My File.cpp
30/04/2018 15:14 <DIR> My dossier
19/09/2019 10:40 (41 650) New Rich Text Document.rtf
10/10/2021 11:06 0 New Text Document.txt
4 File(s) 46 224 bytes
1 Dir(s) 544 625 274 880 bytes free
事实证明我的代码本身是正确的,但如果下面的文件系统不支持 NTFS object ID,它可能会失败,因为这是它试图读取的内容(使用 FILE_INFO_BY_HANDLE_CLASS::FileIdInfo 和FILE_INFO_BY_HANDLE_CLASS::FileIdExtdDirectoryInfo).
例如,如果目录是 NTFS mount point with a substitute name that points to a volume that doesn't have the FILE_SUPPORTS_OBJECT_IDS 标志集(在虚拟驱动器场景中看到),就会发生这种情况。
这里的错误 (ERROR_INVALID_PARAMETER
) 有点误导,因为任何参数都没有问题(可能 FileInformationClass
一个除外),我本以为会出现一些“不受支持”的错误。
至于 cmd.exe,嗯,它只是没有 read/need 那个信息,所以它工作正常。
如果 path
指向常规目录,我的代码运行良好:
#include <windows.h>
#include <stdio.h>
int main()
{
wchar_t path[1024] = L"C:\MyPath\MyDir";
auto h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (h == INVALID_HANDLE_VALUE)
{
printf("CreateFile error: 0x%08X\n", GetLastError());
return 0;
}
FILE_ID_INFO id = {};
if (!GetFileInformationByHandleEx(h, FILE_INFO_BY_HANDLE_CLASS::FileIdInfo, &id, sizeof(id)))
{
printf("FileIdInfo error: 0x%08X\n", GetLastError());
}
unsigned char buffer[4096];
do
{
if (!GetFileInformationByHandleEx(h, FILE_INFO_BY_HANDLE_CLASS::FileIdExtdDirectoryInfo, buffer, ARRAYSIZE(buffer)))
{
auto gle = GetLastError();
if (gle == ERROR_NO_MORE_FILES)
break;
printf("FileIdExtdDirectoryInfo error: 0x%08X\n", gle);
break;
}
auto current = buffer;
do
{
auto info = (FILE_ID_EXTD_DIR_INFO*)current;
wprintf(L"name: %.*s\n", info->FileNameLength / 2, info->FileName);
if (!info->NextEntryOffset)
break;
current += info->NextEntryOffset;
} while (true);
} while (true);
CloseHandle(h);
}
但是如果目录指向一个连接点,它returns(ERROR_INVALID_PARAMETER
无效参数)
FileIdInfo error: 0x00000057
FileIdExtdDirectoryInfo error: 0x00000057
所以,我已经为 CreateFile
auto h = CreateFile(path, FILE_LIST_DIRECTORY, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
现在,我没有错误,但它只显示 "."
和 ".."
条目,而不是我可以使用 cmd.exe[=19 读取的目录中的所有文件=]
C:\MyPath\MyDir>dir
Volume in drive C has no label.
Volume Serial Number is AEA6-688A
Directory of C:\MyPath\MyDir
20/10/2017 14:08 (157) My Icon.ico
11/04/2018 09:08 321 My File.cpp
30/04/2018 15:14 <DIR> My dossier
19/09/2019 10:40 (41 650) New Rich Text Document.rtf
10/10/2021 11:06 0 New Text Document.txt
4 File(s) 46 224 bytes
1 Dir(s) 544 625 274 880 bytes free
事实证明我的代码本身是正确的,但如果下面的文件系统不支持 NTFS object ID,它可能会失败,因为这是它试图读取的内容(使用 FILE_INFO_BY_HANDLE_CLASS::FileIdInfo 和FILE_INFO_BY_HANDLE_CLASS::FileIdExtdDirectoryInfo).
例如,如果目录是 NTFS mount point with a substitute name that points to a volume that doesn't have the FILE_SUPPORTS_OBJECT_IDS 标志集(在虚拟驱动器场景中看到),就会发生这种情况。
这里的错误 (ERROR_INVALID_PARAMETER
) 有点误导,因为任何参数都没有问题(可能 FileInformationClass
一个除外),我本以为会出现一些“不受支持”的错误。
至于 cmd.exe,嗯,它只是没有 read/need 那个信息,所以它工作正常。