getnamedsecurityinfo是读取文件夹dacl的标准api,需同时传dacl_security_information和owner_security_information,返回只读pacl,路径须为绝对路径且unc末尾不能有反斜杠。

怎么用 GetNamedSecurityInfo 读取文件夹的 DACL
直接调用 GetNamedSecurityInfo 是获取 Windows 文件夹 ACL 的标准方式,但它返回 NULL 不代表没权限——大概率是参数写错了。必须同时传入 DACL_SECURITY_INFORMATION 和 OWNER_SECURITY_INFORMATION,只传前者会被系统忽略。
返回的 PACL 是只读副本,不能直接修改;若要编辑,得用 CopySid + InitializeAcl 新建一块内存,再把原 ACE 拷贝过去(注意清除 ACE_INHERITED_ACE 标志,否则 SetEntriesInAcl 会失败)。
- 路径必须是绝对路径,UNC 路径末尾不能带反斜杠,否则返回
ERROR_INVALID_PARAMETER - 调用前建议先用
GetFileSecurity测试是否可读,避免因权限不足导致静默失败 - 返回的 DACL 可能含继承项,但
GetNamedSecurityInfo不自动展开子项,需手动遍历GetAce解析
怎么用 SetNamedSecurityInfo 设置文件夹 ACL(不是 chmod)
SetNamedSecurityInfo 是 Windows 下真正替换 DACL 的底层 API,它不“追加”,而是全量覆盖——原来有的 ACE(比如 SYSTEM 的 FullControl),新 DACL 里没写,就彻底消失。这点和 Linux 的 setfacl -m 完全不同。
构造新 DACL 分两步:EXPLICIT_ACCESS 数组 → SetEntriesInAcl 生成 PACL。别手写 ACCESS_ALLOWED_ACE,大小、顺序、继承标志都容易错。
- 必须以管理员权限运行,普通用户即使对文件夹有 Full Control 也无法改 DACL,错误码是
ERROR_PRIVILEGE_NOT_HELD -
Trustee.TrusteeForm必须设为TRUSTEE_IS_NAME,不能直接传字符串 SID;更稳的做法是用ConvertStringSidToSid解析已知 SID(如"S-1-5-32-545") -
grfAccessMode选GRANT_ACCESS,不是SET_ACCESS;后者会清掉同类型旧 ACE,不是你想要的“添加”
std::filesystem::permissions 能不能替代 ACL 设置
不能。C++17 的 std::filesystem::permissions 只映射基础 POSIX 权限(rwx),在 Windows 上它只是调用 SetFileAttributes 或简单 ACL 封装,无法控制用户/组粒度、无法设置拒绝规则、无法处理继承或对象所有者。
比如你想“禁止 Users 组删除某个文件夹,但允许读取”,std::filesystem::perms 根本做不到——它没有 DELETE 权限位,也没有 Trustee 概念。
- 适合场景:跨平台脚本类工具、仅需 owner/group/others 三级控制
- 不适合场景:企业级部署、需要细粒度审计、与域账户集成、规避继承污染
- Windows 下调用它可能触发后台 ACL 合成,但行为不可控,且不返回错误码,失败时静默降级
为什么 SetFileSecurity 不推荐用于 ACL 修改
SetFileSecurity 要求你手动构造完整 SECURITY_DESCRIPTOR,其中 DACL 字段必须指向已初始化的内存块。新手常只分配 sizeof(ACL) 却忘了调 InitializeAcl,结果触发 ERROR_INVALID_PARAMETER,还很难定位。
相比 SetNamedSecurityInfo,它还有两个硬伤:一是不支持原子性更新(DACL/Owner/Group 需一次全传),二是对空 DACL 处理不一致,某些旧系统会拒绝空指针。
- 如果你已经拿到一个现成的
SECURITY_DESCRIPTOR(比如从其他对象复制),那它可用;否则一律优先用SetNamedSecurityInfo - 调试时可用
icacls "path" /save acl.txt导出当前 ACL 做比对,验证是否真的生效 - 设置后务必用
GetNamedSecurityInfo再读一次,确认GetAce遍历出来的 ACE 条目数和权限掩码符合预期
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











