[ADVAPI32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
authorAmine Khaldi <amine.khaldi@reactos.org>
Sun, 6 Mar 2016 16:43:16 +0000 (16:43 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Sun, 6 Mar 2016 16:43:16 +0000 (16:43 +0000)
svn path=/trunk/; revision=70962

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

index ebae143..84a54a1 100644 (file)
@@ -961,7 +961,13 @@ static void test_machine_guid(void)
    {
        restoreGuid = TRUE;
        r = RegDeleteValueA(key, "MachineGuid");
    {
        restoreGuid = TRUE;
        r = RegDeleteValueA(key, "MachineGuid");
-       ok(!r, "RegDeleteValueA failed: %d\n", r);
+       ok(!r || broken(r == ERROR_ACCESS_DENIED) /*win8*/, "RegDeleteValueA failed: %d\n", r);
+       if (r == ERROR_ACCESS_DENIED)
+       {
+           skip("broken virtualization on HKLM\\Software\\Microsoft\\Cryptography\n");
+           RegCloseKey(key);
+           return;
+       }
    }
    else
        ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
    }
    else
        ok(r == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n",
index 1e48348..3ca59c3 100644 (file)
@@ -487,7 +487,7 @@ static void test_read(void)
     ok(!ret, "Expected failure\n");
     ok(read == 0, "Expected no bytes read\n");
     ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n");
     ok(!ret, "Expected failure\n");
     ok(read == 0, "Expected no bytes read\n");
     ok(needed > sizeof(EVENTLOGRECORD), "Expected the needed buffersize to be bigger than sizeof(EVENTLOGRECORD)\n");
-    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
+    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
 
     /* Read the first record */
     toread = needed;
 
     /* Read the first record */
     toread = needed;
index 7d16cb3..407c18b 100644 (file)
@@ -44,7 +44,8 @@ static const char * sTestpath2 = "%FOO%\\subdir1";
 static const DWORD ptr_size = 8 * sizeof(void*);
 
 static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD);
 static const DWORD ptr_size = 8 * sizeof(void*);
 
 static DWORD (WINAPI *pRegGetValueA)(HKEY,LPCSTR,LPCSTR,DWORD,LPDWORD,PVOID,LPDWORD);
-static DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
+static LONG (WINAPI *pRegCopyTreeA)(HKEY,const char *,HKEY);
+static LONG (WINAPI *pRegDeleteTreeA)(HKEY,const char *);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
 static DWORD (WINAPI *pRegDeleteKeyExA)(HKEY,LPCSTR,REGSAM,DWORD);
 static BOOL (WINAPI *pIsWow64Process)(HANDLE,PBOOL);
 static NTSTATUS (WINAPI * pNtDeleteKey)(HANDLE);
@@ -138,6 +139,7 @@ static void InitFunctionPtrs(void)
 
     /* This function was introduced with Windows 2003 SP1 */
     ADVAPI32_GET_PROC(RegGetValueA);
 
     /* This function was introduced with Windows 2003 SP1 */
     ADVAPI32_GET_PROC(RegGetValueA);
+    ADVAPI32_GET_PROC(RegCopyTreeA);
     ADVAPI32_GET_PROC(RegDeleteTreeA);
     ADVAPI32_GET_PROC(RegDeleteKeyExA);
     ADVAPI32_GET_PROC(RegDeleteKeyValueA);
     ADVAPI32_GET_PROC(RegDeleteTreeA);
     ADVAPI32_GET_PROC(RegDeleteKeyExA);
     ADVAPI32_GET_PROC(RegDeleteKeyValueA);
@@ -1343,6 +1345,13 @@ static void test_reg_create_key(void)
     RegDeleteKeyA(hkey1, "");
     RegCloseKey(hkey1);
 
     RegDeleteKeyA(hkey1, "");
     RegCloseKey(hkey1);
 
+    /* System\CurrentControlSet\Control\Video should be non-volatile */
+    ret = RegCreateKeyExA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Video\\Wine",
+                          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);
     /* 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);
@@ -2082,10 +2091,106 @@ static void test_string_termination(void)
     RegCloseKey(subkey);
 }
 
     RegCloseKey(subkey);
 }
 
+static void test_reg_copy_tree(void)
+{
+    HKEY src, dst, subkey;
+    CHAR buffer[MAX_PATH];
+    DWORD dwsize, type;
+    LONG size, ret;
+
+    if (!pRegCopyTreeA)
+    {
+        win_skip("Skipping RegCopyTreeA tests, function not present\n");
+        return;
+    }
+
+    ret = RegCreateKeyA(hkey_main, "src", &src);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegCreateKeyA(hkey_main, "dst", &dst);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    /* Copy nonexistent subkey */
+    ret = pRegCopyTreeA(src, "nonexistent_subkey", dst);
+    ok(ret == ERROR_FILE_NOT_FOUND, "Expected ERROR_FILE_NOT_FOUND, got %d\n", ret);
+
+    /*  Create test keys and values */
+    ret = RegSetValueA(src, NULL, REG_SZ, "data", 4);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegSetValueExA(src, "value", 0, REG_SZ, (const BYTE *)"data2", 5);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    ret = RegCreateKeyA(src, "subkey2", &subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegSetValueA(subkey, NULL, REG_SZ, "data3", 5);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegSetValueExA(subkey, "value", 0, REG_SZ, (const BYTE *)"data4", 5);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegCloseKey(subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    ret = RegCreateKeyA(src, "subkey3", &subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegCloseKey(subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    /* Copy subkey */
+    ret = pRegCopyTreeA(src, "subkey2", dst);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    size = MAX_PATH;
+    ret = RegQueryValueA(dst, NULL, buffer, &size);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(!strcmp(buffer, "data3"), "Expected 'data3', got '%s'\n", buffer);
+
+    dwsize = MAX_PATH;
+    ret = RegQueryValueExA(dst, "value", NULL, &type, (BYTE *)buffer, &dwsize);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
+    ok(!strcmp(buffer, "data4"), "Expected 'data4', got '%s'\n", buffer);
+
+    /* Copy full tree */
+    ret = pRegCopyTreeA(src, NULL, dst);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    size = MAX_PATH;
+    ret = RegQueryValueA(dst, NULL, buffer, &size);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(!strcmp(buffer, "data"), "Expected 'data', got '%s'\n", buffer);
+
+    dwsize = MAX_PATH;
+    ret = RegQueryValueExA(dst, "value", NULL, &type, (BYTE *)buffer, &dwsize);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
+    ok(!strcmp(buffer, "data2"), "Expected 'data2', got '%s'\n", buffer);
+
+    ret = RegOpenKeyA(dst, "subkey2", &subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    size = MAX_PATH;
+    ret = RegQueryValueA(subkey, NULL, buffer, &size);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(!strcmp(buffer, "data3"), "Expected 'data3', got '%s'\n", buffer);
+    dwsize = MAX_PATH;
+    ret = RegQueryValueExA(subkey, "value", NULL, &type, (BYTE *)buffer, &dwsize);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ok(type == REG_SZ, "Expected REG_SZ, got %u\n", type);
+    ok(!strcmp(buffer, "data4"), "Expected 'data4', got '%s'\n", buffer);
+    ret = RegCloseKey(subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    ret = RegOpenKeyA(dst, "subkey3", &subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegCloseKey(subkey);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+
+    delete_key(src);
+    delete_key(dst);
+}
+
 static void test_reg_delete_tree(void)
 {
     CHAR buffer[MAX_PATH];
     HKEY subkey, subkey2;
 static void test_reg_delete_tree(void)
 {
     CHAR buffer[MAX_PATH];
     HKEY subkey, subkey2;
+    DWORD dwsize, type;
     LONG size, ret;
 
     if(!pRegDeleteTreeA) {
     LONG size, ret;
 
     if(!pRegDeleteTreeA) {
@@ -2131,7 +2236,9 @@ static void test_reg_delete_tree(void)
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ret = RegCloseKey(subkey2);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ret = RegCloseKey(subkey2);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
-    ret = RegSetValueA(subkey, "value", REG_SZ, "data2", 5);
+    ret = RegSetValueA(subkey, NULL, REG_SZ, "data", 4);
+    ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
+    ret = RegSetValueExA(subkey, "value", 0, REG_SZ, (const BYTE *)"data2", 5);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ret = pRegDeleteTreeA(subkey, NULL);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
     ret = pRegDeleteTreeA(subkey, NULL);
     ok(ret == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %d\n", ret);
@@ -2146,8 +2253,8 @@ static void test_reg_delete_tree(void)
     ok(ret == ERROR_SUCCESS,
         "Default value of subkey is not present\n");
     ok(!buffer[0], "Expected length 0 got length %u(%s)\n", lstrlenA(buffer), buffer);
     ok(ret == ERROR_SUCCESS,
         "Default value of subkey is not present\n");
     ok(!buffer[0], "Expected length 0 got length %u(%s)\n", lstrlenA(buffer), buffer);
-    size = MAX_PATH;
-    ok(RegQueryValueA(subkey, "value", buffer, &size),
+    dwsize = MAX_PATH;
+    ok(RegQueryValueExA(subkey, "value", NULL, &type, (BYTE *)buffer, &dwsize),
         "Value is still present\n");
 
     ret = pRegDeleteTreeA(hkey_main, "not-here");
         "Value is still present\n");
 
     ret = pRegDeleteTreeA(hkey_main, "not-here");
@@ -3281,6 +3388,18 @@ static void test_delete_key_value(void)
     RegCloseKey(subkey);
 }
 
     RegCloseKey(subkey);
 }
 
+static void test_RegOpenCurrentUser(void)
+{
+    HKEY key;
+    LONG ret;
+
+    key = HKEY_CURRENT_USER;
+    ret = RegOpenCurrentUser(KEY_READ, &key);
+    ok(!ret, "got %d, error %d\n", ret, GetLastError());
+    ok(key != HKEY_CURRENT_USER, "got %p\n", key);
+    RegCloseKey(key);
+}
+
 START_TEST(registry)
 {
     /* Load pointers for functions that are not available in all Windows versions */
 START_TEST(registry)
 {
     /* Load pointers for functions that are not available in all Windows versions */
@@ -3305,16 +3424,16 @@ START_TEST(registry)
     test_classesroot();
     test_classesroot_enum();
     test_classesroot_mask();
     test_classesroot();
     test_classesroot_enum();
     test_classesroot_mask();
-
     test_reg_save_key();
     test_reg_load_key();
     test_reg_unload_key();
     test_reg_save_key();
     test_reg_load_key();
     test_reg_unload_key();
-
+    test_reg_copy_tree();
     test_reg_delete_tree();
     test_rw_order();
     test_deleted_key();
     test_delete_value();
     test_delete_key_value();
     test_reg_delete_tree();
     test_rw_order();
     test_deleted_key();
     test_delete_value();
     test_delete_key_value();
+    test_RegOpenCurrentUser();
 
     /* cleanup */
     delete_key( hkey_main );
 
     /* cleanup */
     delete_key( hkey_main );
index 1c88cea..e99cfd7 100644 (file)
 
 #include "wine/test.h"
 
 
 #include "wine/test.h"
 
+/* FIXME: Inspect */
+#define GetCurrentProcessToken() ((HANDLE)~(ULONG_PTR)3)
+#define GetCurrentThreadToken() ((HANDLE)~(ULONG_PTR)4)
+#define GetCurrentThreadEffectiveToken() ((HANDLE)~(ULONG_PTR)5)
+
 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
 #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
 #endif
 #ifndef PROCESS_QUERY_LIMITED_INFORMATION
 #define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
 #endif
@@ -135,6 +140,7 @@ static NTSTATUS (WINAPI *pRtlAnsiStringToUnicodeString)(PUNICODE_STRING,PCANSI_S
 static BOOL     (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*);
 static void     (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
 static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
 static BOOL     (WINAPI *pGetWindowsAccountDomainSid)(PSID,PSID,DWORD*);
 static void     (WINAPI *pRtlInitAnsiString)(PANSI_STRING,PCSZ);
 static NTSTATUS (WINAPI *pRtlFreeUnicodeString)(PUNICODE_STRING);
+static PSID_IDENTIFIER_AUTHORITY (WINAPI *pGetSidIdentifierAuthority)(PSID);
 
 static HMODULE hmod;
 static int     myARGC;
 
 static HMODULE hmod;
 static int     myARGC;
@@ -148,6 +154,35 @@ struct strsid_entry
 #define STRSID_OK     0
 #define STRSID_OPT    1
 
 #define STRSID_OK     0
 #define STRSID_OPT    1
 
+#define SID_SLOTS 4
+static char debugsid_str[SID_SLOTS][256];
+static int debugsid_index = 0;
+static const char* debugstr_sid(PSID sid)
+{
+    LPSTR sidstr;
+    DWORD le = GetLastError();
+    char* res = debugsid_str[debugsid_index];
+    debugsid_index = (debugsid_index + 1) % SID_SLOTS;
+    if (!pConvertSidToStringSidA)
+        strcpy(res, "missing ConvertSidToStringSidA");
+    else if (!pConvertSidToStringSidA(sid, &sidstr))
+        sprintf(res, "ConvertSidToStringSidA failed le=%u", GetLastError());
+    else if (strlen(sidstr) > sizeof(*debugsid_str) - 1)
+    {
+        memcpy(res, sidstr, sizeof(*debugsid_str) - 4);
+        strcpy(res + sizeof(*debugsid_str) - 4, "...");
+        LocalFree(sidstr);
+    }
+    else
+    {
+        strcpy(res, sidstr);
+        LocalFree(sidstr);
+    }
+    /* Restore the last error in case ConvertSidToStringSidA() modified it */
+    SetLastError(le);
+    return res;
+}
+
 struct sidRef
 {
     SID_IDENTIFIER_AUTHORITY auth;
 struct sidRef
 {
     SID_IDENTIFIER_AUTHORITY auth;
@@ -199,6 +234,7 @@ static void init(void)
     pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
     pGetAce = (void *)GetProcAddress(hmod, "GetAce");
     pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid");
     pGetAclInformation = (void *)GetProcAddress(hmod, "GetAclInformation");
     pGetAce = (void *)GetProcAddress(hmod, "GetAce");
     pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid");
+    pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority");
 
     myARGC = winetest_get_mainargs( &myARGV );
 }
 
     myARGC = winetest_get_mainargs( &myARGV );
 }
@@ -241,7 +277,8 @@ static void test_owner_equal(HANDLE Handle, PSID expected, int line)
     res = GetSecurityDescriptorOwner(queriedSD, &owner, &owner_defaulted);
     ok_(__FILE__, line)(res, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
 
     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)(EqualSid(owner, expected), "Owner SIDs are not equal %s != %s\n",
+                        debugstr_sid(owner), debugstr_sid(expected));
     ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n");
 
     HeapFree(GetProcessHeap(), 0, queriedSD);
     ok_(__FILE__, line)(!owner_defaulted, "Defaulted is true\n");
 
     HeapFree(GetProcessHeap(), 0, queriedSD);
@@ -259,7 +296,8 @@ static void test_group_equal(HANDLE Handle, PSID expected, int line)
     res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted);
     ok_(__FILE__, line)(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
 
     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)(EqualSid(group, expected), "Group SIDs are not equal %s != %s\n",
+                        debugstr_sid(group), debugstr_sid(expected));
     ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n");
 
     HeapFree(GetProcessHeap(), 0, queriedSD);
     ok_(__FILE__, line)(!group_defaulted, "Defaulted is true\n");
 
     HeapFree(GetProcessHeap(), 0, queriedSD);
@@ -1381,6 +1419,158 @@ static void test_AccessCheck(void)
         GetLastError());
     trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access);
 
         GetLastError());
     trace("AccessCheck with MAXIMUM_ALLOWED got Access 0x%08x\n", Access);
 
+    /* Null PrivSet with null PrivSetLen pointer */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      NULL, NULL, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
+       "failed with ERROR_NOACCESS, instead of %d\n", err);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Null PrivSet with zero PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = 0;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      0, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+       "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Null PrivSet with insufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = 1;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      0, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
+       "failed with ERROR_NOACCESS, instead of %d\n", err);
+    ok(PrivSetLen == 1, "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Null PrivSet with insufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      0, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
+       "failed with ERROR_NOACCESS, instead of %d\n", err);
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET) - 1, "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Null PrivSet with minimal sufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = sizeof(PRIVILEGE_SET);
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      0, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
+       "failed with ERROR_NOACCESS, instead of %d\n", err);
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Valid PrivSet with zero PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = 0;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      PrivSet, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+       "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Valid PrivSet with insufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = 1;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      PrivSet, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+todo_wine
+    ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+       "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+todo_wine
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Valid PrivSet with insufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      PrivSet, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+todo_wine
+    ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+       "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+todo_wine
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+todo_wine
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
+    /* Valid PrivSet with minimal sufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = sizeof(PRIVILEGE_SET);
+    memset(PrivSet, 0xcc, PrivSetLen);
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      PrivSet, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(ret, "AccessCheck failed with error %d\n", GetLastError());
+todo_wine
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    ok(AccessStatus && (Access == KEY_READ),
+        "AccessCheck failed to grant access with error %d\n", GetLastError());
+    ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
+        PrivSet->PrivilegeCount);
+
+    /* Valid PrivSet with sufficient PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    PrivSetLen = sizeof(PRIVILEGE_SET) + 1;
+    memset(PrivSet, 0xcc, PrivSetLen);
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      PrivSet, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(ret, "AccessCheck failed with error %d\n", GetLastError());
+todo_wine
+    ok(PrivSetLen == sizeof(PRIVILEGE_SET) + 1, "PrivSetLen returns %d\n", PrivSetLen);
+    ok(AccessStatus && (Access == KEY_READ),
+        "AccessCheck failed to grant access with error %d\n", GetLastError());
+    ok(PrivSet->PrivilegeCount == 0, "PrivilegeCount returns %d, expects 0\n",
+        PrivSet->PrivilegeCount);
+
+    PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
+
+    /* Null PrivSet with valid PrivSetLen */
+    SetLastError(0xdeadbeef);
+    Access = AccessStatus = 0x1abe11ed;
+    ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                      0, &PrivSetLen, &Access, &AccessStatus);
+    err = GetLastError();
+    ok(!ret && err == ERROR_NOACCESS, "AccessCheck should have "
+       "failed with ERROR_NOACCESS, instead of %d\n", err);
+    ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+       "Access and/or AccessStatus were changed!\n");
+
     /* Access denied by SD */
     SetLastError(0xdeadbeef);
     Access = AccessStatus = 0x1abe11ed;
     /* Access denied by SD */
     SetLastError(0xdeadbeef);
     Access = AccessStatus = 0x1abe11ed;
@@ -1392,7 +1582,7 @@ static void test_AccessCheck(void)
        "with ERROR_ACCESS_DENIED, instead of %d\n", err);
     ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
 
        "with ERROR_ACCESS_DENIED, instead of %d\n", err);
     ok(!Access, "Should have failed to grant any access, got 0x%08x\n", Access);
 
-    SetLastError(0);
+    SetLastError(0xdeadbeef);
     PrivSet->PrivilegeCount = 16;
     ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
                       PrivSet, &PrivSetLen, &Access, &AccessStatus);
     PrivSet->PrivilegeCount = 16;
     ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
                       PrivSet, &PrivSetLen, &Access, &AccessStatus);
