gpt4 book ai didi

C++ 文件系统迭代器无效参数

转载 作者:行者123 更新时间:2023-11-30 04:58:07 25 4
gpt4 key购买 nike

我正在使用 fs::recursive_directory_iterator 列出驱动器中的所有文件。

我还传递了 fs::directory_options::skip_permission_denied 以防止迭代器在尝试进入不允许的目录时抛出异常。所以应该没有问题……

但是当尝试在特殊目录(Volume Information、Recycle.Bin、...)中迭代时:

filesystem error: cannot increment recursive directory iterator: Invalid argument

我必须尝试...捕获迭代作为解决方法,但为什么我会遇到这个问题?我应该如何解决这个问题?

我可以用来自 cppreference.com 的最小示例重现它:

#include <fstream>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;

int main()
{
for(auto& p: fs::recursive_directory_iterator("M:", fs::directory_options::skip_permission_denied))
std::cout << p << '\n';
}

结果:

… (Listing real files)

"M:\\System Volume Information"
terminate called after throwing an instance of 'std::experimental::filesystem::v1::__cxx11::filesystem_error'
what(): filesystem error: cannot increment recursive directory iterator: Invalid argument

编辑:此外,filesystem_error 方法 path1()、path2() 返回空路径。是 gcc 错误吗?

最佳答案

如果简单地搜索skip_permission_denied symbol in header files easy可以查看到这个符号只存在于<filesystem>中但不在<experimental/filesystem> .你包含了错误的头文件。

我们需要使用 namespace fs = std::filesystem; - 没有 experimental术语。

关于文件权限 - 如果调用者有 SE_BACKUP_PRIVILEGE :

This privilege allows the user to circumvent file and directory permissions to back up the system. This privilege causes the system to grant all read access control to any file, regardless of the access control list (ACL) specified for the file. Any access request other than read is still evaluated with the ACL. The following access rights are granted if this privilege is held:

  • READ_CONTROL
  • ACCESS_SYSTEM_SECURITY
  • FILE_GENERIC_READ
  • FILE_TRAVERSE

User-mode applications represent this privilege as the following user-right string: "Back up files and directories".

我们还需要使用 FILE_OPEN_FOR_BACKUP_INTENT NtCreateFile NtOpenFile 称呼。或 FILE_FLAG_BACKUP_SEMANTICS CreateFile .

当我们使用 recursive_directory_iterator 时这个我们管不了(不是自己直接打开文件夹)。但是在当前实现中,此类调用 FindFirstFileExW迭代函数。此 api 内部调用 NtOpenFile 总是与 FILE_OPEN_FOR_BACKUP_INTENT选项。结果 SeBackupPrivilege在这里工作。我们需要启用 SE_BACKUP_PRIVILEGE在线程或进程 token 中,当然如果我们在 token 中具有此权限:

#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}

#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
#define END_PRIVILEGES }};

// in case you not include wdm.h, where this defined
#define SE_BACKUP_PRIVILEGE (17L)

ULONG AdjustPrivileges()
{
if (ImpersonateSelf(SecurityImpersonation))
{
HANDLE hToken;
if (OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, TRUE, &hToken))
{
BEGIN_PRIVILEGES(tp, 1)
LAA(SE_BACKUP_PRIVILEGE),
END_PRIVILEGES
AdjustTokenPrivileges(hToken, FALSE, (PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
CloseHandle(hToken);
}
}

return GetLastError();
}

最终代码可能如下所示:

#include <filesystem>

void demo()
{
AdjustPrivileges();

fs::recursive_directory_iterator item(L"c:\\System Volume Information",
fs::directory_options::skip_permission_denied), end;

while (item != end)
{
DbgPrint("%S\n", item->path().c_str());
item++;
}
}

关于C++ 文件系统迭代器无效参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51799541/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com