Author: akhaldi Date: Sun Mar 6 16:43:16 2016 New Revision: 70962
URL: http://svn.reactos.org/svn/reactos?rev=70962&view=rev Log: [ADVAPI32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
Modified: trunk/rostests/winetests/advapi32/crypt.c trunk/rostests/winetests/advapi32/eventlog.c trunk/rostests/winetests/advapi32/registry.c trunk/rostests/winetests/advapi32/security.c
Modified: trunk/rostests/winetests/advapi32/crypt.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/crypt.c... ============================================================================== --- trunk/rostests/winetests/advapi32/crypt.c [iso-8859-1] (original) +++ trunk/rostests/winetests/advapi32/crypt.c [iso-8859-1] Sun Mar 6 16:43:16 2016 @@ -961,7 +961,13 @@ { 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",
Modified: trunk/rostests/winetests/advapi32/eventlog.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/eventlo... ============================================================================== --- trunk/rostests/winetests/advapi32/eventlog.c [iso-8859-1] (original) +++ trunk/rostests/winetests/advapi32/eventlog.c [iso-8859-1] Sun Mar 6 16:43:16 2016 @@ -487,7 +487,7 @@ 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;
Modified: trunk/rostests/winetests/advapi32/registry.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/registr... ============================================================================== --- trunk/rostests/winetests/advapi32/registry.c [iso-8859-1] (original) +++ trunk/rostests/winetests/advapi32/registry.c [iso-8859-1] Sun Mar 6 16:43:16 2016 @@ -44,7 +44,8 @@ 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); @@ -138,6 +139,7 @@
/* 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); @@ -1343,6 +1345,13 @@ 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); @@ -2082,10 +2091,106 @@ 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; + DWORD dwsize, type; LONG size, ret;
if(!pRegDeleteTreeA) { @@ -2131,7 +2236,9 @@ 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); @@ -2146,8 +2253,8 @@ 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"); @@ -3279,6 +3386,18 @@
RegDeleteKeyA(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) @@ -3305,16 +3424,16 @@ test_classesroot(); test_classesroot_enum(); test_classesroot_mask(); - 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_RegOpenCurrentUser();
/* cleanup */ delete_key( hkey_main );
Modified: trunk/rostests/winetests/advapi32/security.c URL: http://svn.reactos.org/svn/reactos/trunk/rostests/winetests/advapi32/securit... ============================================================================== --- trunk/rostests/winetests/advapi32/security.c [iso-8859-1] (original) +++ trunk/rostests/winetests/advapi32/security.c [iso-8859-1] Sun Mar 6 16:43:16 2016 @@ -38,6 +38,11 @@ #include <winsvc.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 @@ -135,6 +140,7 @@ 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; @@ -147,6 +153,35 @@ }; #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 { @@ -199,6 +234,7 @@ 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 ); } @@ -241,7 +277,8 @@ 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); @@ -259,7 +296,8 @@ 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); @@ -1381,6 +1419,158 @@ 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; @@ -1392,7 +1582,7 @@ "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); @@ -1405,16 +1595,66 @@ 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); - 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); + 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", @@ -2187,7 +2427,8 @@ 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); @@ -3186,15 +3427,10 @@ bret = pGetAclInformation(dacl, &acl_size, sizeof(acl_size), AclSizeInformation); ok_(__FILE__, line)(bret, "GetAclInformation failed\n");
- if (todo_count) - todo_wine + todo_wine_if (todo_count) ok_(__FILE__, line)(acl_size.AceCount == 2, "GetAclInformation returned unexpected entry count (%d != 2)\n", acl_size.AceCount); - else - ok_(__FILE__, line)(acl_size.AceCount == 2, - "GetAclInformation returned unexpected entry count (%d != 2)\n", - acl_size.AceCount);
if (acl_size.AceCount > 0) { @@ -3202,21 +3438,13 @@ 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"); - - if (todo_flags) - todo_wine + 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)); + + 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); - else - 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->Mask == mask, "Current User ACE has unexpected mask (0x%x != 0x%x)\n", @@ -3228,18 +3456,10 @@ 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"); - - 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_sid) + ok_(__FILE__, line)(bret, "Administators Group ACE (%s) != Administators Group SID (%s)\n", debugstr_sid(&ace->SidStart), debugstr_sid(admin_sid)); + + 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); @@ -3451,7 +3671,6 @@ 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); @@ -3510,6 +3729,7 @@ 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); @@ -3785,7 +4005,8 @@ 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, @@ -3796,7 +4017,8 @@ 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 */, @@ -3930,14 +4152,15 @@ 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 */, - "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 */ @@ -4579,7 +4802,7 @@ 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", @@ -4590,7 +4813,7 @@ 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, @@ -4817,7 +5040,8 @@
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", @@ -5472,11 +5696,8 @@ 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); } @@ -5961,7 +6182,6 @@ 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}, @@ -5993,14 +6213,10 @@ 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), - "got %s (expected 'S-1-16-8192' or 'S-1-16-12288')\n", sidname); - - LocalFree(sidname); + "got %s (expected %s or %s)\n", debugstr_sid(tml->Label.Sid), + debugstr_sid(&medium_level), debugstr_sid(&high_level)); + CloseHandle(token); }
@@ -6315,9 +6531,89 @@ 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); +} + +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) @@ -6364,4 +6660,6 @@ test_AdjustTokenPrivileges(); test_AddAce(); test_system_security_access(); -} + test_GetSidIdentifierAuthority(); + test_pseudo_tokens(); +}