@@ -1405,16 +1595,66 @@ static void test_AccessCheck(void)
     ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
     if (!ret)
     {
     ret = pRtlAdjustPrivilege(SE_SECURITY_PRIVILEGE, TRUE, TRUE, &Enabled);
     if (!ret)
     {
-        SetLastError(0);
-        PrivSet->PrivilegeCount = 16;
+        /* Valid PrivSet with zero PrivSetLen */
+        SetLastError(0xdeadbeef);
+        Access = AccessStatus = 0x1abe11ed;
+        PrivSetLen = 0;
+        ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                          PrivSet, &PrivSetLen, &Access, &AccessStatus);
+        err = GetLastError();
+        ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+           "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+        ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+        ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+           "Access and/or AccessStatus were changed!\n");
+
+        /* Valid PrivSet with insufficient PrivSetLen */
+        SetLastError(0xdeadbeef);
+        Access = AccessStatus = 0x1abe11ed;
+        PrivSetLen = sizeof(PRIVILEGE_SET) - 1;
+        ret = AccessCheck(SecurityDescriptor, Token, KEY_READ, &Mapping,
+                          PrivSet, &PrivSetLen, &Access, &AccessStatus);
+        err = GetLastError();
+    todo_wine
+        ok(!ret && err == ERROR_INSUFFICIENT_BUFFER, "AccessCheck should have "
+           "failed with ERROR_INSUFFICIENT_BUFFER, instead of %d\n", err);
+    todo_wine
+        ok(PrivSetLen == sizeof(PRIVILEGE_SET), "PrivSetLen returns %d\n", PrivSetLen);
+    todo_wine
+        ok(Access == 0x1abe11ed && AccessStatus == 0x1abe11ed,
+           "Access and/or AccessStatus were changed!\n");
+
+        /* Valid PrivSet with minimal sufficient PrivSetLen */
+        SetLastError(0xdeadbeef);
+        Access = AccessStatus = 0x1abe11ed;
+        PrivSetLen = sizeof(PRIVILEGE_SET);
+        memset(PrivSet, 0xcc, PrivSetLen);
         ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
                           PrivSet, &PrivSetLen, &Access, &AccessStatus);
         ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
                           PrivSet, &PrivSetLen, &Access, &AccessStatus);
