mirror of
https://github.com/reactos/reactos.git
synced 2025-06-04 08:50:27 +00:00
[ADVAPI32_WINETEST]
* Sync with Wine 1.7.1. CORE-7469 svn path=/trunk/; revision=60531
This commit is contained in:
parent
cfc62dc4d1
commit
490190e205
8 changed files with 594 additions and 38 deletions
|
@ -1,8 +1,4 @@
|
|||
|
||||
add_definitions(
|
||||
-D__ROS_LONG64__
|
||||
-D_DLL -D__USE_CRTIMP)
|
||||
|
||||
list(APPEND SOURCE
|
||||
cred.c
|
||||
crypt.c
|
||||
|
@ -18,9 +14,6 @@ list(APPEND SOURCE
|
|||
testlist.c)
|
||||
|
||||
add_executable(advapi32_winetest ${SOURCE})
|
||||
|
||||
target_link_libraries(advapi32_winetest uuid)
|
||||
|
||||
set_module_type(advapi32_winetest win32cui)
|
||||
add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32 ntdll)
|
||||
add_importlibs(advapi32_winetest advapi32 ole32 msvcrt kernel32)
|
||||
add_cd_file(TARGET advapi32_winetest DESTINATION reactos/bin FOR all)
|
||||
|
|
|
@ -146,6 +146,13 @@ static void clean_up_environment(void)
|
|||
pCryptReleaseContext(hProv, 0);
|
||||
pCryptAcquireContextA(&hProv, szKeySet, NULL, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
|
||||
}
|
||||
|
||||
/* Remove container "wine_test_bad_keyset" */
|
||||
if (pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, 0))
|
||||
{
|
||||
pCryptReleaseContext(hProv, 0);
|
||||
pCryptAcquireContextA(&hProv, szBadKeySet, szRsaBaseProv, PROV_RSA_FULL, CRYPT_DELETEKEYSET);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_acquire_context(void)
|
||||
|
@ -561,7 +568,16 @@ static void test_enum_providers(void)
|
|||
if (!(provider = LocalAlloc(LMEM_ZEROINIT, providerLen)))
|
||||
return;
|
||||
|
||||
providerLen = 0xdeadbeef;
|
||||
providerLen = -1;
|
||||
result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
|
||||
ok(result, "expected TRUE, got %d\n", result);
|
||||
ok(type==dwType, "expected %d, got %d\n", dwType, type);
|
||||
if (pszProvName)
|
||||
ok(!strcmp(pszProvName, provider), "expected %s, got %s\n", pszProvName, provider);
|
||||
ok(cbName==providerLen, "expected %d, got %d\n", cbName, providerLen);
|
||||
|
||||
providerLen = -1000;
|
||||
provider[0] = 0;
|
||||
result = pCryptEnumProvidersA(dwIndex, NULL, 0, &type, provider, &providerLen);
|
||||
ok(result, "expected TRUE, got %d\n", result);
|
||||
ok(type==dwType, "expected %d, got %d\n", dwType, type);
|
||||
|
|
|
@ -637,7 +637,6 @@ static BOOL create_new_eventlog(void)
|
|||
|
||||
/* First create our eventlog */
|
||||
lret = RegOpenKeyA(HKEY_LOCAL_MACHINE, eventlogsvc, &key);
|
||||
/* FIXME: Wine stops here */
|
||||
if (lret != ERROR_SUCCESS)
|
||||
{
|
||||
skip("Could not open the EventLog service registry key\n");
|
||||
|
@ -832,11 +831,13 @@ static void test_readwrite(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
ret = GetNumberOfEventLogRecords(handle, &count);
|
||||
ok(ret, "Expected GetNumberOfEventLogRecords success : %d\n", GetLastError());
|
||||
todo_wine
|
||||
ok(count == (i + 1), "Expected %d records, got %d\n", i + 1, count);
|
||||
|
||||
oldest = 0xdeadbeef;
|
||||
ret = GetOldestEventLogRecord(handle, &oldest);
|
||||
ok(ret, "Expected GetOldestEventLogRecord success : %d\n", GetLastError());
|
||||
todo_wine
|
||||
ok(oldest == 1 ||
|
||||
(oldest > 1 && oldest != 0xdeadbeef), /* Vista SP1+, W2K8 and Win7 */
|
||||
"Expected oldest to be 1 or higher, got %d\n", oldest);
|
||||
|
@ -855,6 +856,7 @@ static void test_readwrite(void)
|
|||
count = 0xdeadbeef;
|
||||
ret = GetNumberOfEventLogRecords(handle, &count);
|
||||
ok(ret, "Expected success\n");
|
||||
todo_wine
|
||||
ok(count == i, "Expected %d records, got %d\n", i, count);
|
||||
CloseEventLog(handle);
|
||||
|
||||
|
@ -1083,6 +1085,7 @@ static void test_autocreation(void)
|
|||
lstrcatA(eventlogfile, ".evtx");
|
||||
}
|
||||
|
||||
todo_wine
|
||||
ok(GetFileAttributesA(eventlogfile) != INVALID_FILE_ATTRIBUTES,
|
||||
"Expected an eventlog file\n");
|
||||
|
||||
|
@ -1109,14 +1112,12 @@ static void cleanup_eventlog(void)
|
|||
RegDeleteValueA(key, "Sources");
|
||||
RegCloseKey(key);
|
||||
lret = RegDeleteKeyA(HKEY_LOCAL_MACHINE, winesvc);
|
||||
todo_wine
|
||||
ok(lret == ERROR_SUCCESS, "Could not delete the registry tree : %d\n", lret);
|
||||
|
||||
/* A handle to the eventlog is locked by services.exe. We can only
|
||||
* delete the eventlog file after reboot.
|
||||
*/
|
||||
bret = MoveFileExA(eventlogfile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
|
||||
todo_wine
|
||||
ok(bret, "Expected MoveFileEx to succeed: %d\n", GetLastError());
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#define _INC_WINDOWS
|
||||
#define COM_NO_WINDOWS_H
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winreg.h"
|
||||
|
@ -43,6 +45,7 @@ static NTSTATUS (WINAPI *pLsaOpenPolicy)(PLSA_UNICODE_STRING,PLSA_OBJECT_ATTRIBU
|
|||
static NTSTATUS (WINAPI *pLsaQueryInformationPolicy)(LSA_HANDLE,POLICY_INFORMATION_CLASS,PVOID*);
|
||||
static BOOL (WINAPI *pConvertSidToStringSidA)(PSID,LPSTR*);
|
||||
static NTSTATUS (WINAPI *pLsaLookupNames2)(LSA_HANDLE,ULONG,ULONG,PLSA_UNICODE_STRING,PLSA_REFERENCED_DOMAIN_LIST*,PLSA_TRANSLATED_SID2*);
|
||||
static NTSTATUS (WINAPI *pLsaLookupSids)(LSA_HANDLE,ULONG,PSID*,LSA_REFERENCED_DOMAIN_LIST**,LSA_TRANSLATED_NAME**);
|
||||
|
||||
static BOOL init(void)
|
||||
{
|
||||
|
@ -55,6 +58,7 @@ static BOOL init(void)
|
|||
pLsaQueryInformationPolicy = (void*)GetProcAddress(hadvapi32, "LsaQueryInformationPolicy");
|
||||
pConvertSidToStringSidA = (void*)GetProcAddress(hadvapi32, "ConvertSidToStringSidA");
|
||||
pLsaLookupNames2 = (void*)GetProcAddress(hadvapi32, "LsaLookupNames2");
|
||||
pLsaLookupSids = (void*)GetProcAddress(hadvapi32, "LsaLookupSids");
|
||||
|
||||
if (pLsaClose && pLsaEnumerateAccountRights && pLsaFreeMemory && pLsaOpenPolicy && pLsaQueryInformationPolicy && pConvertSidToStringSidA)
|
||||
return TRUE;
|
||||
|
@ -253,7 +257,8 @@ static void test_LsaLookupNames2(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH)
|
||||
if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
|
||||
(PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH))
|
||||
{
|
||||
skip("Non-English locale (skipping LsaLookupNames2 tests)\n");
|
||||
return;
|
||||
|
@ -351,6 +356,57 @@ static void test_LsaLookupNames2(void)
|
|||
ok(status == STATUS_SUCCESS, "LsaClose() failed, returned 0x%08x\n", status);
|
||||
}
|
||||
|
||||
static void test_LsaLookupSids(void)
|
||||
{
|
||||
LSA_REFERENCED_DOMAIN_LIST *list;
|
||||
LSA_OBJECT_ATTRIBUTES attrs;
|
||||
LSA_TRANSLATED_NAME *names;
|
||||
LSA_HANDLE policy;
|
||||
TOKEN_USER *user;
|
||||
NTSTATUS status;
|
||||
HANDLE token;
|
||||
DWORD size;
|
||||
BOOL ret;
|
||||
|
||||
memset(&attrs, 0, sizeof(attrs));
|
||||
attrs.Length = sizeof(attrs);
|
||||
|
||||
status = pLsaOpenPolicy(NULL, &attrs, POLICY_LOOKUP_NAMES, &policy);
|
||||
ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
|
||||
|
||||
ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
|
||||
ok(ret, "got %d\n", ret);
|
||||
|
||||
ret = GetTokenInformation(token, TokenUser, NULL, 0, &size);
|
||||
ok(!ret, "gotr %d\n", ret);
|
||||
|
||||
user = HeapAlloc(GetProcessHeap(), 0, size);
|
||||
ret = GetTokenInformation(token, TokenUser, user, size, &size);
|
||||
ok(ret, "got %d\n", ret);
|
||||
|
||||
status = pLsaLookupSids(policy, 1, &user->User.Sid, &list, &names);
|
||||
ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
|
||||
|
||||
ok(list->Entries > 0, "got %d\n", list->Entries);
|
||||
if (list->Entries)
|
||||
{
|
||||
ok((char*)list->Domains - (char*)list > 0, "%p, %p\n", list, list->Domains);
|
||||
ok((char*)list->Domains[0].Sid - (char*)list->Domains > 0, "%p, %p\n", list->Domains, list->Domains[0].Sid);
|
||||
ok(list->Domains[0].Name.MaximumLength > list->Domains[0].Name.Length, "got %d, %d\n", list->Domains[0].Name.MaximumLength,
|
||||
list->Domains[0].Name.Length);
|
||||
}
|
||||
|
||||
pLsaFreeMemory(names);
|
||||
pLsaFreeMemory(list);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
|
||||
CloseHandle(token);
|
||||
|
||||
status = pLsaClose(policy);
|
||||
ok(status == STATUS_SUCCESS, "got 0x%08x\n", status);
|
||||
}
|
||||
|
||||
START_TEST(lsa)
|
||||
{
|
||||
if (!init()) {
|
||||
|
@ -360,4 +416,5 @@ START_TEST(lsa)
|
|||
|
||||
test_lsa();
|
||||
test_LsaLookupNames2();
|
||||
test_LsaLookupSids();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
@ -31,11 +34,14 @@
|
|||
#include "winerror.h"
|
||||
#include "aclapi.h"
|
||||
|
||||
#define IS_HKCR(hk) ((UINT_PTR)hk > 0 && ((UINT_PTR)hk & 3) == 2)
|
||||
|
||||
static HKEY hkey_main;
|
||||
static DWORD GLE;
|
||||
|
||||
static const char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
|
||||
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 DWORD (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
|
||||
|
@ -143,6 +149,7 @@ static DWORD delete_key( HKEY hkey )
|
|||
char name[MAX_PATH];
|
||||
DWORD ret;
|
||||
|
||||
if ((ret = RegOpenKeyExA( hkey, "", 0, KEY_ENUMERATE_SUB_KEYS, &hkey ))) return ret;
|
||||
while (!(ret = RegEnumKeyA(hkey, 0, name, sizeof(name))))
|
||||
{
|
||||
HKEY tmp;
|
||||
|
@ -155,6 +162,7 @@ static DWORD delete_key( HKEY hkey )
|
|||
}
|
||||
if (ret != ERROR_NO_MORE_ITEMS) return ret;
|
||||
RegDeleteKeyA( hkey, "" );
|
||||
RegCloseKey(hkey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -823,7 +831,8 @@ static void test_get_value(void)
|
|||
|
||||
/* Query REG_EXPAND_SZ using RRF_RT_REG_EXPAND_SZ (not allowed without RRF_NOEXPAND) */
|
||||
ret = pRegGetValueA(hkey_main, NULL, "TP1_EXP_SZ", RRF_RT_REG_EXPAND_SZ, NULL, NULL, NULL);
|
||||
ok(ret == ERROR_INVALID_PARAMETER, "ret=%d\n", ret);
|
||||
/* before win8: ERROR_INVALID_PARAMETER, win8: ERROR_UNSUPPORTED_TYPE */
|
||||
ok(ret == ERROR_INVALID_PARAMETER || ret == ERROR_UNSUPPORTED_TYPE, "ret=%d\n", ret);
|
||||
|
||||
/* Query REG_EXPAND_SZ using RRF_RT_ANY */
|
||||
buf[0] = 0; type = 0xdeadbeef; size = sizeof(buf);
|
||||
|
@ -946,6 +955,39 @@ static void test_reg_open_key(void)
|
|||
"RegOpenKeyEx with KEY_WOW64_64KEY failed (err=%u)\n", ret);
|
||||
RegCloseKey(hkResult);
|
||||
|
||||
/* check special HKEYs on 64bit
|
||||
* only the lower 4 bytes of the supplied key are used
|
||||
*/
|
||||
if (ptr_size == 64)
|
||||
{
|
||||
/* HKEY_CURRENT_USER */
|
||||
ret = RegOpenKeyA(UlongToHandle(HandleToUlong(HKEY_CURRENT_USER)), "Software", &hkResult);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
|
||||
ok(hkResult != NULL, "expected hkResult != NULL\n");
|
||||
RegCloseKey(hkResult);
|
||||
|
||||
ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)1 << 32), "Software", &hkResult);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
|
||||
ok(hkResult != NULL, "expected hkResult != NULL\n");
|
||||
RegCloseKey(hkResult);
|
||||
|
||||
ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
|
||||
ok(hkResult != NULL, "expected hkResult != NULL\n");
|
||||
RegCloseKey(hkResult);
|
||||
|
||||
ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_CURRENT_USER) | (ULONG64)0xffffffff << 32), "Software", &hkResult);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
|
||||
ok(hkResult != NULL, "expected hkResult != NULL\n");
|
||||
RegCloseKey(hkResult);
|
||||
|
||||
/* HKEY_LOCAL_MACHINE */
|
||||
ret = RegOpenKeyA((HKEY)(HandleToUlong(HKEY_LOCAL_MACHINE) | (ULONG64)0xdeadbeef << 32), "Software", &hkResult);
|
||||
ok(ret == ERROR_SUCCESS, "expected ERROR_SUCCESS, got %d\n", ret);
|
||||
ok(hkResult != NULL, "expected hkResult != NULL\n");
|
||||
RegCloseKey(hkResult);
|
||||
}
|
||||
|
||||
/* Try using WOW64 flags when opening a key with a DACL set to verify that
|
||||
* the registry access check is performed correctly. Redirection isn't
|
||||
* being tested, so the tests don't care about whether the process is
|
||||
|
@ -1797,8 +1839,6 @@ static void test_symlinks(void)
|
|||
pRtlFreeUnicodeString( &target_str );
|
||||
}
|
||||
|
||||
static const DWORD ptr_size = 8 * sizeof(void*);
|
||||
|
||||
static DWORD get_key_value( HKEY root, const char *name, DWORD flags )
|
||||
{
|
||||
HKEY key;
|
||||
|
@ -2085,6 +2125,7 @@ static void test_classesroot(void)
|
|||
skip("not enough privileges to add a user class\n");
|
||||
return;
|
||||
}
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
|
||||
/* try to open that key in hkcr */
|
||||
res = RegOpenKeyExA( HKEY_CLASSES_ROOT, "WineTestCls", 0,
|
||||
|
@ -2092,6 +2133,7 @@ static void test_classesroot(void)
|
|||
todo_wine ok(res == ERROR_SUCCESS ||
|
||||
broken(res == ERROR_FILE_NOT_FOUND /* WinNT */),
|
||||
"test key not found in hkcr: %d\n", res);
|
||||
todo_wine ok(IS_HKCR(hkcr), "hkcr mask not set in %p\n", hkcr);
|
||||
if (res)
|
||||
{
|
||||
skip("HKCR key merging not supported\n");
|
||||
|
@ -2123,16 +2165,16 @@ static void test_classesroot(void)
|
|||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
|
||||
/* try to find the value in user's classes */
|
||||
res = RegQueryValueExA(hkcr, "val0", NULL, &type, (LPBYTE)buffer, &size);
|
||||
res = RegQueryValueExA(hkey, "val0", NULL, &type, (LPBYTE)buffer, &size);
|
||||
ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res);
|
||||
ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer );
|
||||
|
||||
/* modify the value in user's classes */
|
||||
res = RegSetValueExA(hkcr, "val0", 0, REG_SZ, (const BYTE *)"user", sizeof("user"));
|
||||
res = RegSetValueExA(hkey, "val0", 0, REG_SZ, (const BYTE *)"user", sizeof("user"));
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
|
||||
/* check if the value is also modified in hkcr */
|
||||
res = RegQueryValueExA(hkey, "val0", NULL, &type, (LPBYTE)buffer, &size);
|
||||
res = RegQueryValueExA(hkcr, "val0", NULL, &type, (LPBYTE)buffer, &size);
|
||||
ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
ok(!strcmp( buffer, "user" ), "value set to '%s'\n", buffer );
|
||||
|
||||
|
@ -2155,12 +2197,14 @@ static void test_classesroot(void)
|
|||
skip("not enough privileges to add a system class\n");
|
||||
return;
|
||||
}
|
||||
ok(!IS_HKCR(hklm), "hkcr mask set in %p\n", hklm);
|
||||
|
||||
/* try to open that key in hkcr */
|
||||
res = RegOpenKeyExA( HKEY_CLASSES_ROOT, "WineTestCls", 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcr );
|
||||
ok(res == ERROR_SUCCESS,
|
||||
"test key not found in hkcr: %d\n", res);
|
||||
ok(IS_HKCR(hkcr), "hkcr mask not set in %p\n", hkcr);
|
||||
if (res)
|
||||
{
|
||||
delete_key( hklm );
|
||||
|
@ -2181,19 +2225,21 @@ static void test_classesroot(void)
|
|||
res = RegSetValueExA(hkcr, "val2", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr"));
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
|
||||
/* check that the value is not modified in hklm classes */
|
||||
/* check that the value is modified in hklm classes */
|
||||
res = RegQueryValueExA(hklm, "val2", NULL, &type, (LPBYTE)buffer, &size);
|
||||
ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
ok(!strcmp( buffer, "hklm" ), "value set to '%s'\n", buffer );
|
||||
ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer );
|
||||
|
||||
if (RegCreateKeyExA( HKEY_CURRENT_USER, "Software\\Classes\\WineTestCls", 0, NULL, 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, &hkey, NULL )) return;
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
|
||||
/* try to open that key in hkcr */
|
||||
res = RegOpenKeyExA( HKEY_CLASSES_ROOT, "WineTestCls", 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcr );
|
||||
ok(res == ERROR_SUCCESS,
|
||||
"test key not found in hkcr: %d\n", res);
|
||||
ok(IS_HKCR(hkcr), "hkcr mask not set in %p\n", hkcr);
|
||||
|
||||
/* set a value in user's classes */
|
||||
res = RegSetValueExA(hkey, "val2", 0, REG_SZ, (const BYTE *)"user", sizeof("user"));
|
||||
|
@ -2231,9 +2277,11 @@ static void test_classesroot(void)
|
|||
/* create a subkey in hklm */
|
||||
if (RegCreateKeyExA( hklm, "subkey1", 0, NULL, 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, &hklmsub1, NULL )) return;
|
||||
ok(!IS_HKCR(hklmsub1), "hkcr mask set in %p\n", hklmsub1);
|
||||
/* try to open that subkey in hkcr */
|
||||
res = RegOpenKeyExA( hkcr, "subkey1", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hkcrsub1 );
|
||||
ok(res == ERROR_SUCCESS, "test key not found in hkcr: %d\n", res);
|
||||
ok(IS_HKCR(hkcrsub1), "hkcr mask not set in %p\n", hkcrsub1);
|
||||
|
||||
/* set a value in hklm classes */
|
||||
res = RegSetValueExA(hklmsub1, "subval1", 0, REG_SZ, (const BYTE *)"hklm", sizeof("hklm"));
|
||||
|
@ -2256,6 +2304,7 @@ static void test_classesroot(void)
|
|||
/* create a subkey in user's classes */
|
||||
if (RegCreateKeyExA( hkey, "subkey1", 0, NULL, 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, &hkeysub1, NULL )) return;
|
||||
ok(!IS_HKCR(hkeysub1), "hkcr mask set in %p\n", hkeysub1);
|
||||
|
||||
/* set a value in user's classes */
|
||||
res = RegSetValueExA(hkeysub1, "subval1", 0, REG_SZ, (const BYTE *)"user", sizeof("user"));
|
||||
|
@ -2293,6 +2342,7 @@ static void test_classesroot(void)
|
|||
/* new subkey in hkcr */
|
||||
if (RegCreateKeyExA( hkcr, "subkey2", 0, NULL, 0,
|
||||
KEY_QUERY_VALUE|KEY_SET_VALUE, NULL, &hkcrsub2, NULL )) return;
|
||||
ok(IS_HKCR(hkcrsub2), "hkcr mask not set in %p\n", hkcrsub2);
|
||||
res = RegSetValueExA(hkcrsub2, "subval1", 0, REG_SZ, (const BYTE *)"hkcr", sizeof("hkcr"));
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d, GLE=%x\n", res, GetLastError());
|
||||
|
||||
|
@ -2302,12 +2352,37 @@ static void test_classesroot(void)
|
|||
hklmsub2 = 0;
|
||||
res = RegOpenKeyExA( hklm, "subkey2", 0, KEY_QUERY_VALUE|KEY_SET_VALUE, &hklmsub2 );
|
||||
ok(res == ERROR_SUCCESS, "test key not found in hklm: %d\n", res);
|
||||
ok(!IS_HKCR(hklmsub2), "hkcr mask set in %p\n", hklmsub2);
|
||||
|
||||
/* check that the value is present in hklm */
|
||||
res = RegQueryValueExA(hklmsub2, "subval1", NULL, &type, (LPBYTE)buffer, &size);
|
||||
ok(res == ERROR_SUCCESS, "RegQueryValueExA failed: %d\n", res);
|
||||
ok(!strcmp( buffer, "hkcr" ), "value set to '%s'\n", buffer );
|
||||
|
||||
/* cleanup */
|
||||
RegCloseKey( hkeysub1 );
|
||||
RegCloseKey( hklmsub1 );
|
||||
|
||||
/* delete subkey1 from hkcr (should point at user's classes) */
|
||||
res = RegDeleteKey(hkcr, "subkey1");
|
||||
ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res);
|
||||
|
||||
/* confirm key was removed in hkey but not hklm */
|
||||
res = RegOpenKeyExA(hkey, "subkey1", 0, KEY_READ, &hkeysub1);
|
||||
ok(res == ERROR_FILE_NOT_FOUND, "test key found in user's classes: %d\n", res);
|
||||
res = RegOpenKeyExA(hklm, "subkey1", 0, KEY_READ, &hklmsub1);
|
||||
ok(res == ERROR_SUCCESS, "test key not found in hklm: %d\n", res);
|
||||
ok(!IS_HKCR(hklmsub1), "hkcr mask set in %p\n", hklmsub1);
|
||||
|
||||
/* delete subkey1 from hkcr again (which should now point at hklm) */
|
||||
res = RegDeleteKey(hkcr, "subkey1");
|
||||
ok(res == ERROR_SUCCESS, "RegDeleteKey failed: %d\n", res);
|
||||
|
||||
/* confirm hkey was removed in hklm */
|
||||
RegCloseKey( hklmsub1 );
|
||||
res = RegOpenKeyExA(hklm, "subkey1", 0, KEY_READ, &hklmsub1);
|
||||
ok(res == ERROR_FILE_NOT_FOUND, "test key found in hklm: %d\n", res);
|
||||
|
||||
/* final cleanup */
|
||||
delete_key( hkey );
|
||||
delete_key( hklm );
|
||||
|
@ -2327,6 +2402,214 @@ static void test_classesroot(void)
|
|||
RegCloseKey( hkcrsub2 );
|
||||
}
|
||||
|
||||
static void test_classesroot_enum(void)
|
||||
{
|
||||
HKEY hkcu=0, hklm=0, hkcr=0, hkcusub[2]={0}, hklmsub[2]={0};
|
||||
DWORD size;
|
||||
static CHAR buffer[2];
|
||||
LONG res;
|
||||
|
||||
/* prepare initial testing env in HKCU */
|
||||
if (!RegOpenKeyA( HKEY_CURRENT_USER, "Software\\Classes\\WineTestCls", &hkcu ))
|
||||
{
|
||||
delete_key( hkcu );
|
||||
RegCloseKey( hkcu );
|
||||
}
|
||||
res = RegCreateKeyExA( HKEY_CURRENT_USER, "Software\\Classes\\WineTestCls", 0, NULL, 0,
|
||||
KEY_SET_VALUE|KEY_ENUMERATE_SUB_KEYS, NULL, &hkcu, NULL );
|
||||
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
skip("failed to add a user class\n");
|
||||
return;
|
||||
}
|
||||
|
||||
res = RegOpenKeyA( HKEY_CLASSES_ROOT, "WineTestCls", &hkcr );
|
||||
todo_wine ok(res == ERROR_SUCCESS ||
|
||||
broken(res == ERROR_FILE_NOT_FOUND /* WinNT */),
|
||||
"test key not found in hkcr: %d\n", res);
|
||||
if (res)
|
||||
{
|
||||
skip("HKCR key merging not supported\n");
|
||||
delete_key( hkcu );
|
||||
RegCloseKey( hkcu );
|
||||
return;
|
||||
}
|
||||
|
||||
res = RegSetValueExA( hkcu, "X", 0, REG_SZ, (const BYTE *) "AA", 3 );
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res);
|
||||
res = RegSetValueExA( hkcu, "Y", 0, REG_SZ, (const BYTE *) "B", 2 );
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res);
|
||||
res = RegCreateKeyA( hkcu, "A", &hkcusub[0] );
|
||||
ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res);
|
||||
res = RegCreateKeyA( hkcu, "B", &hkcusub[1] );
|
||||
ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res);
|
||||
|
||||
/* test on values in HKCU */
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "Y" ), "expected 'Y', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
res = RegEnumKeyA( hkcr, 0, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 1, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "B" ), "expected 'B', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 2, buffer, size );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
/* prepare test env in HKLM */
|
||||
if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Classes\\WineTestCls", &hklm ))
|
||||
{
|
||||
delete_key( hklm );
|
||||
RegCloseKey( hklm );
|
||||
}
|
||||
|
||||
res = RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Classes\\WineTestCls", 0, NULL, 0,
|
||||
KEY_SET_VALUE|KEY_ENUMERATE_SUB_KEYS, NULL, &hklm, NULL );
|
||||
|
||||
if (res == ERROR_ACCESS_DENIED)
|
||||
{
|
||||
RegCloseKey( hkcusub[0] );
|
||||
RegCloseKey( hkcusub[1] );
|
||||
delete_key( hkcu );
|
||||
RegCloseKey( hkcu );
|
||||
RegCloseKey( hkcr );
|
||||
skip("not enough privileges to add a system class\n");
|
||||
return;
|
||||
}
|
||||
|
||||
res = RegSetValueExA( hklm, "X", 0, REG_SZ, (const BYTE *) "AB", 3 );
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res);
|
||||
res = RegSetValueExA( hklm, "Z", 0, REG_SZ, (const BYTE *) "C", 2 );
|
||||
ok(res == ERROR_SUCCESS, "RegSetValueExA failed: %d\n", res);
|
||||
res = RegCreateKeyA( hklm, "A", &hklmsub[0] );
|
||||
ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res);
|
||||
res = RegCreateKeyA( hklm, "C", &hklmsub[1] );
|
||||
ok(res == ERROR_SUCCESS, "RegCreateKeyA failed: %d\n", res);
|
||||
|
||||
/* test on values/keys in both HKCU and HKLM */
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "Y" ), "expected 'Y', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "Z" ), "expected 'Z', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 3, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
res = RegEnumKeyA( hkcr, 0, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 1, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "B" ), "expected 'B', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 2, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "C" ), "expected 'C', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 3, buffer, size );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
/* delete values/keys from HKCU to test only on HKLM */
|
||||
RegCloseKey( hkcusub[0] );
|
||||
RegCloseKey( hkcusub[1] );
|
||||
delete_key( hkcu );
|
||||
RegCloseKey( hkcu );
|
||||
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_KEY_DELETED ||
|
||||
res == ERROR_NO_SYSTEM_RESOURCES, /* Windows XP */
|
||||
"expected ERROR_KEY_DELETED, got %d\n", res);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumKeyA( hkcr, 0, buffer, size );
|
||||
ok(res == ERROR_KEY_DELETED ||
|
||||
res == ERROR_NO_SYSTEM_RESOURCES, /* Windows XP */
|
||||
"expected ERROR_KEY_DELETED, got %d\n", res);
|
||||
|
||||
/* reopen HKCR handle */
|
||||
RegCloseKey( hkcr );
|
||||
res = RegOpenKeyA( HKEY_CLASSES_ROOT, "WineTestCls", &hkcr );
|
||||
ok(res == ERROR_SUCCESS, "test key not found in hkcr: %d\n", res);
|
||||
if (res) goto cleanup;
|
||||
|
||||
/* test on values/keys in HKLM */
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 0, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "X" ), "expected 'X', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 1, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumValueA failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "Z" ), "expected 'Z', got '%s'\n", buffer);
|
||||
size = sizeof(buffer);
|
||||
res = RegEnumValueA( hkcr, 2, buffer, &size, NULL, NULL, NULL, NULL );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
res = RegEnumKeyA( hkcr, 0, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "A" ), "expected 'A', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 1, buffer, size );
|
||||
ok(res == ERROR_SUCCESS, "RegEnumKey failed: %d\n", res );
|
||||
ok(!strcmp( buffer, "C" ), "expected 'C', got '%s'\n", buffer);
|
||||
res = RegEnumKeyA( hkcr, 2, buffer, size );
|
||||
ok(res == ERROR_NO_MORE_ITEMS, "expected ERROR_NO_MORE_ITEMS, got %d\n", res );
|
||||
|
||||
cleanup:
|
||||
RegCloseKey( hklmsub[0] );
|
||||
RegCloseKey( hklmsub[1] );
|
||||
delete_key( hklm );
|
||||
RegCloseKey( hklm );
|
||||
RegCloseKey( hkcr );
|
||||
}
|
||||
|
||||
static void test_classesroot_mask(void)
|
||||
{
|
||||
HKEY hkey;
|
||||
LSTATUS res;
|
||||
|
||||
res = RegOpenKeyA( HKEY_CLASSES_ROOT, "CLSID", &hkey );
|
||||
ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res);
|
||||
todo_wine ok(IS_HKCR(hkey), "hkcr mask not set in %p\n", hkey);
|
||||
RegCloseKey( hkey );
|
||||
|
||||
res = RegOpenKeyA( HKEY_CURRENT_USER, "Software", &hkey );
|
||||
ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res);
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
RegCloseKey( hkey );
|
||||
|
||||
res = RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software", &hkey );
|
||||
ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res);
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
RegCloseKey( hkey );
|
||||
|
||||
res = RegOpenKeyA( HKEY_USERS, ".Default", &hkey );
|
||||
ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res);
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
RegCloseKey( hkey );
|
||||
|
||||
res = RegOpenKeyA( HKEY_CURRENT_CONFIG, "Software", &hkey );
|
||||
ok(res == ERROR_SUCCESS, "RegOpenKeyA failed: %d\n", res);
|
||||
ok(!IS_HKCR(hkey), "hkcr mask set in %p\n", hkey);
|
||||
RegCloseKey( hkey );
|
||||
}
|
||||
|
||||
static void test_deleted_key(void)
|
||||
{
|
||||
HKEY hkey, hkey2;
|
||||
|
@ -2420,6 +2703,8 @@ START_TEST(registry)
|
|||
test_symlinks();
|
||||
test_redirection();
|
||||
test_classesroot();
|
||||
test_classesroot_enum();
|
||||
test_classesroot_mask();
|
||||
|
||||
/* SaveKey/LoadKey require the SE_BACKUP_NAME privilege to be set */
|
||||
if (set_privileges(SE_BACKUP_NAME, TRUE) &&
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
|
@ -3007,10 +3008,15 @@ static void test_SetEntriesInAclA(void)
|
|||
|
||||
static void test_GetNamedSecurityInfoA(void)
|
||||
{
|
||||
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], dacl[100], *user;
|
||||
char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user;
|
||||
char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
|
||||
char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES];
|
||||
PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr;
|
||||
PSID system_sid = (PSID) system_ptr, user_sid;
|
||||
DWORD sid_size = sizeof(admin_ptr), user_size;
|
||||
char invalid_path[] = "/an invalid file path";
|
||||
PSID admin_sid = (PSID) admin_ptr, user_sid;
|
||||
int users_ace_id = -1, admins_ace_id = -1, i;
|
||||
char software_key[] = "MACHINE\\Software";
|
||||
char sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||
SECURITY_DESCRIPTOR_CONTROL control;
|
||||
ACL_SIZE_INFORMATION acl_size;
|
||||
|
@ -3022,9 +3028,12 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
DWORD error, revision;
|
||||
BOOL owner_defaulted;
|
||||
BOOL group_defaulted;
|
||||
BOOL dacl_defaulted;
|
||||
HANDLE token, hTemp;
|
||||
PSID owner, group;
|
||||
BOOL dacl_present;
|
||||
PACL pDacl;
|
||||
BYTE flags;
|
||||
|
||||
if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid)
|
||||
{
|
||||
|
@ -3115,13 +3124,12 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
|
||||
/* Create security descriptor information and test that it comes back the same */
|
||||
pSD = &sd;
|
||||
pDacl = (PACL)&dacl;
|
||||
pDacl = HeapAlloc(GetProcessHeap(), 0, 100);
|
||||
InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
|
||||
pCreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, admin_sid, &sid_size);
|
||||
bret = InitializeAcl(pDacl, sizeof(dacl), ACL_REVISION);
|
||||
bret = InitializeAcl(pDacl, 100, ACL_REVISION);
|
||||
ok(bret, "Failed to initialize ACL.\n");
|
||||
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, user_sid);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
ok(bret, "Failed to add Current User to ACL.\n");
|
||||
bret = pAddAccessAllowedAceEx(pDacl, ACL_REVISION, 0, GENERIC_ALL, admin_sid);
|
||||
ok(bret, "Failed to add Administrator Group to ACL.\n");
|
||||
|
@ -3133,9 +3141,11 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
SetLastError(0xdeadbeef);
|
||||
error = pSetNamedSecurityInfoA(tmpfile, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, pDacl, NULL);
|
||||
HeapFree(GetProcessHeap(), 0, pDacl);
|
||||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
{
|
||||
win_skip("SetNamedSecurityInfoA is not implemented\n");
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
CloseHandle(hTemp);
|
||||
return;
|
||||
}
|
||||
|
@ -3146,6 +3156,8 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
if (error != ERROR_SUCCESS && (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED))
|
||||
{
|
||||
win_skip("GetNamedSecurityInfoA is not implemented\n");
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
CloseHandle(hTemp);
|
||||
return;
|
||||
}
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
@ -3176,7 +3188,80 @@ static void test_GetNamedSecurityInfoA(void)
|
|||
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
HeapFree(GetProcessHeap(), 0, user);
|
||||
CloseHandle(hTemp);
|
||||
|
||||
/* Test querying the ownership of a built-in registry key */
|
||||
sid_size = sizeof(system_ptr);
|
||||
pCreateWellKnownSid(WinLocalSystemSid, NULL, system_sid, &sid_size);
|
||||
error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY,
|
||||
OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION,
|
||||
NULL, NULL, NULL, NULL, &pSD);
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
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");
|
||||
|
||||
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");
|
||||
LocalFree(pSD);
|
||||
|
||||
/* Test querying the DACL of a built-in registry key */
|
||||
sid_size = sizeof(users_ptr);
|
||||
pCreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size);
|
||||
error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION,
|
||||
NULL, NULL, NULL, NULL, &pSD);
|
||||
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
|
||||
|
||||
bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted);
|
||||
ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError());
|
||||
ok(dacl_present, "DACL should be present\n");
|
||||
ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n");
|
||||
bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation);
|
||||
ok(bret, "GetAclInformation failed\n");
|
||||
ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n");
|
||||
for (i=0; i<acl_size.AceCount; i++)
|
||||
{
|
||||
bret = pGetAce(pDacl, i, (VOID **)&ace);
|
||||
ok(bret, "Failed to get ACE %d.\n", i);
|
||||
bret = EqualSid(&ace->SidStart, users_sid);
|
||||
if (bret) users_ace_id = i;
|
||||
bret = EqualSid(&ace->SidStart, admin_sid);
|
||||
if (bret) admins_ace_id = i;
|
||||
}
|
||||
ok(users_ace_id != -1 || broken(users_ace_id == -1) /* win2k */,
|
||||
"Bultin Users ACE not found.\n");
|
||||
if (users_ace_id != -1)
|
||||
{
|
||||
bret = pGetAce(pDacl, users_ace_id, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Builtin Users ACE.\n");
|
||||
flags = ((ACE_HEADER *)ace)->AceFlags;
|
||||
ok(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE)
|
||||
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */,
|
||||
"Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", flags,
|
||||
INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE);
|
||||
ok(ace->Mask == GENERIC_READ, "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n",
|
||||
ace->Mask, GENERIC_READ);
|
||||
}
|
||||
ok(admins_ace_id != -1, "Bultin Admins ACE not found.\n");
|
||||
if (admins_ace_id != -1)
|
||||
{
|
||||
bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace);
|
||||
ok(bret, "Failed to get Builtin Admins ACE.\n");
|
||||
flags = ((ACE_HEADER *)ace)->AceFlags;
|
||||
ok(flags == 0x0
|
||||
|| broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */,
|
||||
"Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags);
|
||||
ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */,
|
||||
"Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS);
|
||||
}
|
||||
LocalFree(pSD);
|
||||
}
|
||||
|
||||
static void test_ConvertStringSecurityDescriptor(void)
|
||||
|
@ -4077,6 +4162,8 @@ static void test_CreateRestrictedToken(void)
|
|||
HANDLE process_token, token, r_token;
|
||||
PTOKEN_GROUPS token_groups, groups2;
|
||||
SID_AND_ATTRIBUTES sattr;
|
||||
SECURITY_IMPERSONATION_LEVEL level;
|
||||
TOKEN_TYPE type;
|
||||
BOOL is_member;
|
||||
DWORD size;
|
||||
BOOL ret;
|
||||
|
@ -4127,7 +4214,7 @@ static void test_CreateRestrictedToken(void)
|
|||
sattr.Attributes = 0;
|
||||
r_token = NULL;
|
||||
ret = pCreateRestrictedToken(token, 0, 1, &sattr, 0, NULL, 0, NULL, &r_token);
|
||||
todo_wine ok(ret, "got error %d\n", GetLastError());
|
||||
ok(ret, "got error %d\n", GetLastError());
|
||||
|
||||
if (ret)
|
||||
{
|
||||
|
@ -4135,7 +4222,7 @@ static void test_CreateRestrictedToken(void)
|
|||
is_member = TRUE;
|
||||
ret = pCheckTokenMembership(r_token, token_groups->Groups[i].Sid, &is_member);
|
||||
ok(ret, "got error %d\n", GetLastError());
|
||||
ok(!is_member, "not a member\n");
|
||||
todo_wine ok(!is_member, "not a member\n");
|
||||
|
||||
ret = GetTokenInformation(r_token, TokenGroups, NULL, 0, &size);
|
||||
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "got %d with error %d\n",
|
||||
|
@ -4150,12 +4237,22 @@ static void test_CreateRestrictedToken(void)
|
|||
break;
|
||||
}
|
||||
|
||||
ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY,
|
||||
todo_wine ok(groups2->Groups[j].Attributes & SE_GROUP_USE_FOR_DENY_ONLY,
|
||||
"got wrong attributes\n");
|
||||
ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0,
|
||||
todo_wine ok((groups2->Groups[j].Attributes & SE_GROUP_ENABLED) == 0,
|
||||
"got wrong attributes\n");
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, groups2);
|
||||
|
||||
size = sizeof(type);
|
||||
ret = GetTokenInformation(r_token, TokenType, &type, size, &size);
|
||||
ok(ret, "got error %d\n", GetLastError());
|
||||
ok(type == TokenImpersonation, "got type %u\n", type);
|
||||
|
||||
size = sizeof(level);
|
||||
ret = GetTokenInformation(r_token, TokenImpersonationLevel, &level, size, &size);
|
||||
ok(ret, "got error %d\n", GetLastError());
|
||||
ok(level == SecurityImpersonation, "got level %u\n", type);
|
||||
}
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, token_groups);
|
||||
|
@ -4497,6 +4594,64 @@ static void test_TokenIntegrityLevel(void)
|
|||
CloseHandle(token);
|
||||
}
|
||||
|
||||
static void test_default_dacl_owner_sid(void)
|
||||
{
|
||||
HANDLE handle;
|
||||
BOOL ret, defaulted, present, found;
|
||||
DWORD size, index;
|
||||
SECURITY_DESCRIPTOR *sd;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
PSID owner;
|
||||
ACL *dacl;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
|
||||
sd = HeapAlloc( GetProcessHeap(), 0, SECURITY_DESCRIPTOR_MIN_LENGTH );
|
||||
ret = InitializeSecurityDescriptor( sd, SECURITY_DESCRIPTOR_REVISION );
|
||||
ok( ret, "error %u\n", GetLastError() );
|
||||
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.lpSecurityDescriptor = sd;
|
||||
sa.bInheritHandle = FALSE;
|
||||
handle = CreateEvent( &sa, TRUE, TRUE, "test_event" );
|
||||
ok( handle != NULL, "error %u\n", GetLastError() );
|
||||
|
||||
size = 0;
|
||||
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, NULL, 0, &size );
|
||||
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER, "error %u\n", GetLastError() );
|
||||
|
||||
sd = HeapAlloc( GetProcessHeap(), 0, size );
|
||||
ret = GetKernelObjectSecurity( handle, OWNER_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, sd, size, &size );
|
||||
ok( ret, "error %u\n", GetLastError() );
|
||||
|
||||
owner = (void *)0xdeadbeef;
|
||||
defaulted = TRUE;
|
||||
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" );
|
||||
|
||||
dacl = (void *)0xdeadbeef;
|
||||
present = FALSE;
|
||||
defaulted = TRUE;
|
||||
ret = GetSecurityDescriptorDacl( sd, &present, &dacl, &defaulted );
|
||||
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" );
|
||||
|
||||
index = 0;
|
||||
found = FALSE;
|
||||
while (pGetAce( dacl, index++, (void **)&ace ))
|
||||
{
|
||||
if (EqualSid( &ace->SidStart, owner )) found = TRUE;
|
||||
}
|
||||
ok( found, "owner sid not found in dacl\n" );
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, sa.lpSecurityDescriptor );
|
||||
HeapFree( GetProcessHeap(), 0, sd );
|
||||
CloseHandle( handle );
|
||||
}
|
||||
|
||||
START_TEST(security)
|
||||
{
|
||||
init();
|
||||
|
@ -4535,4 +4690,5 @@ START_TEST(security)
|
|||
test_GetUserNameW();
|
||||
test_CreateRestrictedToken();
|
||||
test_TokenIntegrityLevel();
|
||||
test_default_dacl_owner_sid();
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define WIN32_NO_STATUS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
@ -48,6 +51,8 @@ static BOOL (WINAPI *pQueryServiceConfig2A)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD
|
|||
static BOOL (WINAPI *pQueryServiceConfig2W)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
|
||||
static BOOL (WINAPI *pQueryServiceStatusEx)(SC_HANDLE, SC_STATUS_TYPE, LPBYTE,
|
||||
DWORD, LPDWORD);
|
||||
static BOOL (WINAPI *pQueryServiceObjectSecurity)(SC_HANDLE, SECURITY_INFORMATION,
|
||||
PSECURITY_DESCRIPTOR, DWORD, LPDWORD);
|
||||
|
||||
static void init_function_pointers(void)
|
||||
{
|
||||
|
@ -60,6 +65,7 @@ static void init_function_pointers(void)
|
|||
pQueryServiceConfig2A= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2A");
|
||||
pQueryServiceConfig2W= (void*)GetProcAddress(hadvapi32, "QueryServiceConfig2W");
|
||||
pQueryServiceStatusEx= (void*)GetProcAddress(hadvapi32, "QueryServiceStatusEx");
|
||||
pQueryServiceObjectSecurity = (void*)GetProcAddress(hadvapi32, "QueryServiceObjectSecurity");
|
||||
}
|
||||
|
||||
static void test_open_scm(void)
|
||||
|
@ -1756,7 +1762,7 @@ static void test_close(void)
|
|||
static void test_sequence(void)
|
||||
{
|
||||
SC_HANDLE scm_handle, svc_handle;
|
||||
BOOL ret;
|
||||
BOOL ret, is_nt4;
|
||||
QUERY_SERVICE_CONFIGA *config;
|
||||
DWORD given, needed;
|
||||
static const CHAR servicename [] = "Winetest";
|
||||
|
@ -1780,6 +1786,9 @@ static void test_sequence(void)
|
|||
ok(scm_handle != NULL, "Could not get a handle to the manager: %d\n", GetLastError());
|
||||
|
||||
if (!scm_handle) return;
|
||||
svc_handle = OpenServiceA(scm_handle, NULL, GENERIC_READ);
|
||||
is_nt4=(svc_handle == NULL && GetLastError() == ERROR_INVALID_PARAMETER);
|
||||
CloseServiceHandle(svc_handle);
|
||||
|
||||
/* Create a dummy service */
|
||||
SetLastError(0xdeadbeef);
|
||||
|
@ -1817,12 +1826,54 @@ static void test_sequence(void)
|
|||
PSID sidOwner, sidGroup;
|
||||
PACL dacl, sacl;
|
||||
PSECURITY_DESCRIPTOR pSD;
|
||||
HRESULT retval = pGetSecurityInfo(svc_handle,SE_SERVICE,DACL_SECURITY_INFORMATION,&sidOwner,&sidGroup,&dacl,&sacl,&pSD);
|
||||
todo_wine ok(ERROR_SUCCESS == retval, "Expected GetSecurityInfo to succeed: result %d\n",retval);
|
||||
DWORD error, n1, n2;
|
||||
HRESULT retval;
|
||||
BOOL bret;
|
||||
|
||||
/* Test using GetSecurityInfo to obtain security information */
|
||||
retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, &sidOwner,
|
||||
&sidGroup, &dacl, &sacl, &pSD);
|
||||
LocalFree(pSD);
|
||||
ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
|
||||
retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, NULL, NULL, &pSD);
|
||||
LocalFree(pSD);
|
||||
ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
|
||||
if (!is_nt4)
|
||||
{
|
||||
retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, &dacl, NULL, NULL);
|
||||
ok(retval == ERROR_SUCCESS, "Expected GetSecurityInfo to succeed: result %d\n", retval);
|
||||
SetLastError(0xdeadbeef);
|
||||
retval = pGetSecurityInfo(svc_handle, SE_SERVICE, DACL_SECURITY_INFORMATION, NULL,
|
||||
NULL, NULL, NULL, NULL);
|
||||
error = GetLastError();
|
||||
ok(retval == ERROR_INVALID_PARAMETER, "Expected GetSecurityInfo to fail: result %d\n", retval);
|
||||
ok(error == 0xdeadbeef, "Unexpected last error %d\n", error);
|
||||
}
|
||||
else
|
||||
win_skip("A NULL security descriptor in GetSecurityInfo results in an exception on NT4.\n");
|
||||
|
||||
/* Test using QueryServiceObjectSecurity to obtain security information */
|
||||
SetLastError(0xdeadbeef);
|
||||
bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, NULL, 0, &n1);
|
||||
error = GetLastError();
|
||||
ok(!bret, "Expected QueryServiceObjectSecurity to fail: result %d\n", bret);
|
||||
ok(error == ERROR_INSUFFICIENT_BUFFER ||
|
||||
broken(error == ERROR_INVALID_ADDRESS) || broken(error == ERROR_INVALID_PARAMETER),
|
||||
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", error);
|
||||
if (error != ERROR_INSUFFICIENT_BUFFER) n1 = 1024;
|
||||
pSD = LocalAlloc(0, n1);
|
||||
bret = pQueryServiceObjectSecurity(svc_handle, DACL_SECURITY_INFORMATION, pSD, n1, &n2);
|
||||
ok(bret, "Expected QueryServiceObjectSecurity to succeed: result %d\n", bret);
|
||||
LocalFree(pSD);
|
||||
}
|
||||
}
|
||||
|
||||
if (!svc_handle) return;
|
||||
if (!svc_handle) {
|
||||
CloseServiceHandle(scm_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
* Before we do a QueryServiceConfig we should check the registry. This will make sure
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
/* Automatically generated file; DO NOT EDIT!! */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#define STANDALONE
|
||||
#include "wine/test.h"
|
||||
#include <wine/test.h>
|
||||
|
||||
extern void func_cred(void);
|
||||
extern void func_crypt(void);
|
||||
|
|
Loading…
Reference in a new issue