From: Santino Mazza smazza@codeweavers.com
Signed-off-by: Santino Mazza smazza@codeweavers.com --- dlls/ntdll/tests/reg.c | 118 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index f3c4eb15da0..c2c6759ea43 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -150,6 +150,8 @@ static NTSTATUS (WINAPI * pRtlZeroMemory)(PVOID, ULONG); static NTSTATUS (WINAPI * pRtlCreateRegistryKey)(ULONG, PWSTR); static NTSTATUS (WINAPI * pRtlpNtQueryValueKey)(HANDLE,ULONG*,PBYTE,DWORD*,void *); static NTSTATUS (WINAPI * pNtNotifyChangeKey)(HANDLE,HANDLE,PIO_APC_ROUTINE,PVOID,PIO_STATUS_BLOCK,ULONG,BOOLEAN,PVOID,ULONG,BOOLEAN); +static NTSTATUS (WINAPI * pNtLoadKeyEx)(const OBJECT_ATTRIBUTES *, OBJECT_ATTRIBUTES *, ULONG, HANDLE, HANDLE, ACCESS_MASK, HANDLE*, IO_STATUS_BLOCK*); +static NTSTATUS (WINAPI * pNtUnloadKey)( OBJECT_ATTRIBUTES * ); static NTSTATUS (WINAPI * pNtNotifyChangeMultipleKeys)(HANDLE,ULONG,OBJECT_ATTRIBUTES*,HANDLE,PIO_APC_ROUTINE, void*,IO_STATUS_BLOCK*,ULONG,BOOLEAN,void*,ULONG,BOOLEAN); static NTSTATUS (WINAPI * pNtWaitForSingleObject)(HANDLE,BOOLEAN,const LARGE_INTEGER*); @@ -193,6 +195,8 @@ static BOOL InitFunctionPtrs(void) NTDLL_GET_PROC(NtSetValueKey) NTDLL_GET_PROC(NtOpenKey) NTDLL_GET_PROC(NtNotifyChangeKey) + NTDLL_GET_PROC(NtLoadKeyEx) + NTDLL_GET_PROC(NtUnloadKey) NTDLL_GET_PROC(RtlFormatCurrentUserKeyPath) NTDLL_GET_PROC(RtlCompareUnicodeString) NTDLL_GET_PROC(RtlReAllocateHeap) @@ -457,6 +461,19 @@ static void test_NtOpenKey(void) ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtOpenKey failed: 0x%08lx\n", status ); pRtlFreeUnicodeString( &str );
+ /* test if application hive is accessible */ + pRtlCreateUnicodeStringFromAsciiz( &str, "\Registry\A" ); + status = pNtOpenKey(&key, KEY_READ, &attr); + todo_wine ok( status == STATUS_ACCESS_DENIED, "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + pRtlFreeUnicodeString( &str ); + + pRtlCreateUnicodeStringFromAsciiz( &str, "\Registry\A" ); + status = pNtOpenKey(&key, KEY_CREATE_SUB_KEY, &attr); + todo_wine ok( status == STATUS_ACCESS_DENIED, "NtOpenKey failed: 0x%08lx\n", status ); + pNtClose( key ); + pRtlFreeUnicodeString( &str ); + InitializeObjectAttributes(&attr, &winetestpath, 0, 0, 0); status = pNtOpenKey(&key, KEY_WRITE|KEY_READ, &attr); ok(status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08lx\n", status); @@ -677,6 +694,12 @@ static void test_NtCreateKey(void) if (!status) pNtClose( subkey ); pRtlFreeUnicodeString( &str );
+ /* test if we can create a new application hive key */ + pRtlCreateUnicodeStringFromAsciiz( &str, "\Registry\A\FooTest" ); + status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); + todo_wine ok( status == STATUS_ACCESS_DENIED || broken(status == STATUS_OBJECT_PATH_NOT_FOUND) /* win7 */, "NtCreateKey failed: 0x%08lx\n", status ); + pRtlFreeUnicodeString( &str ); + pNtClose(key); }
@@ -2268,6 +2291,100 @@ static void test_NtRenameKey(void) pNtClose(key); }
+static BOOL set_privileges(LPCSTR privilege, BOOL set) +{ + TOKEN_PRIVILEGES tp; + HANDLE hToken; + LUID luid; + + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) + return FALSE; + + if(!LookupPrivilegeValueA(NULL, privilege, &luid)) + { + CloseHandle(hToken); + return FALSE; + } + + tp.PrivilegeCount = 1; + tp.Privileges[0].Luid = luid; + + if (set) + tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + else + tp.Privileges[0].Attributes = 0; + + AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL); + if (GetLastError() != ERROR_SUCCESS) + { + CloseHandle(hToken); + return FALSE; + } + + CloseHandle(hToken); + return TRUE; +} + +static void test_NtLoadKeyEx(void) +{ + NTSTATUS status; + DWORD size, attr; + CHAR *directory; + OBJECT_ATTRIBUTES destkey, file; + UNICODE_STRING str, filename; + HANDLE rootkey; + HANDLE hivefile; + + /* Create empty hive file */ + hivefile = CreateFileA("savedkey", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hivefile == INVALID_HANDLE_VALUE) + { + win_skip("error when creating file %ld\n", GetLastError()); + return; + } + CloseHandle(hivefile); + + size = GetFullPathNameA("savedkey", 0, NULL, NULL); + directory = malloc(size + 4); + strcpy(directory, "\??\"); + GetFullPathNameA("savedkey", size, &directory[4], NULL); + pRtlCreateUnicodeStringFromAsciiz(&filename, directory); + file.Length = sizeof(file); + + InitializeObjectAttributes(&file, &filename, OBJ_CASE_INSENSITIVE, 0, 0); + InitializeObjectAttributes(&destkey, &str, 0, 0, 0); + + /* Test for application flag (0x10) */ + pRtlCreateUnicodeStringFromAsciiz(&str, "\REGISTRY\A\test1"); + status = pNtLoadKeyEx(&destkey, &file, 0x10, 0, 0, 0, &rootkey, 0); + todo_wine ok(status == STATUS_ACCESS_DENIED || broken(status == STATUS_ACCESS_VIOLATION) /* win7 */, "NtLoadKeyEx failed: %lx\n", status); + + status = pNtLoadKeyEx(&destkey, &file, 0x10, 0, 0, GENERIC_ALL, &rootkey, 0); + todo_wine ok(status == STATUS_SUCCESS || broken(status == STATUS_ACCESS_VIOLATION) /* win7 */, "NtLoadKeyEx failed: %lx\n", status); + pNtClose(rootkey); + + DeleteFileA("savedkey"); + /* Test normal key load */ + if (!set_privileges(SE_RESTORE_NAME, TRUE) || + !set_privileges(SE_BACKUP_NAME, FALSE)) + { + win_skip("Failed to set SE_RESTORE_NAME privileges, skipping tests\n"); + return; + } + + pRtlCreateUnicodeStringFromAsciiz(&str, "\REGISTRY\Machine\test2"); + status = pNtLoadKeyEx(&destkey, &file, 0, 0, 0, 0, NULL, 0); + todo_wine ok(status == STATUS_SUCCESS, "NtLoadKeyEx failed: %lx\n", status); + pNtUnloadKey(&destkey); + + attr = GetFileAttributesA("savedkey"); + todo_wine ok(attr != INVALID_FILE_ATTRIBUTES, "expected NtLoadKeyEx to create a file\n"); + + pRtlFreeUnicodeString(&str); + pRtlFreeUnicodeString(&filename); + DeleteFileA("savedkey"); +} + START_TEST(reg) { static const WCHAR winetest[] = {'\','W','i','n','e','T','e','s','t',0}; @@ -2298,6 +2415,7 @@ START_TEST(reg) test_symlinks(); test_redirection(); test_NtRenameKey(); + test_NtLoadKeyEx();
pRtlFreeUnicodeString(&winetestpath);