-        ok(ret && AccessStatus && GetLastError() == 0,
+        ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
             "AccessCheck should have succeeded, error %d\n",
             GetLastError());
         ok(Access == ACCESS_SYSTEM_SECURITY,
             "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
             Access);
             "AccessCheck should have succeeded, error %d\n",
             GetLastError());
         ok(Access == ACCESS_SYSTEM_SECURITY,
             "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
             Access);
+        ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
+            PrivSet->PrivilegeCount);
+
+        /* Valid PrivSet with large PrivSetLen */
+        SetLastError(0xdeadbeef);
+        Access = AccessStatus = 0x1abe11ed;
+        PrivSetLen = FIELD_OFFSET(PRIVILEGE_SET, Privilege[16]);
+        memset(PrivSet, 0xcc, PrivSetLen);
+        ret = AccessCheck(SecurityDescriptor, Token, ACCESS_SYSTEM_SECURITY, &Mapping,
+                          PrivSet, &PrivSetLen, &Access, &AccessStatus);
+        ok(ret && AccessStatus && GetLastError() == 0xdeadbeef,
+            "AccessCheck should have succeeded, error %d\n",
+            GetLastError());
+        ok(Access == ACCESS_SYSTEM_SECURITY,
+            "Access should be equal to ACCESS_SYSTEM_SECURITY instead of 0x%08x\n",
+            Access);
+        ok(PrivSet->PrivilegeCount == 1, "PrivilegeCount returns %d, expects 1\n",
+            PrivSet->PrivilegeCount);
     }
     else
         trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
     }
     else
         trace("Couldn't get SE_SECURITY_PRIVILEGE (0x%08x), skipping ACCESS_SYSTEM_SECURITY test\n",
@@ -2187,7 +2427,8 @@ static void check_wellknown_name(const char* name, WELL_KNOWN_SID_TYPE result)
     ok(ret, "Failed to lookup account name %s\n",name);
     ok(sid_size != 0, "sid_size was zero\n");
 
     ok(ret, "Failed to lookup account name %s\n",name);
     ok(sid_size != 0, "sid_size was zero\n");
 
-    ok(EqualSid(psid,wk_sid),"(%s) Sids fail to match well known sid!\n",name);
+    ok(EqualSid(psid,wk_sid),"%s Sid %s fails to match well known sid %s!\n",
+       name, debugstr_sid(psid), debugstr_sid(wk_sid));
 
     ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account);
     ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain);
 
     ok(!lstrcmpA(account, wk_account), "Expected %s , got %s\n", account, wk_account);
     ok(!lstrcmpA(domain, wk_domain), "Expected %s, got %s\n", wk_domain, domain);
