[ADVAPI32_WINETEST]
authorAmine Khaldi <amine.khaldi@reactos.org>
Fri, 17 Oct 2014 13:36:13 +0000 (13:36 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Fri, 17 Oct 2014 13:36:13 +0000 (13:36 +0000)
* Sync with Wine 1.7.27.
CORE-8540

svn path=/trunk/; revision=64784

rostests/winetests/advapi32/eventlog.c
rostests/winetests/advapi32/registry.c
rostests/winetests/advapi32/security.c
rostests/winetests/advapi32/service.c

index a3fe44b..1e48348 100644 (file)
@@ -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);
 }
index 5659930..02bfff5 100644 (file)
@@ -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 );
index 4485746..1336da0 100644 (file)
@@ -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;
index 603e508..262b823 100644 (file)
@@ -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);