From a0b621c3e4049ff86ad492378b9f431128ae8de5 Mon Sep 17 00:00:00 2001 From: Amine Khaldi Date: Fri, 17 Oct 2014 13:36:13 +0000 Subject: [PATCH] [ADVAPI32_WINETEST] * Sync with Wine 1.7.27. CORE-8540 svn path=/trunk/; revision=64784 --- rostests/winetests/advapi32/eventlog.c | 19 +- rostests/winetests/advapi32/registry.c | 233 ++++++++++++++++++++----- rostests/winetests/advapi32/security.c | 134 +++++++++++--- rostests/winetests/advapi32/service.c | 21 +-- 4 files changed, 312 insertions(+), 95 deletions(-) diff --git a/rostests/winetests/advapi32/eventlog.c b/rostests/winetests/advapi32/eventlog.c index a3fe44b770d..1e483482df5 100644 --- a/rostests/winetests/advapi32/eventlog.c +++ b/rostests/winetests/advapi32/eventlog.c @@ -130,7 +130,8 @@ static void test_info(void) HANDLE handle; BOOL ret; DWORD needed; - EVENTLOG_FULL_INFORMATION efi; + BYTE buffer[2 * sizeof(EVENTLOG_FULL_INFORMATION)]; + EVENTLOG_FULL_INFORMATION *efi = (void *)buffer; if (!pGetEventLogInformation) { @@ -161,26 +162,26 @@ static void test_info(void) ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); SetLastError(0xdeadbeef); - ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, NULL); + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, 0, NULL); ok(!ret, "Expected failure\n"); ok(GetLastError() == RPC_X_NULL_REF_POINTER, "Expected RPC_X_NULL_REF_POINTER, got %d\n", GetLastError()); SetLastError(0xdeadbeef); needed = 0xdeadbeef; - efi.dwFull = 0xdeadbeef; - ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, 0, &needed); + efi->dwFull = 0xdeadbeef; + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, 0, &needed); ok(!ret, "Expected failure\n"); ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); - ok(efi.dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n"); + ok(efi->dwFull == 0xdeadbeef, "Expected no change to the dwFull member\n"); /* Not that we care, but on success last error is set to ERROR_IO_PENDING */ - efi.dwFull = 0xdeadbeef; - needed *= 2; - ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, (LPVOID)&efi, needed, &needed); + efi->dwFull = 0xdeadbeef; + needed = sizeof(buffer); + ret = pGetEventLogInformation(handle, EVENTLOG_FULL_INFO, efi, needed, &needed); ok(ret, "Expected success\n"); ok(needed == sizeof(EVENTLOG_FULL_INFORMATION), "Expected sizeof(EVENTLOG_FULL_INFORMATION), got %d\n", needed); - ok(efi.dwFull == 0 || efi.dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi.dwFull); + ok(efi->dwFull == 0 || efi->dwFull == 1, "Expected 0 (not full) or 1 (full), got %d\n", efi->dwFull); CloseEventLog(handle); } diff --git a/rostests/winetests/advapi32/registry.c b/rostests/winetests/advapi32/registry.c index 56599300af7..02bfff56768 100644 --- a/rostests/winetests/advapi32/registry.c +++ b/rostests/winetests/advapi32/registry.c @@ -50,6 +50,10 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL); static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE); static NTSTATUS (WINAPI * pRtlFormatCurrentUserKeyPath)(UNICODE_STRING*); static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING); +static LONG (WINAPI *pRegDeleteKeyValueA)(HKEY,LPCSTR,LPCSTR); +static LONG (WINAPI *pRegSetKeyValueW)(HKEY,LPCWSTR,LPCWSTR,DWORD,const void*,DWORD); + +static BOOL limited_user; /* Debugging functions from wine/libs/wine/debug.c */ @@ -136,6 +140,8 @@ static void InitFunctionPtrs(void) ADVAPI32_GET_PROC(RegGetValueA); ADVAPI32_GET_PROC(RegDeleteTreeA); ADVAPI32_GET_PROC(RegDeleteKeyExA); + ADVAPI32_GET_PROC(RegDeleteKeyValueA); + ADVAPI32_GET_PROC(RegSetKeyValueW); pIsWow64Process = (void *)GetProcAddress( hkernel32, "IsWow64Process" ); pRtlFormatCurrentUserKeyPath = (void *)GetProcAddress( hntdll, "RtlFormatCurrentUserKeyPath" ); @@ -173,6 +179,26 @@ static void setup_main_key(void) assert (!RegCreateKeyA( HKEY_CURRENT_USER, "Software\\Wine\\Test", &hkey_main )); } +static void check_user_privs(void) +{ + DWORD ret; + HKEY hkey = (HKEY)0xdeadbeef; + + ret = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, KEY_READ|KEY_WRITE, &hkey); + ok(ret == ERROR_SUCCESS || ret == ERROR_ACCESS_DENIED, "expected success or access denied, got %i\n", ret); + if (ret == ERROR_SUCCESS) + { + ok(hkey != NULL, "RegOpenKeyExA succeeded but returned NULL hkey\n"); + RegCloseKey(hkey); + } + else + { + ok(hkey == NULL, "RegOpenKeyExA failed but returned hkey %p\n", hkey); + limited_user = TRUE; + trace("running as limited user\n"); + } +} + #define lok ok_(__FILE__, line) #define test_hkey_main_Value_A(name, string, full_byte_len) _test_hkey_main_Value_A(__LINE__, name, string, full_byte_len) static void _test_hkey_main_Value_A(int line, LPCSTR name, LPCSTR string, @@ -412,6 +438,37 @@ static void test_set_value(void) ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); ret = RegSetValueExW(hkey_main, name2W, 0, REG_DWORD, (const BYTE *)1, 1); ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + + /* RegSetKeyValue */ + if (!pRegSetKeyValueW) + win_skip("RegSetKeyValue() is not supported.\n"); + else + { + static const WCHAR subkeyW[] = {'s','u','b','k','e','y',0}; + DWORD len, type; + HKEY subkey; + + ret = pRegSetKeyValueW(hkey_main, NULL, name1W, REG_SZ, (const BYTE*)string2W, sizeof(string2W)); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + test_hkey_main_Value_A(name1A, string2A, sizeof(string2A)); + test_hkey_main_Value_W(name1W, string2W, sizeof(string2W)); + + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, string1W, sizeof(string1W)); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegOpenKeyExW(hkey_main, subkeyW, 0, KEY_QUERY_VALUE, &subkey); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + type = len = 0; + ret = RegQueryValueExW(subkey, name1W, 0, &type, NULL, &len); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ok(len == sizeof(string1W), "got %d\n", len); + ok(type == REG_SZ, "got type %d\n", type); + + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + RegCloseKey(subkey); + } } static void create_test_entries(void) @@ -1000,13 +1057,21 @@ static void test_reg_open_key(void) ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL); - ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + if (limited_user) + ok(ret == ERROR_ACCESS_DENIED && hkRoot32 == NULL, + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + else + ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL); - ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + if (limited_user) + ok(ret == ERROR_ACCESS_DENIED && hkRoot64 == NULL, + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + else + ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world_sid); @@ -1035,26 +1100,34 @@ static void test_reg_open_key(void) ok(bRet == TRUE, "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError()); - /* The "sanctioned" methods of setting a registry ACL aren't implemented in Wine. */ - bRet = SetKernelObjectSecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); - ok(bRet == TRUE, - "Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + if (limited_user) + { + skip("not enough privileges to modify HKLM\n"); + } + else + { + LONG error; - bRet = SetKernelObjectSecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); - ok(bRet == TRUE, - "Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError()); + error = RegSetKeySecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); + ok(error == ERROR_SUCCESS, + "Expected RegSetKeySecurity to return success, got error %u\n", error); - hkResult = NULL; - ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_64KEY | KEY_READ, &hkResult); - ok(ret == ERROR_SUCCESS && hkResult != NULL, - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); - RegCloseKey(hkResult); + bRet = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); + ok(error == ERROR_SUCCESS, + "Expected RegSetKeySecurity to return success, got error %u\n", error); - hkResult = NULL; - ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_32KEY | KEY_READ, &hkResult); - ok(ret == ERROR_SUCCESS && hkResult != NULL, - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); - RegCloseKey(hkResult); + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_64KEY | KEY_READ, &hkResult); + ok(ret == ERROR_SUCCESS && hkResult != NULL, + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + RegCloseKey(hkResult); + + hkResult = NULL; + ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, KEY_WOW64_32KEY | KEY_READ, &hkResult); + ok(ret == ERROR_SUCCESS && hkResult != NULL, + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + RegCloseKey(hkResult); + } HeapFree(GetProcessHeap(), 0, sd); LocalFree(key_acl); @@ -1146,13 +1219,21 @@ static void test_reg_create_key(void) ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &hkRoot32, NULL); - ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, - "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret); + if (limited_user) + ok(ret == ERROR_ACCESS_DENIED && hkRoot32 == NULL, + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret); + else + ok(ret == ERROR_SUCCESS && hkRoot32 != NULL, + "RegCreateKeyEx with KEY_WOW64_32KEY failed (err=%d)\n", ret); ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &hkRoot64, NULL); - ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, - "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret); + if (limited_user) + ok(ret == ERROR_ACCESS_DENIED && hkRoot64 == NULL, + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret); + else + ok(ret == ERROR_SUCCESS && hkRoot64 != NULL, + "RegCreateKeyEx with KEY_WOW64_64KEY failed (err=%d)\n", ret); bRet = AllocateAndInitializeSid(&sid_authority, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &world_sid); @@ -1169,7 +1250,7 @@ static void test_reg_create_key(void) access.Trustee.ptstrName = (char *)world_sid; dwRet = SetEntriesInAclA(1, &access, NULL, &key_acl); - ok(ret == ERROR_SUCCESS, + ok(dwRet == ERROR_SUCCESS, "Expected SetEntriesInAclA to return ERROR_SUCCESS, got %u, last error %u\n", dwRet, GetLastError()); sd = HeapAlloc(GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH); @@ -1181,28 +1262,34 @@ static void test_reg_create_key(void) ok(bRet == TRUE, "Expected SetSecurityDescriptorDacl to return TRUE, got %d, last error %u\n", bRet, GetLastError()); - /* The "sanctioned" methods of setting a registry ACL aren't implemented in Wine. */ - bRet = SetKernelObjectSecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); - ok(bRet == TRUE, - "Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError()); - - bRet = SetKernelObjectSecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); - ok(bRet == TRUE, - "Expected SetKernelObjectSecurity to return TRUE, got %d, last error %u\n", bRet, GetLastError()); - - hkey1 = NULL; - ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, - KEY_WOW64_64KEY | KEY_READ, NULL, &hkey1, NULL); - ok(ret == ERROR_SUCCESS && hkey1 != NULL, - "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); - RegCloseKey(hkey1); + if (limited_user) + { + skip("not enough privileges to modify HKLM\n"); + } + else + { + ret = RegSetKeySecurity(hkRoot64, DACL_SECURITY_INFORMATION, sd); + ok(ret == ERROR_SUCCESS, + "Expected RegSetKeySecurity to return success, got error %u\n", ret); + + ret = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); + ok(ret == ERROR_SUCCESS, + "Expected RegSetKeySecurity to return success, got error %u\n", ret); + + hkey1 = NULL; + ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_READ, NULL, &hkey1, NULL); + ok(ret == ERROR_SUCCESS && hkey1 != NULL, + "RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret); + RegCloseKey(hkey1); - hkey1 = NULL; - ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, - KEY_WOW64_32KEY | KEY_READ, NULL, &hkey1, NULL); - ok(ret == ERROR_SUCCESS && hkey1 != NULL, - "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); - RegCloseKey(hkey1); + hkey1 = NULL; + ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software\\Wine", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_READ, NULL, &hkey1, NULL); + ok(ret == ERROR_SUCCESS && hkey1 != NULL, + "RegOpenKeyEx with KEY_WOW64_32KEY failed (err=%u)\n", ret); + RegCloseKey(hkey1); + } HeapFree(GetProcessHeap(), 0, sd); LocalFree(key_acl); @@ -2719,12 +2806,63 @@ static void test_delete_value(void) "expect ERROR_FILE_NOT_FOUND, got %i\n", res); } +static void test_delete_key_value(void) +{ + HKEY subkey; + LONG ret; + + if (!pRegDeleteKeyValueA) + { + win_skip("RegDeleteKeyValue is not available.\n"); + return; + } + + ret = pRegDeleteKeyValueA(NULL, NULL, NULL); + ok(ret == ERROR_INVALID_HANDLE, "got %d\n", ret); + + ret = pRegDeleteKeyValueA(hkey_main, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + ret = RegSetValueExA(hkey_main, "test", 0, REG_SZ, (const BYTE*)"value", 6); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + /* NULL subkey name means delete from open key */ + ret = pRegDeleteKeyValueA(hkey_main, NULL, "test"); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(hkey_main, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + /* now with real subkey */ + ret = RegCreateKeyExA(hkey_main, "Subkey1", 0, NULL, 0, KEY_WRITE|KEY_READ, NULL, &subkey, NULL); + ok(!ret, "failed with error %d\n", ret); + + ret = RegSetValueExA(subkey, "test", 0, REG_SZ, (const BYTE*)"value", 6); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = pRegDeleteKeyValueA(hkey_main, "Subkey1", "test"); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegQueryValueExA(subkey, "test", NULL, NULL, NULL, NULL); + ok(ret == ERROR_FILE_NOT_FOUND, "got %d\n", ret); + + RegDeleteKeyA(subkey, ""); + RegCloseKey(subkey); +} + START_TEST(registry) { /* Load pointers for functions that are not available in all Windows versions */ InitFunctionPtrs(); setup_main_key(); + check_user_privs(); test_set_value(); create_test_entries(); test_enum_value(); @@ -2758,6 +2896,7 @@ START_TEST(registry) test_rw_order(); test_deleted_key(); test_delete_value(); + test_delete_key_value(); /* cleanup */ delete_key( hkey_main ); diff --git a/rostests/winetests/advapi32/security.c b/rostests/winetests/advapi32/security.c index 4485746789f..1336da0c240 100644 --- a/rostests/winetests/advapi32/security.c +++ b/rostests/winetests/advapi32/security.c @@ -211,6 +211,68 @@ static void init(void) myARGC = winetest_get_mainargs( &myARGV ); } +static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line) +{ + /* use HeapFree(GetProcessHeap(), 0, sd); when done */ + DWORD ret, length, needed; + SECURITY_DESCRIPTOR *sd; + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + NULL, 0, &needed); + ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n"); + ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); + ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n"); + + length = needed; + sd = HeapAlloc(GetProcessHeap(), 0, length); + + needed = 0xdeadbeef; + SetLastError(0xdeadbeef); + ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, + sd, length, &needed); + ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError()); + ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed); + return sd; +} + +static void test_owner_equal(HANDLE Handle, PSID expected, int line) +{ + BOOL res; + SECURITY_DESCRIPTOR *queriedSD = NULL; + PSID owner; + BOOL owner_defaulted; + + queriedSD = test_get_security_descriptor( Handle, line ); + + res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted); + ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + + ok_(__FILE__, line)(EqualSid(owner, expected), "Owner SIDs are not equal\n"); + ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n"); + + HeapFree(GetProcessHeap(), 0, queriedSD); +} + +static void test_group_equal(HANDLE Handle, PSID expected, int line) +{ + BOOL res; + SECURITY_DESCRIPTOR *queriedSD = NULL; + PSID group; + BOOL group_defaulted; + + queriedSD = test_get_security_descriptor( Handle, line ); + + res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); + ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + + ok_(__FILE__, line)(EqualSid(group, expected), "Group SIDs are not equal\n"); + ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n"); + + HeapFree(GetProcessHeap(), 0, queriedSD); +} + static void test_sid(void) { struct sidRef refs[] = { @@ -2481,6 +2543,8 @@ static void test_process_security(void) SECURITY_ATTRIBUTES psa; HANDLE token, event; DWORD size; + SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; + PSID EveryoneSid = NULL; Acl = HeapAlloc(GetProcessHeap(), 0, 256); res = InitializeAcl(Acl, 256, ACL_REVISION); @@ -2492,6 +2556,9 @@ static void test_process_security(void) } ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid); + ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError()); + /* get owner from the token we might be running as a user not admin */ res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token ); ok(res, "OpenProcessToken failed with error %d\n", GetLastError()); @@ -2550,7 +2617,7 @@ static void test_process_security(void) CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR ); CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED ); CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); - /* NULL DACL is valid and means default DACL from token */ + /* NULL DACL is valid and means that everyone has access */ SecurityDescriptor->Control |= SE_DACL_PRESENT; CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); @@ -2558,12 +2625,31 @@ static void test_process_security(void) res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE); ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS ); + test_owner_equal( event, AdminSid, __LINE__ ); + + res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE); + ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); + test_group_equal( event, EveryoneSid, __LINE__ ); + + res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); + ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); + /* setting a dacl should not change the owner or group */ + test_owner_equal( event, AdminSid, __LINE__ ); + test_group_equal( event, EveryoneSid, __LINE__ ); + + /* Test again with a different SID in case the previous SID also happens to + * be the one that is incorrectly replacing the group. */ res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE); ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS ); + test_group_equal( event, UsersSid, __LINE__ ); + res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE); ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS ); + test_group_equal( event, UsersSid, __LINE__ ); sprintf(buffer, "%s tests/security.c test", myARGV[0]); memset(&startup, 0, sizeof(startup)); @@ -2582,6 +2668,7 @@ static void test_process_security(void) STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); winetest_wait_child_process( info.hProcess ); + FreeSid(EveryoneSid); CloseHandle( info.hProcess ); CloseHandle( info.hThread ); CloseHandle( event ); @@ -3127,6 +3214,7 @@ static void test_CreateDirectoryA(void) ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); } + LocalFree(pSD); done: HeapFree(GetProcessHeap(), 0, user); @@ -3234,10 +3322,12 @@ static void test_GetNamedSecurityInfoA(void) NULL, NULL, NULL, NULL, NULL); ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error); + pDacl = NULL; error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION, - NULL, NULL, &pDacl, NULL, NULL); + NULL, NULL, &pDacl, NULL, &pSD); ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); ok(pDacl != NULL, "DACL should not be NULL\n"); + LocalFree(pSD); error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION, NULL, NULL, &pDacl, NULL, NULL); @@ -3953,7 +4043,7 @@ static void test_GetSecurityInfo(void) NULL, NULL, pDacl, NULL); ok(ret == ERROR_SUCCESS, "SetSecurityInfo returned %d\n", ret); ret = pGetSecurityInfo(obj, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, - NULL, NULL, &pDacl, NULL, NULL); + NULL, NULL, &pDacl, NULL, &pSD); ok(ret == ERROR_SUCCESS, "GetSecurityInfo returned %d\n", ret); ok(pDacl && IsValidAcl(pDacl), "GetSecurityInfo returned invalid DACL.\n"); bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); @@ -3980,6 +4070,7 @@ static void test_GetSecurityInfo(void) ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); } + LocalFree(pSD); CloseHandle(obj); } @@ -4431,29 +4522,12 @@ todo_wine static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping) { - DWORD ret, length, needed, granted, priv_set_len; + DWORD ret, granted, priv_set_len; BOOL status; PRIVILEGE_SET priv_set; SECURITY_DESCRIPTOR *sd; - needed = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - NULL, 0, &needed); - ok(!ret, "GetKernelObjectSecurity should fail\n"); - ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError()); - ok(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n"); - - length = needed; - sd = HeapAlloc(GetProcessHeap(), 0, length); - - needed = 0xdeadbeef; - SetLastError(0xdeadbeef); - ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, - sd, length, &needed); - ok(ret, "GetKernelObjectSecurity error %d\n", GetLastError()); - ok(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed); - + sd = test_get_security_descriptor(handle, __LINE__); validate_default_security_descriptor(sd); priv_set_len = sizeof(priv_set); @@ -5072,12 +5146,16 @@ static void test_thread_security(void) { case GENERIC_READ: case GENERIC_EXECUTE: - ok(access == map[i].mapped || access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */, + ok(access == map[i].mapped || + access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION) /* Vista+ */ || + access == (map[i].mapped | THREAD_QUERY_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); break; case GENERIC_WRITE: todo_wine - ok(access == map[i].mapped || access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */, + ok(access == map[i].mapped || + access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION) /* Vista+ */ || + access == (map[i].mapped | THREAD_SET_LIMITED_INFORMATION | THREAD_RESUME) /* win8 */, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); break; case GENERIC_ALL: @@ -5143,7 +5221,9 @@ static void test_process_access(void) "%d: expected %#x, got %#x\n", i, map[i].mapped, access); break; case GENERIC_WRITE: - ok(access == map[i].mapped || access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */, + ok(access == map[i].mapped || + access == (map[i].mapped | PROCESS_TERMINATE) /* before Vista */ || + access == (map[i].mapped | PROCESS_SET_LIMITED_INFORMATION) /* win8 */, "%d: expected %#x, got %#x\n", i, map[i].mapped, access); break; case GENERIC_EXECUTE: @@ -5334,7 +5414,7 @@ static void test_default_dacl_owner_sid(void) ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted ); ok( ret, "error %u\n", GetLastError() ); ok( owner != (void *)0xdeadbeef, "owner not set\n" ); - todo_wine ok( !defaulted, "owner defaulted\n" ); + ok( !defaulted, "owner defaulted\n" ); dacl = (void *)0xdeadbeef; present = FALSE; @@ -5343,7 +5423,7 @@ static void test_default_dacl_owner_sid(void) ok( ret, "error %u\n", GetLastError() ); ok( present, "dacl not present\n" ); ok( dacl != (void *)0xdeadbeef, "dacl not set\n" ); - todo_wine ok( !defaulted, "dacl defaulted\n" ); + ok( !defaulted, "dacl defaulted\n" ); index = 0; found = FALSE; diff --git a/rostests/winetests/advapi32/service.c b/rostests/winetests/advapi32/service.c index 603e5085e60..262b823d5b8 100644 --- a/rostests/winetests/advapi32/service.c +++ b/rostests/winetests/advapi32/service.c @@ -139,6 +139,7 @@ static void test_open_svc(void) ok(GetLastError() == ERROR_INVALID_ADDRESS /* W2K, XP, W2K3, Vista */ || GetLastError() == ERROR_INVALID_PARAMETER /* NT4 */, "Expected ERROR_INVALID_ADDRESS or ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); + CloseServiceHandle(scm_handle); /* Nonexistent service */ scm_handle = OpenSCManagerA(NULL, NULL, SC_MANAGER_CONNECT); @@ -189,7 +190,7 @@ static void test_open_svc(void) static void test_create_delete_svc(void) { - SC_HANDLE scm_handle, svc_handle1; + SC_HANDLE scm_handle, svc_handle1, svc_handle2; CHAR username[UNLEN + 1], domain[MAX_PATH]; DWORD user_size = UNLEN + 1; CHAR account[UNLEN + 3]; @@ -414,6 +415,11 @@ static void test_create_delete_svc(void) ret = DeleteService(svc_handle1); ok(ret, "Expected success, got error %u\n", GetLastError()); + /* Service is marked for delete, but handle is still open. Try to open service again. */ + svc_handle2 = OpenServiceA(scm_handle, servicename, GENERIC_READ); + ok(svc_handle2 != NULL, "got %p, error %u\n", svc_handle2, GetLastError()); + CloseServiceHandle(svc_handle2); + CloseServiceHandle(svc_handle1); CloseServiceHandle(scm_handle); @@ -1843,8 +1849,9 @@ static void test_sequence(void) if (!is_nt4) { retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, - NULL, &dacl, NULL, NULL); + NULL, &dacl, NULL, &pSD); ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval); + LocalFree(pSD); SetLastError(0xdeadbeef); retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, NULL); @@ -2348,19 +2355,9 @@ static void test_refcount(void) svc_handle5 = CreateServiceA(scm_handle, servicename, NULL, GENERIC_ALL, SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS, SERVICE_DISABLED, 0, pathname, NULL, NULL, NULL, NULL, NULL); - todo_wine - { ok(!svc_handle5, "Expected failure\n"); ok(GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE, "Expected ERROR_SERVICE_MARKED_FOR_DELETE, got %d\n", GetLastError()); - } - - /* FIXME: Remove this when Wine is fixed */ - if (svc_handle5) - { - DeleteService(svc_handle5); - CloseServiceHandle(svc_handle5); - } /* Close all the handles to the service and try again */ ret = CloseServiceHandle(svc_handle4); -- 2.17.1