@@ -3186,12 +3427,7 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
     bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
 
     bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
 
-    if (todo_count)
-        todo_wine
-        ok_(__FILE__, line)(acl_size.AceCount == 2,
-            "GetAclInformation returned unexpected entry count (%d != 2)\n",
-            acl_size.AceCount);
-    else
+    todo_wine_if (todo_count)
         ok_(__FILE__, line)(acl_size.AceCount == 2,
             "GetAclInformation returned unexpected entry count (%d != 2)\n",
             acl_size.AceCount);
         ok_(__FILE__, line)(acl_size.AceCount == 2,
             "GetAclInformation returned unexpected entry count (%d != 2)\n",
             acl_size.AceCount);
@@ -3202,18 +3438,10 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
         ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
 
         bret = EqualSid(&ace->SidStart, user_sid);
         ok_(__FILE__, line)(bret, "Failed to get Current User ACE\n");
 
         bret = EqualSid(&ace->SidStart, user_sid);
-        if (todo_sid)
-            todo_wine
-            ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n");
-        else
-            ok_(__FILE__, line)(bret, "Current User ACE != Current User SID\n");
+        todo_wine_if (todo_sid)
+            ok_(__FILE__, line)(bret, "Current User ACE (%s) != Current User SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
 
 
-        if (todo_flags)
-            todo_wine
-            ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
-                "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
-                ((ACE_HEADER *)ace)->AceFlags, flags);
-        else
+        todo_wine_if (todo_flags)
             ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
                 "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
                 ((ACE_HEADER *)ace)->AceFlags, flags);
             ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
                 "Current User ACE has unexpected flags (0x%x != 0x%x)\n",
                 ((ACE_HEADER *)ace)->AceFlags, flags);
