Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/ntdll/tests/reg.c | 2 -- server/registry.c | 26 +++++++++++++++++++++++--- 2 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/dlls/ntdll/tests/reg.c b/dlls/ntdll/tests/reg.c index 91b752ac069..74d82b85be4 100644 --- a/dlls/ntdll/tests/reg.c +++ b/dlls/ntdll/tests/reg.c @@ -417,7 +417,6 @@ todo_wine
pRtlCreateUnicodeStringFromAsciiz( &str, "\Registry" ); status = pNtOpenKey(&key, KEY_READ, &attr); - todo_wine ok( status == STATUS_SUCCESS, "NtOpenKey failed: 0x%08x\n", status ); pNtClose( key ); pRtlFreeUnicodeString( &str ); @@ -569,7 +568,6 @@ static void test_NtCreateKey(void)
pRtlCreateUnicodeStringFromAsciiz( &str, "\Registry" ); status = pNtCreateKey( &subkey, am, &attr, 0, 0, 0, 0 ); - todo_wine ok( status == STATUS_SUCCESS || status == STATUS_ACCESS_DENIED, "NtCreateKey failed: 0x%08x\n", status ); if (!status) pNtClose( subkey ); diff --git a/server/registry.c b/server/registry.c index b00abdbc004..ebe11db1039 100644 --- a/server/registry.c +++ b/server/registry.c @@ -127,7 +127,7 @@ static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between peri static struct timeout_user *save_timeout_user; /* saving timer */ static enum prefix_type { PREFIX_UNKNOWN, PREFIX_32BIT, PREFIX_64BIT } prefix_type;
-static const WCHAR root_name[] = { '\','R','e','g','i','s','t','r','y','\' }; +static const WCHAR root_name[] = { '\','R','e','g','i','s','t','r','y' }; static const WCHAR wow6432node[] = {'W','o','w','6','4','3','2','N','o','d','e'}; static const WCHAR symlink_value[] = {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e'}; static const struct unicode_str symlink_str = { symlink_value, sizeof(symlink_value) }; @@ -411,7 +411,7 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len ) { static const WCHAR backslash = '\'; struct key *key = (struct key *) obj; - data_size_t len = sizeof(root_name) - sizeof(WCHAR); + data_size_t len = sizeof(root_name); char *ret;
if (key->flags & KEY_DELETED) @@ -431,7 +431,7 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len ) len -= key->namelen + sizeof(WCHAR); memcpy( ret + len, &backslash, sizeof(WCHAR) ); } - memcpy( ret, root_name, sizeof(root_name) - sizeof(WCHAR) ); + memcpy( ret, root_name, sizeof(root_name) ); return (WCHAR *)ret; }
@@ -483,6 +483,11 @@ static inline void get_req_path( struct unicode_str *str, int skip_root ) { str->str += ARRAY_SIZE( root_name ); str->len -= sizeof(root_name); + if (str->str[0] == '\') + { + str->str++; + str->len -= sizeof(WCHAR); + } } }
@@ -734,6 +739,11 @@ static struct key *follow_symlink( struct key *key, int iteration ) if (memicmp_strW( path.str, root_name, sizeof(root_name) )) return NULL; path.str += ARRAY_SIZE( root_name ); path.len -= sizeof(root_name); + if (path.str[0] == '\') + { + path.str++; + path.len -= sizeof(WCHAR); + }
key = root_key; token.str = NULL; @@ -2156,6 +2166,11 @@ DECL_HANDLER(create_key) { name.str += ARRAY_SIZE( root_name ); name.len -= sizeof(root_name); + if (name.str[0] == '\') + { + name.str++; + name.len -= sizeof(WCHAR); + } }
/* NOTE: no access rights are required from the parent handle to create a key */ @@ -2314,6 +2329,11 @@ DECL_HANDLER(load_registry) { name.str += ARRAY_SIZE( root_name ); name.len -= sizeof(root_name); + if (name.str[0] == '\') + { + name.str++; + name.len -= sizeof(WCHAR); + } }
if ((parent = get_parent_hkey_obj( objattr->rootdir )))
Dmitry Timoshkov dmitry@baikal.ru writes:
diff --git a/server/registry.c b/server/registry.c index b00abdbc004..ebe11db1039 100644 --- a/server/registry.c +++ b/server/registry.c @@ -127,7 +127,7 @@ static const timeout_t save_period = 30 * -TICKS_PER_SEC; /* delay between peri static struct timeout_user *save_timeout_user; /* saving timer */ static enum prefix_type { PREFIX_UNKNOWN, PREFIX_32BIT, PREFIX_64BIT } prefix_type;
-static const WCHAR root_name[] = { '\','R','e','g','i','s','t','r','y','\' }; +static const WCHAR root_name[] = { '\','R','e','g','i','s','t','r','y' }; static const WCHAR wow6432node[] = {'W','o','w','6','4','3','2','N','o','d','e'}; static const WCHAR symlink_value[] = {'S','y','m','b','o','l','i','c','L','i','n','k','V','a','l','u','e'}; static const struct unicode_str symlink_str = { symlink_value, sizeof(symlink_value) }; @@ -411,7 +411,7 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len ) { static const WCHAR backslash = '\'; struct key *key = (struct key *) obj;
- data_size_t len = sizeof(root_name) - sizeof(WCHAR);
data_size_t len = sizeof(root_name); char *ret;
if (key->flags & KEY_DELETED)
@@ -431,7 +431,7 @@ static WCHAR *key_get_full_name( struct object *obj, data_size_t *ret_len ) len -= key->namelen + sizeof(WCHAR); memcpy( ret + len, &backslash, sizeof(WCHAR) ); }
- memcpy( ret, root_name, sizeof(root_name) - sizeof(WCHAR) );
- memcpy( ret, root_name, sizeof(root_name) ); return (WCHAR *)ret;
}
@@ -483,6 +483,11 @@ static inline void get_req_path( struct unicode_str *str, int skip_root ) { str->str += ARRAY_SIZE( root_name ); str->len -= sizeof(root_name);
if (str->str[0] == '\\')
{
str->str++;
str->len -= sizeof(WCHAR);
}
You need to check the length first, and you need to reject anything that isn't a backslash at that point.
I feel that using the normal path handling also for the first component, possibly creating a root key of that name, would be a better approach.
Alexandre Julliard julliard@winehq.org wrote:
@@ -483,6 +483,11 @@ static inline void get_req_path( struct unicode_str *str, int skip_root ) { str->str += ARRAY_SIZE( root_name ); str->len -= sizeof(root_name);
if (str->str[0] == '\\')
{
str->str++;
str->len -= sizeof(WCHAR);
}
You need to check the length first, and you need to reject anything that isn't a backslash at that point.
Thanks, I'll resend with the length check.
I feel that using the normal path handling also for the first component, possibly creating a root key of that name, would be a better approach.
I'll leave investigating that solution as a later opportunity.