对于 GetSecurityInfo 成功的注册表项,GetNamedSecurityInfo 失败

GetNamedSecurityInfo fails for registry key where GetSecurityInfo succeeds

我有一个这样的注册表项 ACL 读取请求:

PACL dacl = NULL;
PSECURITY_DESCRIPTOR secDesc = NULL;
if (GetNamedSecurityInfoW(L"HKEY_CURRENT_USER\SOFTWARE\SomeSoftware\SomeKey", SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, &dacl, NULL, &secDesc) != ERROR_SUCCESS)
{ /*... */ }

并且失败,错误 87,参数无效。但是,如果我使用

HKEY handle;
DWORD Ret = RegOpenKeyExW(HKEY_CURRENT_USER, L"SOFTWARE\SomeSoftware\SomeKey", 0, KEY_ALL_ACCESS, &handle);
if (Ret != ERROR_SUCCESS) { /* ... */ }

DWORD secDescSize = 4096;
secDesc = LocalAlloc(LMEM_FIXED, secDescSize);
Ret = (DWORD)RegGetKeySecurity(handle, DACL_SECURITY_INFORMATION, secDesc, &secDescSize);
if (Ret != ERROR_SUCCESS) { /* ... */ }

RegOpenKey()RegGetKeySecurity() 成功,运行 GetSecurityDescriptorDacl()RegGetKeySecurity() 的结果也有效。

此代码适用于 SE_FILE_OBJECT 和读取目录的 ACL。
此代码位于 Windows 10 Pro 64 位中 32 位应用程序的 32 位 DLL 中。我的目标是 XP 及更高版本,使用 Visual Studio 2019 预览版。

我在参数验证中可能遗漏了什么?

L"HKEY_CURRENT_USER\SOFTWARE\SomeSoftware\SomeKey" 不是 GetNamedSecurityInfoW() 的有效对象名称。阅读 SE_OBJECT_TYPE 文档以了解用于注册表项的正确格式:

SE_REGISTRY_KEY

Indicates a registry key. A registry key object can be in the local registry, such as CLASSES_ROOT\SomePath or in a remote registry, such as \ComputerName\CLASSES_ROOT\SomePath.

The names of registry keys must use the following literal strings to identify the predefined registry keys: "CLASSES_ROOT", "CURRENT_USER", "MACHINE", and "USERS".

试试 L"CURRENT_USER\SOFTWARE\SomeSoftware\SomeKey"