@@ -3228,18 +3456,10 @@ static void test_inherited_dacl(PACL dacl, PSID admin_sid, PSID user_sid, DWORD
         ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
 
         bret = EqualSid(&ace->SidStart, admin_sid);
         ok_(__FILE__, line)(bret, "Failed to get Administators Group ACE\n");
 
         bret = EqualSid(&ace->SidStart, admin_sid);
-        if (todo_sid)
-            todo_wine
-            ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n");
-        else
-            ok_(__FILE__, line)(bret, "Administators Group ACE != Administators Group SID\n");
+        todo_wine_if (todo_sid)
+            ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
 
 
-        if (todo_flags)
-            todo_wine
-            ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
-                "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
-                ((ACE_HEADER *)ace)->AceFlags, flags);
-        else
+        todo_wine_if (todo_flags)
             ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
                 "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
                 ((ACE_HEADER *)ace)->AceFlags, flags);
             ok_(__FILE__, line)(((ACE_HEADER *)ace)->AceFlags == flags,
                 "Administators Group ACE has unexpected flags (0x%x != 0x%x)\n",
                 ((ACE_HEADER *)ace)->AceFlags, flags);
@@ -3451,7 +3671,6 @@ static void test_CreateDirectoryA(void)
     ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
     bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok(bret, "GetAclInformation failed\n");
     ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
     bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok(bret, "GetAclInformation failed\n");
