Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v3: Test all root keys.
dlls/advapi32/tests/security.c | 50 ++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 6d2d5f56f1b..da752f8c413 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -7871,6 +7871,55 @@ static void test_create_process_token_child(void) } }
+static void test_pseudo_handle_security(void) +{ + char buffer[200]; + PSECURITY_DESCRIPTOR sd = buffer, sd_ptr; + unsigned int i; + DWORD size; + BOOL ret; + + static const HKEY keys[] = + { + HKEY_CLASSES_ROOT, + HKEY_CURRENT_USER, + HKEY_LOCAL_MACHINE, + HKEY_USERS, + HKEY_PERFORMANCE_DATA, + HKEY_CURRENT_CONFIG, + HKEY_DYN_DATA, + }; + + ret = GetKernelObjectSecurity(GetCurrentProcess(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); + ok(ret, "got error %u\n", GetLastError()); + + ret = GetKernelObjectSecurity(GetCurrentThread(), OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); + ok(ret, "got error %u\n", GetLastError()); + + for (i = 0; i < ARRAY_SIZE(keys); ++i) + { + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(keys[i], OWNER_SECURITY_INFORMATION, &sd, sizeof(buffer), &size); + ok(!ret, "key %p: expected failure\n", keys[i]); + ok(GetLastError() == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], GetLastError()); + + ret = GetSecurityInfo(keys[i], SE_REGISTRY_KEY, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr); + if (keys[i] == HKEY_PERFORMANCE_DATA) + ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); + else if (keys[i] == HKEY_DYN_DATA) + todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED || broken(ret == ERROR_INVALID_HANDLE) /* <7 */, + "key %p: got error %u\n", keys[i], ret); + else + todo_wine ok(!ret, "key %p: got error %u\n", keys[i], ret); + LocalFree(sd_ptr); + + ret = GetSecurityInfo(keys[i], SE_KERNEL_OBJECT, + DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr); + ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); + } +} + START_TEST(security) { init(); @@ -7935,6 +7984,7 @@ START_TEST(security) test_BuildSecurityDescriptorW(); test_duplicate_handle_access(); test_create_process_token(); + test_pseudo_handle_security();
/* Must be the last test, modifies process token */ test_token_security_descriptor();
This fixes a message box with the ASCOM Platform installer.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v3: Use RegCreateKeyExW() instead; the "\" subkey only works with HKEY_CLASSES_ROOT.
Note that this patch does not fix HKEY_PERFORMANCE_DATA or HKEY_DYN_DATA, but those keys should fail to open and hence should be handled on a lower level.
dlls/advapi32/security.c | 31 ++++++++++++++++++++++++++++++- dlls/advapi32/tests/security.c | 4 ++-- 2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index a01791bbf0b..9f80a846966 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1467,6 +1467,9 @@ BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceNa return TRUE; }
+#define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT +#define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA + /****************************************************************************** * GetSecurityInfo [ADVAPI32.@] * @@ -1522,17 +1525,43 @@ DWORD WINAPI GetSecurityInfo( HANDLE handle, SE_OBJECT_TYPE type, SECURITY_INFOR } else { + HKEY key = NULL; + + if (type == SE_REGISTRY_KEY && (HandleToUlong(handle) >= HandleToUlong(HKEY_SPECIAL_ROOT_FIRST)) + && (HandleToUlong(handle) <= HandleToUlong(HKEY_SPECIAL_ROOT_LAST))) + { + REGSAM access = READ_CONTROL; + DWORD ret; + + if (SecurityInfo & SACL_SECURITY_INFORMATION) + access |= ACCESS_SYSTEM_SECURITY; + + if ((ret = RegCreateKeyExW( handle, NULL, 0, NULL, 0, access, NULL, &key, NULL ))) + return ret; + + handle = key; + } + status = NtQuerySecurityObject( handle, SecurityInfo, NULL, 0, &size ); if (status != STATUS_SUCCESS && status != STATUS_BUFFER_TOO_SMALL) + { + RegCloseKey( key ); return RtlNtStatusToDosError( status ); + }
- if (!(sd = LocalAlloc( 0, size ))) return ERROR_NOT_ENOUGH_MEMORY; + if (!(sd = LocalAlloc( 0, size ))) + { + RegCloseKey( key ); + return ERROR_NOT_ENOUGH_MEMORY; + }
if ((status = NtQuerySecurityObject( handle, SecurityInfo, sd, size, &size ))) { + RegCloseKey( key ); LocalFree(sd); return RtlNtStatusToDosError( status ); } + RegCloseKey( key ); }
if (ppsidOwner) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index da752f8c413..4121197f6f1 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -7906,12 +7906,12 @@ static void test_pseudo_handle_security(void) ret = GetSecurityInfo(keys[i], SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd_ptr); if (keys[i] == HKEY_PERFORMANCE_DATA) - ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); + todo_wine ok(ret == ERROR_INVALID_HANDLE, "key %p: got error %u\n", keys[i], ret); else if (keys[i] == HKEY_DYN_DATA) todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED || broken(ret == ERROR_INVALID_HANDLE) /* <7 */, "key %p: got error %u\n", keys[i], ret); else - todo_wine ok(!ret, "key %p: got error %u\n", keys[i], ret); + ok(!ret, "key %p: got error %u\n", keys[i], ret); LocalFree(sd_ptr);
ret = GetSecurityInfo(keys[i], SE_KERNEL_OBJECT,