如何使用Windows API C++更改已创建的文件夹/目录安全权限
How to change already created folder/directory security permission using Windows API C++
我必须更改已创建目录的目录权限。如果目录不存在,我可以使用给定安全访问属性的CreateDirectoryEx创建新目录,但是当目录已经存在时,我必须更改目录的安全访问属性 例如:管理员 - 完全访问权限 用户=读取访问权限
首先检查目录是否存在,如果目录存在,则更改安全属性
我能够使用本文更改目录permisison https://learn.microsoft.com/en-us/windows/win32/secauthz/modifying-the-acls-of-an-object-in-c--
对于内核对象的设置安全性,需要使用NtSetSecurityObject
或SetKernelObjectSecurity
(这在NtSetSecurityObject
上是非常薄的外壳(,特别是如果您已经拥有带有WRITE_DAC
的对象句柄,并且如果您还想LABEL_SECURITY_INFORMATION
setWRITE_OWNER
。
需要了解,没有任何其他方法可以在对象上设置安全性 - 任何其他 API 如SetSecurityInfo
或SetNamedSecurityInfoW
无论如何都会内部调用SetKernelObjectSecurity
或NtSetSecurityObject
。
如果我们需要open_if逻辑 - 创建新文件夹(如果它不存在(或打开(如果它已经存在(- 需要使用或NtCreateFile
FILE_OPEN_IF
处置。 然后需要查找IO_STATUS_BLOCK
的信息成员 - 它是FILE_OPENED
还是FILE_CREATED
. 如果FILE_OPENED
调用NtSetSecurityObject
因为在这种情况下,安全描述符将在调用NtCreateFile
中被忽略。 否则,我们已经在NtCreateFile
中设置了安全描述符。 代码可以是下一个:
NTSTATUS CreateFolderWithSD(PCWSTR lpNewDirectory, PSECURITY_ATTRIBUTES psa)
{
UNICODE_STRING ObjectName;
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(lpNewDirectory, &ObjectName, 0, 0);
if (0 <= status)
{
IO_STATUS_BLOCK iosb;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, 0, psa->lpSecurityDescriptor };
status = NtCreateFile(&oa.RootDirectory, WRITE_DAC|WRITE_OWNER, &oa, &iosb, 0,
FILE_ATTRIBUTE_DIRECTORY, FILE_SHARE_VALID_FLAGS, FILE_OPEN_IF,
FILE_DIRECTORY_FILE, 0, 0);
RtlFreeUnicodeString(&ObjectName);
if (0 <= status)
{
switch (iosb.Information)
{
case FILE_OPENED:
status = NtSetSecurityObject(oa.RootDirectory,
DACL_SECURITY_INFORMATION|LABEL_SECURITY_INFORMATION, oa.SecurityDescriptor);
case FILE_CREATED:
break;
default: __debugbreak();
}
NtClose(oa.RootDirectory);
}
}
return status;
}
void TestNF(PCWSTR lpNewDirectory)
{
SECURITY_ATTRIBUTES sa = { sizeof(sa) };
if (ConvertStringSecurityDescriptorToSecurityDescriptor(
L"D:P(A;;FA;;;SY)(A;;FA;;;BA)(A;;FRFX;;;BU)S:(ML;;NWNX;;;HI)",
SDDL_REVISION_1, &sa.lpSecurityDescriptor, 0))
{
CreateFolderWithSD(lpNewDirectory, &sa);
LocalFree(sa.lpSecurityDescriptor);
}
}
在 msdn 页面的 SetKernelObjectSecurity 函数存在下一个注释
注意在文件系统对象上设置安全描述符时,不应使用此函数。相反,请使用 SetSecurityInfo 或SetNamedSecurityInfo函数。
现在我对这个笔记的注释 - 为什么不应该使用?(这不是说不能使用 - 当然可以(。我没有看到任何理由或解释这一点。在任何情况下,当我们在文件上设置安全性时,都将使用此API - 直接或间接。所以认为需要忽略这个注释,它没有任何解释。
另请注意本机API的使用 - 这既是内核又是用户模式API(不仅是许多人认为的内核(,并且像任何其他API一样轻松(或困难(使用它。 没有任何不同(只需使用ntdllp.lib或ntdll.lib(。 我使用NtCreateFile
因为任何 Win 32 API 不提供这样的功能 - 文件夹和返回结果上的open_if逻辑 - 是实际打开或创建的文件。CreateFileW
不能创建文件夹,即使是文件也是如此 - 尽管存在选项OPEN_ALWAYS
(equ 表示FILE_OPEN_IF
(,但 API 不返回信息是FILE_OPENED
或FILE_CREATED
- 它只是删除它。CreateDirectory
根本没有open_if逻辑 - 如果指定的目录已经存在,它会失败并ERROR_ALREADY_EXISTS
。所以真的NtCreateFile
在这里拥有最好的和没有模拟功能,因为它和使用过。使用但不SetKernelObjectSecurity
NtSetSecurityObject
给出相同的错误类型(NTSTATUS
(喜欢和NtCreateFile
- 如何将更多文件夹添加到c++include路径
- GetShortPathName在网络驱动器上使用中文文件夹时失败
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- 在 Windows 上,是否可以让 dll 在不使用 PATH 环境变量的情况下在另一个文件夹中查找依赖项?
- 如何在文档文件夹中创建目录
- "assimp/config.h"找不到,但它在文件夹中
- C++入门 5 版:类消息和文件夹
- 我可以在 Arduino 的库文件夹之外安装库吗?
- 如何按文件扩展名引用文件夹中的文件
- 在QTreeView中仅显示共享驱动器和文件夹
- 加载与引用 .NET DLL 位于同一文件夹中的引用的 .NET DLL 时"Not found"异常
- 如何使用Windows API C++更改已创建的文件夹/目录安全权限
- 威纳派读取自定义文件或文件夹的所有访问权限
- 如何在C#或C++中获取文件或文件夹的有效权限?有什么 API 吗?
- 如何使用 c++ 创建对"everyone"具有共享访问权限的文件夹
- 在 C++ 中为文件夹中的所有文件设置权限
- ShellExecute获取打开文件夹的访问权限
- 如何查明文件夹是否需要管理权限才能修改其内容
- 获取文件或文件夹的权限
- 如何使用C++为特定用户获取文件夹的ACL权限