-    todo_wine
     ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
                                acl_size.AceCount);
     LocalFree(pSD);
     ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
                                acl_size.AceCount);
     LocalFree(pSD);
@@ -3510,6 +3729,7 @@ static void test_CreateDirectoryA(void)
     ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
     bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok(bret, "GetAclInformation failed\n");
     ok(error == ERROR_SUCCESS, "GetNamedSecurityInfo failed with error %d\n", error);
     bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
     ok(bret, "GetAclInformation failed\n");
+    todo_wine
     ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
                                acl_size.AceCount);
     LocalFree(pSD);
     ok(acl_size.AceCount == 0, "GetAclInformation returned unexpected entry count (%d != 0).\n",
                                acl_size.AceCount);
     LocalFree(pSD);
@@ -3785,7 +4005,8 @@ 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);
         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(bret, "Current User ACE (%s) != Current User SID (%s).\n",
+           debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
         ok(((ACE_HEADER *)ace)->AceFlags == 0,
            "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
         ok(ace->Mask == 0x1f01ff,
         ok(((ACE_HEADER *)ace)->AceFlags == 0,
            "Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
         ok(ace->Mask == 0x1f01ff,
@@ -3796,7 +4017,8 @@ 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);
         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(bret || broken(!bret) /* win2k */, "Administators Group ACE (%s) != Administators Group SID (%s).\n",
+           debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
         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 */,
         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 */,
@@ -3930,14 +4152,15 @@ static void test_GetNamedSecurityInfoA(void)
     bret = GetSecurityDescriptorOwner(pSD, &owner, &owner_defaulted);
     ok(bret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
     ok(owner != NULL, "owner should not be NULL\n");
     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), "MACHINE\\Software owner SID != Administrators SID.\n");
+    ok(EqualSid(owner, admin_sid), "MACHINE\\Software owner SID (%s) != Administrators SID (%s).\n", debugstr_sid(owner), debugstr_sid(admin_sid));
 
     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, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */
        || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */,
 
     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, admin_sid) || broken(EqualSid(group, system_sid)) /* before Win7 */
        || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */,
-       "MACHINE\\Software group SID != Local System SID.\n");
+       "MACHINE\\Software group SID (%s) != Local System SID (%s or %s)\n",
+       debugstr_sid(group), debugstr_sid(admin_sid), debugstr_sid(system_sid));
     LocalFree(pSD);
 
     /* Test querying the DACL of a built-in registry key */
     LocalFree(pSD);
 
     /* Test querying the DACL of a built-in registry key */
@@ -4579,7 +4802,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);
         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(bret, "Current User ACE (%s) != Current User SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(user_sid));
         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",
         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",
@@ -4590,7 +4813,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);
         bret = pGetAce(pDacl, 1, (VOID **)&ace);
         ok(bret, "Failed to get Administators Group ACE.\n");
         bret = EqualSid(&ace->SidStart, admin_sid);
