diff --git a/rostests/winetests/advapi32/CMakeLists.txt b/rostests/winetests/advapi32/CMakeLists.txt index 333048659ba..95f3d7cfab0 100644 --- a/rostests/winetests/advapi32/CMakeLists.txt +++ b/rostests/winetests/advapi32/CMakeLists.txt @@ -14,6 +14,11 @@ list(APPEND SOURCE testlist.c) add_executable(advapi32_winetest ${SOURCE}) + +if(NOT MSVC) + add_target_compile_flags(advapi32_winetest "-Wno-format") +endif() + set_module_type(advapi32_winetest win32cui) add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32) add_cd_file(TARGET advapi32_winetest DESTINATION reactos/bin FOR all) diff --git a/rostests/winetests/advapi32/registry.c b/rostests/winetests/advapi32/registry.c index 02bfff56768..9e3c3113eb0 100644 --- a/rostests/winetests/advapi32/registry.c +++ b/rostests/winetests/advapi32/registry.c @@ -439,6 +439,21 @@ static void test_set_value(void) 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()); + if (pRegGetValueA) /* avoid a crash on Windows 2000 */ + { + ret = RegSetValueExW(hkey_main, NULL, 0, REG_SZ, NULL, 4); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + + ret = RegSetValueExW(hkey_main, NULL, 0, REG_SZ, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + + ret = RegSetValueExW(hkey_main, NULL, 0, REG_DWORD, NULL, 4); + ok(ret == ERROR_NOACCESS, "RegSetValueExW should have failed with ERROR_NOACCESS: %d, GLE=%d\n", ret, GetLastError()); + + ret = RegSetValueExW(hkey_main, NULL, 0, REG_DWORD, NULL, 0); + ok(ret == ERROR_SUCCESS, "got %d\n", ret); + } + /* RegSetKeyValue */ if (!pRegSetKeyValueW) win_skip("RegSetKeyValue() is not supported.\n"); @@ -467,6 +482,12 @@ static void test_set_value(void) ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 0); ok(ret == ERROR_SUCCESS, "got %d\n", ret); + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_SZ, NULL, 4); + ok(ret == ERROR_NOACCESS, "got %d\n", ret); + + ret = pRegSetKeyValueW(hkey_main, subkeyW, name1W, REG_DWORD, NULL, 4); + ok(ret == ERROR_NOACCESS, "got %d\n", ret); + RegCloseKey(subkey); } } @@ -520,6 +541,33 @@ static void test_enum_value(void) res = RegSetValueExA( test_key, "Test", 0, REG_BINARY, NULL, 0 ); ok( ERROR_SUCCESS == res || ERROR_INVALID_PARAMETER == res, "RegSetValueExA returned %d\n", res ); + /* test reading the value and data without setting them */ + val_count = 20; + data_count = 20; + type = 1234; + strcpy( value, "xxxxxxxxxx" ); + strcpy( data, "xxxxxxxxxx" ); + res = RegEnumValueA( test_key, 0, value, &val_count, NULL, &type, (LPBYTE)data, &data_count ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); + ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); + ok( data_count == 0, "data_count set to %d instead of 0\n", data_count ); + ok( type == REG_BINARY, "type %d is not REG_BINARY\n", type ); + ok( !strcmp( value, "Test" ), "value is '%s' instead of Test\n", value ); + ok( !strcmp( data, "xxxxxxxxxx" ), "data is '%s' instead of xxxxxxxxxx\n", data ); + + val_count = 20; + data_count = 20; + type = 1234; + memcpy( valueW, xxxW, sizeof(xxxW) ); + memcpy( dataW, xxxW, sizeof(xxxW) ); + res = RegEnumValueW( test_key, 0, valueW, &val_count, NULL, &type, (BYTE*)dataW, &data_count ); + ok( res == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", res ); + ok( val_count == 4, "val_count set to %d instead of 4\n", val_count ); + ok( data_count == 0, "data_count set to %d instead of 0\n", data_count ); + ok( type == REG_BINARY, "type %d is not REG_BINARY\n", type ); + ok( !memcmp( valueW, testW, sizeof(testW) ), "value is not 'Test'\n" ); + ok( !memcmp( dataW, xxxW, sizeof(xxxW) ), "data is not 'xxxxxxxxxx'\n" ); + res = RegSetValueExA( test_key, "Test", 0, REG_SZ, (const BYTE *)"foobar", 7 ); ok( res == 0, "RegSetValueExA failed error %d\n", res ); @@ -929,6 +977,11 @@ static void test_reg_open_key(void) ok(hkResult != NULL, "hkResult != NULL\n"); RegCloseKey(hkResult); + /* trailing slashes */ + ret = RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test\\\\", &hkResult); + ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret); + RegCloseKey(hkResult); + /* open nonexistent key * check that hkResult is set to NULL */ @@ -1112,7 +1165,7 @@ static void test_reg_open_key(void) ok(error == ERROR_SUCCESS, "Expected RegSetKeySecurity to return success, got error %u\n", error); - bRet = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); + error = RegSetKeySecurity(hkRoot32, DACL_SECURITY_INFORMATION, sd); ok(error == ERROR_SUCCESS, "Expected RegSetKeySecurity to return success, got error %u\n", error); @@ -1190,10 +1243,16 @@ static void test_reg_create_key(void) ok(ret == ERROR_BAD_PATHNAME, "expected ERROR_BAD_PATHNAME, got %d\n", ret); else { ok(!ret, "RegCreateKeyExA failed with error %d\n", ret); - RegDeleteKeyA(hkey1, NULL); + RegDeleteKeyA(hkey1, ""); RegCloseKey(hkey1); } + /* trailing backslash characters */ + ret = RegCreateKeyExA(hkey_main, "Subkey4\\\\", 0, NULL, 0, KEY_NOTIFY, NULL, &hkey1, NULL); + ok(ret == ERROR_SUCCESS, "RegCreateKeyExA failed with error %d\n", ret); + RegDeleteKeyA(hkey1, ""); + RegCloseKey(hkey1); + /* WOW64 flags - open an existing key */ hkey1 = NULL; ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, KEY_READ|KEY_WOW64_32KEY, NULL, &hkey1, NULL); @@ -1337,6 +1396,7 @@ static void test_reg_close_key(void) static void test_reg_delete_key(void) { DWORD ret; + HKEY key; ret = RegDeleteKeyA(hkey_main, NULL); @@ -1355,6 +1415,15 @@ static void test_reg_delete_key(void) ret == ERROR_ACCESS_DENIED || ret == ERROR_BADKEY, /* Win95 */ "ret=%d\n", ret); + + ret = RegCreateKeyA(hkey_main, "deleteme", &key); + ok(ret == ERROR_SUCCESS, "Could not create key, got %d\n", ret); + ret = RegDeleteKeyA(key, ""); + ok(ret == ERROR_SUCCESS, "RegDeleteKeyA failed, got %d\n", ret); + RegCloseKey(key); + ret = RegOpenKeyA(hkey_main, "deleteme", &key); + ok(ret == ERROR_FILE_NOT_FOUND, "Key was not deleted, got %d\n", ret); + RegCloseKey(key); } static void test_reg_save_key(void) @@ -1522,7 +1591,7 @@ static void test_reg_query_value(void) ret = RegQueryValueA(hkey_main, "subkey", val, NULL); ok(ret == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); - ok(lstrlenA(val) == 0, "Expected val to be untouched, got %s\n", val); + ok(!val[0], "Expected val to be untouched, got %s\n", val); /* try a NULL value and size */ ret = RegQueryValueA(hkey_main, "subkey", NULL, NULL); @@ -1535,7 +1604,7 @@ static void test_reg_query_value(void) ret = RegQueryValueA(hkey_main, "subkey", val, &size); ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); - ok(lstrlenA(val) == 0, "Expected val to be untouched, got %s\n", val); + ok(!val[0], "Expected val to be untouched, got %s\n", val); ok(size == 5, "Expected 5, got %d\n", size); /* successfully read the value using 'subkey' */ @@ -1564,7 +1633,7 @@ static void test_reg_query_value(void) } ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); - ok(lstrlenW(valW) == 0, "Expected valW to be untouched\n"); + ok(!valW[0], "Expected valW to be untouched\n"); ok(size == sizeof(expected), "Got wrong size: %d\n", size); /* unicode - try size in WCHARS */ @@ -1573,7 +1642,7 @@ static void test_reg_query_value(void) ret = RegQueryValueW(subkey, NULL, valW, &size); ok(ret == ERROR_MORE_DATA, "Expected ERROR_MORE_DATA, got %d\n", ret); ok(GetLastError() == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", GetLastError()); - ok(lstrlenW(valW) == 0, "Expected valW to be untouched\n"); + ok(!valW[0], "Expected valW to be untouched\n"); ok(size == sizeof(expected), "Got wrong size: %d\n", size); /* unicode - successfully read the value */ @@ -1740,8 +1809,7 @@ static void test_reg_delete_tree(void) ret = RegQueryValueA(subkey, NULL, buffer, &size); ok(ret == ERROR_SUCCESS, "Default value of subkey is not present\n"); - ok(!lstrlenA(buffer), - "Expected length 0 got length %u(%s)\n", lstrlenA(buffer), buffer); + ok(!buffer[0], "Expected length 0 got length %u(%s)\n", lstrlenA(buffer), buffer); size = MAX_PATH; ok(RegQueryValueA(subkey, "value", buffer, &size), "Value is still present\n"); @@ -2062,6 +2130,27 @@ static void test_redirection(void) check_key_value( key, "Wow6432Node\\Wine\\Winetest", KEY_WOW64_32KEY, is_vista ? 32 : 0 ); RegCloseKey( key ); } + else + { + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, + KEY_WOW64_64KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + check_key_value( key, "Wine\\Winetest", 0, 64 ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY, 64 ); + dw = get_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY ); + todo_wine ok( dw == 32, "wrong value %u\n", dw ); + check_key_value( key, "Wow6432Node\\Wine\\Winetest", 0, 32 ); + RegCloseKey( key ); + + err = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software", 0, NULL, 0, + KEY_WOW64_32KEY | KEY_ALL_ACCESS, NULL, &key, NULL ); + ok( err == ERROR_SUCCESS, "RegCreateKeyExA failed: %u\n", err ); + check_key_value( key, "Wine\\Winetest", 0, 32 ); + dw = get_key_value( key, "Wine\\Winetest", KEY_WOW64_64KEY ); + ok( dw == 32 || broken(dw == 64) /* vista */, "wrong value %u\n", dw ); + check_key_value( key, "Wine\\Winetest", KEY_WOW64_32KEY, 32 ); + RegCloseKey( key ); + } check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wine\\Winetest", 0, ptr_size ); check_key_value( HKEY_LOCAL_MACHINE, "Software\\Wow6432Node\\Wine\\Winetest", 0, 32 ); diff --git a/rostests/winetests/advapi32/security.c b/rostests/winetests/advapi32/security.c index 1336da0c240..f5c58dd63b0 100644 --- a/rostests/winetests/advapi32/security.c +++ b/rostests/winetests/advapi32/security.c @@ -923,7 +923,6 @@ cleanup: rc &= ~(FILE_ATTRIBUTE_NOT_CONTENT_INDEXED|FILE_ATTRIBUTE_COMPRESSED); ok(rc == FILE_ATTRIBUTE_ARCHIVE, "expected FILE_ATTRIBUTE_ARCHIVE got %#x\n", rc); - retSize = 0xdeadbeef; rc = GetFileSecurityA(file, OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &sdSize); ok(!rc, "GetFileSecurity should fail\n"); @@ -2535,12 +2534,12 @@ static void test_process_security(void) PTOKEN_OWNER owner; PTOKEN_PRIMARY_GROUP group; PSID AdminSid = NULL, UsersSid = NULL; - PACL Acl = NULL; - SECURITY_DESCRIPTOR *SecurityDescriptor = NULL; + PACL Acl = NULL, ThreadAcl = NULL; + SECURITY_DESCRIPTOR *SecurityDescriptor = NULL, *ThreadSecurityDescriptor = NULL; char buffer[MAX_PATH]; PROCESS_INFORMATION info; STARTUPINFOA startup; - SECURITY_ATTRIBUTES psa; + SECURITY_ATTRIBUTES psa, tsa; HANDLE token, event; DWORD size; SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY }; @@ -2661,11 +2660,36 @@ static void test_process_security(void) psa.lpSecurityDescriptor = SecurityDescriptor; psa.bInheritHandle = TRUE; + ThreadSecurityDescriptor = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH ); + res = InitializeSecurityDescriptor( ThreadSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); + ok(res, "InitializeSecurityDescriptor failed with error %d\n", GetLastError()); + + ThreadAcl = HeapAlloc( GetProcessHeap(), 0, 256 ); + res = InitializeAcl( ThreadAcl, 256, ACL_REVISION ); + ok(res, "InitializeAcl failed with error %d\n", GetLastError()); + res = AddAccessDeniedAce( ThreadAcl, ACL_REVISION, THREAD_SET_THREAD_TOKEN, AdminSid ); + ok(res, "AddAccessDeniedAce failed with error %d\n", GetLastError() ); + res = AddAccessAllowedAce( ThreadAcl, ACL_REVISION, THREAD_ALL_ACCESS, AdminSid ); + ok(res, "AddAccessAllowedAce failed with error %d\n", GetLastError()); + + res = SetSecurityDescriptorOwner( ThreadSecurityDescriptor, AdminSid, FALSE ); + ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + res = SetSecurityDescriptorGroup( ThreadSecurityDescriptor, UsersSid, FALSE ); + ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + res = SetSecurityDescriptorDacl( ThreadSecurityDescriptor, TRUE, ThreadAcl, FALSE ); + ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + + tsa.nLength = sizeof(tsa); + tsa.lpSecurityDescriptor = ThreadSecurityDescriptor; + tsa.bInheritHandle = TRUE; + /* Doesn't matter what ACL say we should get full access for ourselves */ - res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info ); + res = CreateProcessA( NULL, buffer, &psa, &tsa, FALSE, 0, NULL, NULL, &startup, &info ); ok(res, "CreateProcess with err:%d\n", GetLastError()); TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4, STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); + TEST_GRANTED_ACCESS2( info.hThread, THREAD_ALL_ACCESS_NT4, + STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL ); winetest_wait_child_process( info.hProcess ); FreeSid(EveryoneSid); @@ -2676,6 +2700,8 @@ static void test_process_security(void) HeapFree(GetProcessHeap(), 0, owner); HeapFree(GetProcessHeap(), 0, Acl); HeapFree(GetProcessHeap(), 0, SecurityDescriptor); + HeapFree(GetProcessHeap(), 0, ThreadAcl); + HeapFree(GetProcessHeap(), 0, ThreadSecurityDescriptor); } static void test_process_security_child(void) @@ -2699,7 +2725,6 @@ static void test_process_security_child(void) ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle1, PROCESS_ALL_ACCESS, TRUE, 0 ); err = GetLastError(); - todo_wine ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed " "with STATUS_ACCESS_DENIED, instead of err:%d\n", err); @@ -2707,10 +2732,8 @@ static void test_process_security_child(void) /* These two should fail - they are denied by ACL */ handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() ); - todo_wine ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n"); handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() ); - todo_wine ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n"); /* Documented privilege elevation */ @@ -2734,6 +2757,15 @@ static void test_process_security_child(void) TEST_GRANTED_ACCESS( handle1, PROCESS_VM_READ ); CloseHandle( handle1 ); CloseHandle( handle ); + + /* Test thread security */ + handle = OpenThread( THREAD_TERMINATE, FALSE, GetCurrentThreadId() ); + ok(handle != NULL, "OpenThread(THREAD_TERMINATE) with err:%d\n", GetLastError()); + TEST_GRANTED_ACCESS( handle, PROCESS_TERMINATE ); + CloseHandle( handle ); + + handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); + ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); } static void test_impersonation_level(void) @@ -3120,10 +3152,11 @@ static void test_CreateDirectoryA(void) ACL_SIZE_INFORMATION acl_size; ACCESS_ALLOWED_ACE *ace; SECURITY_ATTRIBUTES sa; + char tmpfile[MAX_PATH]; char tmpdir[MAX_PATH]; + HANDLE token, hTemp; struct _SID *owner; BOOL bret = TRUE; - HANDLE token; DWORD error; PACL pDacl; @@ -3195,10 +3228,10 @@ static void test_CreateDirectoryA(void) bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - todo_wine ok(bret, "Current User ACE != Current User SID.\n"); - todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE), - "Current User ACE has unexpected flags (0x%x != 0x03)\n", - ((ACE_HEADER *)ace)->AceFlags); + ok(bret, "Current User ACE != Current User SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE), + "Current User ACE has unexpected flags (0x%x != 0x03)\n", + ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); } @@ -3207,15 +3240,52 @@ static void test_CreateDirectoryA(void) bret = pGetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); - todo_wine ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE), - "Administators Group ACE has unexpected flags (0x%x != 0x03)\n", - ((ACE_HEADER *)ace)->AceFlags); + ok(bret, "Administators Group ACE != Administators Group SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE), + "Administators Group ACE has unexpected flags (0x%x != 0x03)\n", + ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); } LocalFree(pSD); + /* Test inheritance of ACLs */ + strcpy(tmpfile, tmpdir); + lstrcatA(tmpfile, "/tmpfile"); + hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, + FILE_FLAG_DELETE_ON_CLOSE, NULL); + error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, (PSID*)&owner, + NULL, &pDacl, NULL, &pSD); + ok(error == ERROR_SUCCESS, "Failed to get permissions on file.\n"); + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + ok(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2).\n", + acl_size.AceCount); + if (acl_size.AceCount > 0) + { + bret = pGetAce(pDacl, 0, (VOID **)&ace); + ok(bret, "Inherited Failed to get Current User ACE.\n"); + bret = EqualSid(&ace->SidStart, user_sid); + ok(bret, "Inherited Current User ACE != Current User SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE, + "Inherited Current User ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags); + ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", + ace->Mask); + } + if (acl_size.AceCount > 1) + { + bret = pGetAce(pDacl, 1, (VOID **)&ace); + ok(bret, "Inherited Failed to get Administators Group ACE.\n"); + bret = EqualSid(&ace->SidStart, admin_sid); + ok(bret, "Inherited Administators Group ACE != Administators Group SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == INHERITED_ACE, + "Inherited Administators Group ACE has unexpected flags (0x%x != 0x10)\n", ((ACE_HEADER *)ace)->AceFlags); + ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", + ace->Mask); + } + CloseHandle(hTemp); + done: HeapFree(GetProcessHeap(), 0, user); bret = RemoveDirectoryA(tmpdir); @@ -3387,7 +3457,7 @@ static void test_GetNamedSecurityInfoA(void) bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - todo_wine ok(bret, "Current User ACE != Current User SID.\n"); + ok(bret, "Current User ACE != Current User SID.\n"); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -3398,8 +3468,75 @@ static void test_GetNamedSecurityInfoA(void) bret = pGetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - todo_wine ok(bret || broken(!bret) /* win2k */, - "Administators Group ACE != Administators Group SID.\n"); + ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); + ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, + "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask); + } + LocalFree(pSD); + CloseHandle(hTemp); + + /* Create security descriptor with no inheritance and test that it comes back the same */ + pSD = &sd; + pDacl = HeapAlloc(GetProcessHeap(), 0, 100); + InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION); + pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size); + bret = InitializeAcl(pDacl, 100, ACL_REVISION); + ok(bret, "Failed to initialize ACL.\n"); + bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid); + ok(bret, "Failed to add Current User to ACL.\n"); + bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid); + ok(bret, "Failed to add Administrator Group to ACL.\n"); + bret = SetSecurityDescriptorDacl(pSD, TRUE, pDacl, FALSE); + ok(bret, "Failed to add ACL to security desciptor.\n"); + GetTempFileNameA(".", "foo", 0, tmpfile); + hTemp = CreateFileA(tmpfile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, + FILE_FLAG_DELETE_ON_CLOSE, NULL); + SetLastError(0xdeadbeef); + error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, + DACL_SECURITY_INFORMATION|PROTECTED_DACL_SECURITY_INFORMATION, + NULL, NULL, pDacl, NULL); + HeapFree(GetProcessHeap(), 0, pDacl); + if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) + { + win_skip("SetNamedSecurityInfoA is not implemented\n"); + HeapFree(GetProcessHeap(), 0, user); + CloseHandle(hTemp); + return; + } + ok(!error, "SetNamedSecurityInfoA failed with error %d\n", error); + SetLastError(0xdeadbeef); + error = pGetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, + NULL, NULL, &pDacl, NULL, &pSD); + if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)) + { + win_skip("GetNamedSecurityInfoA is not implemented\n"); + HeapFree(GetProcessHeap(), 0, user); + CloseHandle(hTemp); + return; + } + ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + if (acl_size.AceCount > 0) + { + bret = pGetAce(pDacl, 0, (VOID **)&ace); + ok(bret, "Failed to get Current User ACE.\n"); + bret = EqualSid(&ace->SidStart, user_sid); + ok(bret, "Current User ACE != Current User SID.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == 0, + "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); + ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", + ace->Mask); + } + if (acl_size.AceCount > 1) + { + bret = pGetAce(pDacl, 1, (VOID **)&ace); + ok(bret, "Failed to get Administators Group ACE.\n"); + bret = EqualSid(&ace->SidStart, admin_sid); + ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n"); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff || broken(ace->Mask == GENERIC_ALL) /* win2k */, @@ -3943,11 +4080,17 @@ static void test_acls(void) static void test_GetSecurityInfo(void) { + char domain_users_ptr[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; char b[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES]; char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100]; + PSID domain_users_sid = (PSID) domain_users_ptr, domain_sid; + SID_IDENTIFIER_AUTHORITY sia = { SECURITY_NT_AUTHORITY }; + int domain_users_ace_id = -1, admins_ace_id = -1, i; DWORD sid_size = sizeof(admin_ptr), l = sizeof(b); PSID admin_sid = (PSID) admin_ptr, user_sid; char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; + BOOL owner_defaulted, group_defaulted; + BOOL dacl_defaulted, dacl_present; ACL_SIZE_INFORMATION acl_size; PSECURITY_DESCRIPTOR pSD; ACCESS_ALLOWED_ACE *ace; @@ -3955,6 +4098,7 @@ static void test_GetSecurityInfo(void) PSID owner, group; BOOL bret = TRUE; PACL pDacl; + BYTE flags; DWORD ret; if (!pGetSecurityInfo || !pSetSecurityInfo) @@ -4053,7 +4197,7 @@ static void test_GetSecurityInfo(void) bret = pGetAce(pDacl, 0, (VOID **)&ace); ok(bret, "Failed to get Current User ACE.\n"); bret = EqualSid(&ace->SidStart, user_sid); - todo_wine ok(bret, "Current User ACE != Current User SID.\n"); + ok(bret, "Current User ACE != Current User SID.\n"); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Current User ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -4064,7 +4208,7 @@ static void test_GetSecurityInfo(void) bret = pGetAce(pDacl, 1, (VOID **)&ace); ok(bret, "Failed to get Administators Group ACE.\n"); bret = EqualSid(&ace->SidStart, admin_sid); - todo_wine ok(bret, "Administators Group ACE != Administators Group SID.\n"); + ok(bret, "Administators Group ACE != Administators Group SID.\n"); ok(((ACE_HEADER *)ace)->AceFlags == 0, "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags); ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", @@ -4072,6 +4216,84 @@ static void test_GetSecurityInfo(void) } LocalFree(pSD); CloseHandle(obj); + + /* Obtain the "domain users" SID from the user SID */ + if (!AllocateAndInitializeSid(&sia, 4, *GetSidSubAuthority(user_sid, 0), + *GetSidSubAuthority(user_sid, 1), + *GetSidSubAuthority(user_sid, 2), + *GetSidSubAuthority(user_sid, 3), 0, 0, 0, 0, &domain_sid)) + { + win_skip("Failed to get current domain SID\n"); + return; + } + sid_size = sizeof(domain_users_ptr); + pCreateWellKnownSid(WinAccountDomainUsersSid, domain_sid, domain_users_sid, &sid_size); + FreeSid(domain_sid); + + /* Test querying the ownership of a process */ + ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, + OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &pSD); + ok(!ret, "GetNamedSecurityInfo failed with error %d\n", ret); + + bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted); + ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(owner != NULL, "owner should not be NULL\n"); + ok(EqualSid(owner, admin_sid) || EqualSid(owner, user_sid), + "Process owner SID != Administrators SID.\n"); + + bret = GetSecurityDescriptorGroup(pSD, &group, &group_defaulted); + ok(bret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(group != NULL, "group should not be NULL\n"); + ok(EqualSid(group, domain_users_sid), "Process group SID != Domain Users SID.\n"); + LocalFree(pSD); + + /* Test querying the DACL of a process */ + ret = pGetSecurityInfo(GetCurrentProcess(), SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &pSD); + ok(!ret, "GetSecurityInfo failed with error %d\n", ret); + + bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); + ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(dacl_present, "DACL should be present\n"); + ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); + for (i=0; iSidStart, domain_users_sid); + if (bret) domain_users_ace_id = i; + bret = EqualSid(&ace->SidStart, admin_sid); + if (bret) admins_ace_id = i; + } + ok(domain_users_ace_id != -1 || broken(domain_users_ace_id == -1) /* win2k */, + "Domain Users ACE not found.\n"); + if (domain_users_ace_id != -1) + { + bret = pGetAce(pDacl, domain_users_ace_id, (VOID **)&ace); + ok(bret, "Failed to get Domain Users ACE.\n"); + flags = ((ACE_HEADER *)ace)->AceFlags; + ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE), + "Domain Users ACE has unexpected flags (0x%x != 0x%x)\n", flags, + INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); + ok(ace->Mask == GENERIC_READ, "Domain Users ACE has unexpected mask (0x%x != 0x%x)\n", + ace->Mask, GENERIC_READ); + } + ok(admins_ace_id != -1 || broken(admins_ace_id == -1) /* xp */, + "Builtin Admins ACE not found.\n"); + if (admins_ace_id != -1) + { + bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); + ok(bret, "Failed to get Builtin Admins ACE.\n"); + flags = ((ACE_HEADER *)ace)->AceFlags; + ok(flags == 0x0, "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); + ok(ace->Mask == PROCESS_ALL_ACCESS || broken(ace->Mask == 0x1f0fff) /* win2k */, + "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, PROCESS_ALL_ACCESS); + } + LocalFree(pSD); } static void test_GetSidSubAuthority(void) diff --git a/rostests/winetests/advapi32/service.c b/rostests/winetests/advapi32/service.c index 9d0337ff150..e54de7a1ea6 100644 --- a/rostests/winetests/advapi32/service.c +++ b/rostests/winetests/advapi32/service.c @@ -1401,8 +1401,8 @@ static void test_enum_svc(void) SERVICE_STATUS status = services[i].ServiceStatus; /* lpServiceName and lpDisplayName should always be filled */ - ok(lstrlenA(services[i].lpServiceName) > 0, "Expected a service name\n"); - ok(lstrlenA(services[i].lpDisplayName) > 0, "Expected a display name\n"); + ok(services[i].lpServiceName[0], "Expected a service name\n"); + ok(services[i].lpDisplayName[0], "Expected a display name\n"); /* Decrement the counters to see if the functions calls return the same * numbers as the contents of these structures. @@ -1704,8 +1704,8 @@ static void test_enum_svc(void) SERVICE_STATUS_PROCESS status = exservices[i].ServiceStatusProcess; /* lpServiceName and lpDisplayName should always be filled */ - ok(lstrlenA(exservices[i].lpServiceName) > 0, "Expected a service name\n"); - ok(lstrlenA(exservices[i].lpDisplayName) > 0, "Expected a display name\n"); + ok(exservices[i].lpServiceName[0], "Expected a service name\n"); + ok(exservices[i].lpDisplayName[0], "Expected a display name\n"); /* Decrement the counters to see if the functions calls return the * same numbers as the contents of these structures.