You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C++获取NTFS特殊$Extend文件夹文件列表并解决权限报错

解决NTFS特殊文件夹/文件访问被拒绝的问题

核心问题分析

打开$Extend或$MFT这类NTFS元数据对象时,仅拥有SE_BACKUP_NAME权限和管理员身份还不够,必须正确启用权限并使用特定的文件打开参数,还要注意路径格式的正确性。

具体步骤与代码实现

1. 启用SE_BACKUP_NAME和SE_RESTORE_NAME权限

即使是管理员,这些特权默认也是禁用的,必须显式启用:

#include <windows.h>
#include <sddl.h>

BOOL EnablePrivilege(LPCWSTR privilegeName) {
    HANDLE tokenHandle;
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &tokenHandle)) {
        return FALSE;
    }

    TOKEN_PRIVILEGES tp{};
    tp.PrivilegeCount = 1;
    if (!LookupPrivilegeValueW(nullptr, privilegeName, &tp.Privileges[0].Luid)) {
        CloseHandle(tokenHandle);
        return FALSE;
    }
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    BOOL result = AdjustTokenPrivileges(tokenHandle, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr);
    CloseHandle(tokenHandle);
    return result && GetLastError() == ERROR_SUCCESS;
}

调用时需同时启用两个特权:

EnablePrivilege(SE_BACKUP_NAME);
EnablePrivilege(SE_RESTORE_NAME);

2. 正确使用CreateFile打开元数据文件

打开$MFT时,需注意:

  • 路径必须使用原生NT路径格式(\\?\C:\$MFT),避免Win32路径解析限制
  • 必须指定FILE_FLAG_OPEN_REPARSE_POINT(防止解析符号链接),结合FILE_FLAG_BACKUP_SEMANTICS
  • 共享模式需包含FILE_SHARE_DELETE,覆盖系统可能的锁定场景

修正后的代码:

HANDLE hMft = CreateFileW(
    L"\\\\?\\C:\\$MFT",
    GENERIC_READ,
    FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    nullptr,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
    nullptr
);

if (hMft == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    // 处理错误,比如打印错误码
} else {
    // 成功打开,执行后续操作
    CloseHandle(hMft);
}

3. 枚举$Extend文件夹内容

使用FindFirstFileExW替代FindFirstFile,搭配原生NT路径和必要的标志位:

WIN32_FIND_DATAW findData{};
HANDLE hFind = FindFirstFileExW(
    L"\\\\?\\C:\\$Extend\\*",
    FindExInfoBasic,
    &findData,
    FindExSearchNameMatch,
    nullptr,
    FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT
);

if (hFind != INVALID_HANDLE_VALUE) {
    do {
        // 处理枚举到的文件/文件夹:findData.cFileName
    } while (FindNextFileW(hFind, &findData));
    FindClose(hFind);
} else {
    DWORD err = GetLastError();
    // 处理错误
}

关键注意事项

  • 若系统启用了BitLocker加密,加密卷的元数据文件无法通过此方式直接访问
  • 部分NTFS元数据对象(如$LogFile)可能被系统独占锁定,此时需通过FSCTL_GET_NTFS_VOLUME_DATA等API间接获取信息
  • 测试时必须以本地管理员身份运行程序,远程桌面管理员可能受UAC权限限制

内容的提问来源于stack exchange,提问作者user3161924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 08:40:13