-        ok(bret, "Administators Group ACE != Administators Group SID.\n");
+        ok(bret, "Administators Group ACE (%s) != Administators Group SID (%s).\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid));
         ok(((ACE_HEADER *)ace)->AceFlags == 0,
            "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
         ok(ace->Mask == 0x1f01ff,
         ok(((ACE_HEADER *)ace)->AceFlags == 0,
            "Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
         ok(ace->Mask == 0x1f01ff,
@@ -4817,7 +5040,8 @@ static void test_EqualSid(void)
 
     SetLastError(0xdeadbeef);
     ret = EqualSid(sid1, sid2);
 
     SetLastError(0xdeadbeef);
     ret = EqualSid(sid1, sid2);
-    ok(ret, "Same sids should have been equal\n");
+    ok(ret, "Same sids should have been equal %s != %s\n",
+       debugstr_sid(sid1), debugstr_sid(sid2));
     ok(GetLastError() == ERROR_SUCCESS ||
        broken(GetLastError() == 0xdeadbeef), /* NT4 */
        "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
     ok(GetLastError() == ERROR_SUCCESS ||
        broken(GetLastError() == 0xdeadbeef), /* NT4 */
        "EqualSid should have set last error to ERROR_SUCCESS instead of %d\n",
@@ -5472,11 +5696,8 @@ static void test_named_pipe_security(HANDLE token)
             ok(ret, "DuplicateHandle error %d\n", GetLastError());
 
             access = get_obj_access(dup);
             ok(ret, "DuplicateHandle error %d\n", GetLastError());
 
             access = get_obj_access(dup);
-            if (map[i].todo)
-todo_wine
-            ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
-            else
-            ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
+            todo_wine_if (map[i].todo)
+                ok(access == map[i].mapped, "%d: expected %#x, got %#x\n", i, map[i].mapped, access);
 
             CloseHandle(dup);
         }
 
             CloseHandle(dup);
         }
@@ -5961,7 +6182,6 @@ static void test_TokenIntegrityLevel(void)
     HANDLE token;
     DWORD size;
     DWORD res;
     HANDLE token;
     DWORD size;
     DWORD res;
-    char *sidname = NULL;
     static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
                                                     {SECURITY_MANDATORY_HIGH_RID}};
     static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
     static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
                                                     {SECURITY_MANDATORY_HIGH_RID}};
     static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
@@ -5993,14 +6213,10 @@ static void test_TokenIntegrityLevel(void)
     ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
         "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
 
     ok(tml->Label.Attributes == (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED),
         "got 0x%x (expected 0x%x)\n", tml->Label.Attributes, (SE_GROUP_INTEGRITY | SE_GROUP_INTEGRITY_ENABLED));
 
-    SetLastError(0xdeadbeef);
-    res = pConvertSidToStringSidA(tml->Label.Sid, &sidname);
-    ok(res, "got %u and %u\n", res, GetLastError());
-
     ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
     ok(EqualSid(tml->Label.Sid, &medium_level) || EqualSid(tml->Label.Sid, &high_level),
-        "got %s (expected 'S-1-16-8192' or 'S-1-16-12288')\n", sidname);
+       "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid),
+       debugstr_sid(&medium_level), debugstr_sid(&high_level));
 
 
-    LocalFree(sidname);
     CloseHandle(token);
 }
 
     CloseHandle(token);
 }
 
