* Sync with Wine 1.7.27.
CORE-8540
svn path=/trunk/; revision=64784
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)
{
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);
}
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 */
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" );
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,
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)
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);
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);
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);
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);
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);
"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();
test_rw_order();
test_deleted_key();
test_delete_value();
+ test_delete_key_value();
/* cleanup */
delete_key( hkey_main );
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[] = {
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);
}
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());
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 );
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));
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
winetest_wait_child_process( info.hProcess );
+ FreeSid(EveryoneSid);
CloseHandle( info.hProcess );
CloseHandle( info.hThread );
CloseHandle( event );
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
+ LocalFree(pSD);
done:
HeapFree(GetProcessHeap(), 0, user);
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);
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);
ok(ace->Mask == 0x1f01ff, "Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n",
ace->Mask);
}
+ LocalFree(pSD);
CloseHandle(obj);
}
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);
{
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:
"%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:
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;
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;
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);
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];
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);
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);
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);