Alexandre Julliard : ntdll/tests: Add tests for registry symlinks.
Alexandre Julliard
julliard at winehq.org
Fri Feb 12 10:17:45 CST 2010
Module: wine
Branch: master
Commit: ed0f34c6e33145d650355b3695c092434951d07b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ed0f34c6e33145d650355b3695c092434951d07b
Author: Alexandre Julliard <julliard at winehq.org>
Date: Fri Feb 12 16:03:27 2010 +0100
ntdll/tests: Add tests for registry symlinks.
---
dlls/ntdll/tests/reg.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 158 insertions(+), 0 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c
index bb541bb..a4802c8 100644
--- a/dlls/ntdll/tests/reg.c
+++ b/dlls/ntdll/tests/reg.c
@@ -116,6 +116,7 @@ typedef enum _KEY_VALUE_INFORMATION_CLASS {
#endif
static NTSTATUS (WINAPI * pRtlCreateUnicodeStringFromAsciiz)(PUNICODE_STRING, LPCSTR);
+static void (WINAPI * pRtlInitUnicodeString)(PUNICODE_STRING,PCWSTR);
static NTSTATUS (WINAPI * pRtlFreeUnicodeString)(PUNICODE_STRING);
static NTSTATUS (WINAPI * pNtDeleteValueKey)(IN HANDLE, IN PUNICODE_STRING);
static NTSTATUS (WINAPI * pRtlQueryRegistryValues)(IN ULONG, IN PCWSTR,IN PRTL_QUERY_REGISTRY_TABLE, IN PVOID,IN PVOID);
@@ -161,6 +162,7 @@ static BOOL InitFunctionPtrs(void)
trace("Could not load ntdll.dll\n");
return FALSE;
}
+ NTDLL_GET_PROC(RtlInitUnicodeString)
NTDLL_GET_PROC(RtlCreateUnicodeStringFromAsciiz)
NTDLL_GET_PROC(RtlCreateUnicodeString)
NTDLL_GET_PROC(RtlFreeUnicodeString)
@@ -593,6 +595,161 @@ static void test_RtlpNtQueryValueKey(void)
ok(status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got: 0x%08x\n", status);
}
+static void test_symlinks(void)
+{
+ static const WCHAR linkW[] = {'l','i','n','k',0};
+ static const WCHAR valueW[] = {'v','a','l','u','e',0};
+ static const WCHAR symlinkW[] = {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e',0};
+ static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
+ char buffer[1024];
+ KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)buffer;
+ WCHAR *target;
+ UNICODE_STRING symlink_str, link_str, target_str, value_str;
+ HANDLE root, key, link;
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+ DWORD target_len, len, dw;
+
+ pRtlInitUnicodeString( &link_str, linkW );
+ pRtlInitUnicodeString( &symlink_str, symlinkW );
+ pRtlInitUnicodeString( &target_str, targetW + 1 );
+ pRtlInitUnicodeString( &value_str, valueW );
+
+ target_len = winetestpath.Length + sizeof(targetW);
+ target = pRtlAllocateHeap( GetProcessHeap(), 0, target_len );
+ memcpy( target, winetestpath.Buffer, winetestpath.Length );
+ memcpy( target + winetestpath.Length/sizeof(WCHAR), targetW, sizeof(targetW) );
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.Attributes = 0;
+ attr.ObjectName = &winetestpath;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+
+ status = pNtCreateKey( &root, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
+ ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08x\n", status );
+
+ attr.RootDirectory = root;
+ attr.ObjectName = &link_str;
+ status = pNtCreateKey( &link, KEY_ALL_ACCESS, &attr, 0, 0, REG_OPTION_CREATE_LINK, 0 );
+ ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08x\n", status );
+
+ /* REG_SZ is not allowed */
+ status = pNtSetValueKey( link, &symlink_str, 0, REG_SZ, target, target_len );
+ todo_wine
+ ok( status == STATUS_ACCESS_DENIED, "NtSetValueKey wrong status 0x%08x\n", status );
+ status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
+ ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08x\n", status );
+ /* other values are not allowed */
+ status = pNtSetValueKey( link, &link_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
+ todo_wine
+ ok( status == STATUS_ACCESS_DENIED, "NtSetValueKey wrong status 0x%08x\n", status );
+
+ /* try opening the target through the link */
+
+ attr.ObjectName = &link_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ todo_wine
+ ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey wrong status 0x%08x\n", status );
+ if (!status) pNtClose( key );
+
+ attr.ObjectName = &target_str;
+ status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, 0, 0 );
+ ok( status == STATUS_SUCCESS, "NtCreateKey failed: 0x%08x\n", status );
+
+ dw = 0xbeef;
+ status = pNtSetValueKey( key, &value_str, 0, REG_DWORD, &dw, sizeof(dw) );
+ ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08x\n", status );
+ pNtClose( key );
+
+ attr.ObjectName = &link_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status );
+
+ len = sizeof(buffer);
+ status = pNtQueryValueKey( key, &value_str, KeyValuePartialInformation, info, len, &len );
+ todo_wine
+ {
+ ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08x\n", status );
+ ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + sizeof(DWORD), "wrong len %u\n", len );
+ }
+
+ status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
+ todo_wine
+ ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtQueryValueKey failed: 0x%08x\n", status );
+
+ /* REG_LINK can be created in non-link keys */
+ status = pNtSetValueKey( key, &symlink_str, 0, REG_LINK, target, target_len - sizeof(WCHAR) );
+ ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08x\n", status );
+ len = sizeof(buffer);
+ status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
+ ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08x\n", status );
+ ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
+ "wrong len %u\n", len );
+ status = pNtDeleteValueKey( key, &symlink_str );
+ ok( status == STATUS_SUCCESS, "NtDeleteValueKey failed: 0x%08x\n", status );
+
+ pNtClose( key );
+
+ /* now open the symlink itself */
+
+ attr.RootDirectory = root;
+ attr.Attributes = OBJ_OPENLINK;
+ attr.ObjectName = &link_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status );
+
+ len = sizeof(buffer);
+ status = pNtQueryValueKey( key, &symlink_str, KeyValuePartialInformation, info, len, &len );
+ todo_wine
+ {
+ ok( status == STATUS_SUCCESS, "NtQueryValueKey failed: 0x%08x\n", status );
+ ok( len == FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION,Data) + target_len - sizeof(WCHAR),
+ "wrong len %u\n", len );
+ }
+ pNtClose( key );
+
+ /* target with terminating null doesn't work */
+ status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, target, target_len );
+ ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08x\n", status );
+ attr.Attributes = 0;
+ attr.ObjectName = &link_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ todo_wine
+ ok( status == STATUS_OBJECT_NAME_NOT_FOUND, "NtOpenKey wrong status 0x%08x\n", status );
+ if (!status) pNtClose( key );
+
+ /* relative symlink, works only on win2k */
+ status = pNtSetValueKey( link, &symlink_str, 0, REG_LINK, targetW+1, sizeof(targetW)-2*sizeof(WCHAR) );
+ ok( status == STATUS_SUCCESS, "NtSetValueKey failed: 0x%08x\n", status );
+ attr.ObjectName = &link_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ ok( status == STATUS_SUCCESS || status == STATUS_OBJECT_NAME_NOT_FOUND,
+ "NtOpenKey wrong status 0x%08x\n", status );
+ if (!status) pNtClose( key );
+
+ status = pNtCreateKey( &key, KEY_ALL_ACCESS, &attr, 0, 0, REG_OPTION_CREATE_LINK, 0 );
+ todo_wine
+ ok( status == STATUS_OBJECT_NAME_COLLISION, "NtCreateKey failed: 0x%08x\n", status );
+ if (!status) pNtClose( key );
+
+ status = pNtDeleteKey( link );
+ ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08x\n", status );
+ pNtClose( link );
+
+ attr.ObjectName = &target_str;
+ status = pNtOpenKey( &key, KEY_ALL_ACCESS, &attr );
+ ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status );
+ status = pNtDeleteKey( key );
+ ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08x\n", status );
+ pNtClose( key );
+
+ status = pNtDeleteKey( root );
+ ok( status == STATUS_SUCCESS, "NtDeleteKey failed: 0x%08x\n", status );
+ pNtClose( root );
+}
+
START_TEST(reg)
{
static const WCHAR winetest[] = {'\\','W','i','n','e','T','e','s','t',0};
@@ -615,6 +772,7 @@ START_TEST(reg)
test_NtFlushKey();
test_NtQueryValueKey();
test_NtDeleteKey();
+ test_symlinks();
pRtlFreeUnicodeString(&winetestpath);
More information about the wine-cvs
mailing list