@@ -6315,11 +6531,91 @@ static void test_GetWindowsAccountDomainSid(void)
     InitializeSid(domain_sid2, &domain_ident, 4);
     for (i = 0; i < 4; i++)
         *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i);
     InitializeSid(domain_sid2, &domain_ident, 4);
     for (i = 0; i < 4; i++)
         *GetSidSubAuthority(domain_sid2, i) = *GetSidSubAuthority(user_sid, i);
-    ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid\n");
+    ok(EqualSid(domain_sid, domain_sid2), "unexpected domain sid %s != %s\n",
+       debugstr_sid(domain_sid), debugstr_sid(domain_sid2));
 
     HeapFree(GetProcessHeap(), 0, user);
 }
 
 
     HeapFree(GetProcessHeap(), 0, user);
 }
 
+static void test_GetSidIdentifierAuthority(void)
+{
+    char buffer[SECURITY_MAX_SID_SIZE];
+    PSID authority_sid = (PSID *)buffer;
+    PSID_IDENTIFIER_AUTHORITY id;
+    BOOL ret;
+
+    if (!pGetSidIdentifierAuthority)
+    {
+        win_skip("GetSidIdentifierAuthority not available\n");
+        return;
+    }
+
+    memset(buffer, 0xcc, sizeof(buffer));
+    ret = IsValidSid(authority_sid);
+    ok(!ret, "expected FALSE, got %u\n", ret);
+
+    SetLastError(0xdeadbeef);
+    id = GetSidIdentifierAuthority(authority_sid);
+    ok(id != NULL, "got NULL pointer as identifier authority\n");
+    ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    id = GetSidIdentifierAuthority(NULL);
+    ok(id != NULL, "got NULL pointer as identifier authority\n");
+    ok(GetLastError() == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %u\n", GetLastError());
+}
+
+static void test_pseudo_tokens(void)
+{
+    TOKEN_STATISTICS statistics1, statistics2;
+    HANDLE token;
+    DWORD retlen;
+    BOOL ret;
+
+    ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token);
+    ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+    memset(&statistics1, 0x11, sizeof(statistics1));
+    ret = GetTokenInformation(token, TokenStatistics, &statistics1, sizeof(statistics1), &retlen);
+    ok(ret, "GetTokenInformation failed with %u\n", GetLastError());
+    CloseHandle(token);
+
+    /* test GetCurrentProcessToken() */
+    SetLastError(0xdeadbeef);
+    memset(&statistics2, 0x22, sizeof(statistics2));
+    ret = GetTokenInformation(GetCurrentProcessToken(), TokenStatistics,
+                              &statistics2, sizeof(statistics2), &retlen);
+    ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
+       "GetTokenInformation failed with %u\n", GetLastError());
+    if (ret)
+        ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
+    else
+        win_skip("CurrentProcessToken not supported, skipping test\n");
+
+    /* test GetCurrentThreadEffectiveToken() */
+    SetLastError(0xdeadbeef);
+    memset(&statistics2, 0x22, sizeof(statistics2));
+    ret = GetTokenInformation(GetCurrentThreadEffectiveToken(), TokenStatistics,
+                              &statistics2, sizeof(statistics2), &retlen);
+    ok(ret || broken(GetLastError() == ERROR_INVALID_HANDLE),
+       "GetTokenInformation failed with %u\n", GetLastError());
+    if (ret)
+        ok(!memcmp(&statistics1, &statistics2, sizeof(statistics1)), "Token statistics do not match\n");
+    else
+        win_skip("CurrentThreadEffectiveToken not supported, skipping test\n");
+
+    SetLastError(0xdeadbeef);
+    ret = OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &token);
+    ok(!ret, "OpenThreadToken should have failed\n");
+    ok(GetLastError() == ERROR_NO_TOKEN, "Expected ERROR_NO_TOKEN, got %u\n", GetLastError());
+
+    /* test GetCurrentThreadToken() */
+    SetLastError(0xdeadbeef);
+    ret = GetTokenInformation(GetCurrentThreadToken(), TokenStatistics,
+                              &statistics2, sizeof(statistics2), &retlen);
+    todo_wine ok(GetLastError() == ERROR_NO_TOKEN || broken(GetLastError() == ERROR_INVALID_HANDLE),
+                 "Expected ERROR_NO_TOKEN, got %u\n", GetLastError());
+}
+
 START_TEST(security)
 {
     init();
 START_TEST(security)
 {
     init();
@@ -6364,4 +6660,6 @@ START_TEST(security)
     test_AdjustTokenPrivileges();
     test_AddAce();
     test_system_security_access();
     test_AdjustTokenPrivileges();
     test_AddAce();
     test_system_security_access();
+    test_GetSidIdentifierAuthority();
+    test_pseudo_tokens();
 }
 }