[PATCH v3 5/6] server: Create the special Perflib\009 key.

Zebediah Figura z.figura12 at gmail.com
Wed Jun 30 11:36:33 CDT 2021


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/advapi32/tests/registry.c |  4 +--
 server/registry.c              | 52 ++++++++++++++++++++++++++++++++++
 server/trace.c                 |  1 +
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index cf7536eff75..122292ce39d 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -3838,12 +3838,12 @@ static void test_perflib_key(void)
     todo_wine ok(key == HKEY_PERFORMANCE_TEXT || key == HKEY_PERFORMANCE_NLSTEXT, "got key %p\n", key);
 
     ret = RegCloseKey(key);
-    todo_wine ok(!ret, "got %u\n", ret);
+    ok(!ret, "got %u\n", ret);
 
     RtlInitUnicodeString(&string, L"009");
     InitializeObjectAttributes(&attr, &string, OBJ_CASE_INSENSITIVE, perflib_key, NULL);
     ret = NtOpenKey((HANDLE *)&key, KEY_ALL_ACCESS, &attr);
-    todo_wine ok(ret == STATUS_PREDEFINED_HANDLE || ret == STATUS_ACCESS_DENIED
+    ok(ret == STATUS_PREDEFINED_HANDLE || ret == STATUS_ACCESS_DENIED
             || ret == STATUS_SUCCESS /* Win < 7 */, "got %#x\n", ret);
     if (ret == STATUS_PREDEFINED_HANDLE)
         ok(!is_special_key(key), "expected a normal handle, got %p\n", key);
diff --git a/server/registry.c b/server/registry.c
index b7971770728..427da8a5883 100644
--- a/server/registry.c
+++ b/server/registry.c
@@ -101,6 +101,7 @@ struct key
 #define KEY_SYMLINK  0x0008  /* key is a symbolic link */
 #define KEY_WOW64    0x0010  /* key contains a Wow6432Node subkey */
 #define KEY_WOWSHARE 0x0020  /* key is a Wow64 shared key (used for Software\Classes) */
+#define KEY_PREDEF   0x0040  /* key is marked as predefined */
 
 /* a key value */
 struct key_value
@@ -801,6 +802,7 @@ static struct key *open_key( struct key *key, const struct unicode_str *name, un
         return NULL;
     }
     if (debug_level > 1) dump_operation( key, NULL, "Open" );
+    if (key->flags & KEY_PREDEF) set_error( STATUS_PREDEFINED_HANDLE );
     grab_object( key );
     return key;
 }
@@ -831,6 +833,7 @@ static struct key *create_key( struct key *key, const struct unicode_str *name,
             return NULL;
         }
         if (debug_level > 1) dump_operation( key, NULL, "Open" );
+        if (key->flags & KEY_PREDEF) set_error( STATUS_PREDEFINED_HANDLE );
         grab_object( key );
         return key;
     }
@@ -925,6 +928,12 @@ static void enum_key( struct key *key, int index, int info_class, struct enum_ke
     WCHAR *fullname = NULL;
     char *data;
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
     if (index != -1)  /* -1 means use the specified key directly */
     {
         if ((index < 0) || (index > key->last_subkey))
@@ -1020,6 +1029,12 @@ static int delete_key( struct key *key, int recurse )
     }
     assert( parent );
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return -1;
+    }
+
     while (recurse && (key->last_subkey>=0))
         if (0 > delete_key(key->subkeys[key->last_subkey], 1))
             return -1;
@@ -1126,6 +1141,12 @@ static void set_value( struct key *key, const struct unicode_str *name,
     void *ptr = NULL;
     int index;
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
     if ((value = find_value( key, name, &index )))
     {
         /* check if the new value is identical to the existing one */
@@ -1172,6 +1193,12 @@ static void get_value( struct key *key, const struct unicode_str *name, int *typ
     struct key_value *value;
     int index;
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
     if ((value = find_value( key, name, &index )))
     {
         *type = value->type;
@@ -1191,6 +1218,12 @@ static void enum_value( struct key *key, int i, int info_class, struct enum_key_
 {
     struct key_value *value;
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
     if (i < 0 || i > key->last_value) set_error( STATUS_NO_MORE_ENTRIES );
     else
     {
@@ -1243,6 +1276,12 @@ static void delete_value( struct key *key, const struct unicode_str *name )
     struct key_value *value;
     int i, index, nb_values;
 
+    if (key->flags & KEY_PREDEF)
+    {
+        set_error( STATUS_INVALID_HANDLE );
+        return;
+    }
+
     if (!(value = find_value( key, name, &index )))
     {
         set_error( STATUS_OBJECT_NAME_NOT_FOUND );
@@ -1817,9 +1856,16 @@ void init_registry(void)
     static const WCHAR classes_arm64[] = {'S','o','f','t','w','a','r','e','\\',
                                           'C','l','a','s','s','e','s','\\',
                                           'W','o','w','A','A','6','4','N','o','d','e'};
+    static const WCHAR perflib[] = {'S','o','f','t','w','a','r','e','\\',
+                                    'M','i','c','r','o','s','o','f','t','\\',
+                                    'W','i','n','d','o','w','s',' ','N','T','\\',
+                                    'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                                    'P','e','r','f','l','i','b','\\',
+                                    '0','0','9'};
     static const struct unicode_str root_name = { NULL, 0 };
     static const struct unicode_str HKLM_name = { HKLM, sizeof(HKLM) };
     static const struct unicode_str HKU_name = { HKU_default, sizeof(HKU_default) };
+    static const struct unicode_str perflib_name = { perflib, sizeof(perflib) };
 
     WCHAR *current_user_path;
     struct unicode_str current_user_str;
@@ -1891,6 +1937,12 @@ void init_registry(void)
         /* FIXME: handle HKCU too */
     }
 
+    if ((key = create_key_recursive( hklm, &perflib_name, current_time )))
+    {
+        key->flags |= KEY_PREDEF;
+        release_object( key );
+    }
+
     release_object( hklm );
     release_object( hkcu );
 
diff --git a/server/trace.c b/server/trace.c
index 55068d1179b..395b72b8d6f 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -5485,6 +5485,7 @@ static const struct
     { "PIPE_LISTENING",              STATUS_PIPE_LISTENING },
     { "PIPE_NOT_AVAILABLE",          STATUS_PIPE_NOT_AVAILABLE },
     { "PORT_NOT_SET",                STATUS_PORT_NOT_SET },
+    { "PREDEFINED_HANDLE",           STATUS_PREDEFINED_HANDLE },
     { "PRIVILEGE_NOT_HELD",          STATUS_PRIVILEGE_NOT_HELD },
     { "PROCESS_IN_JOB",              STATUS_PROCESS_IN_JOB },
     { "PROCESS_IS_TERMINATING",      STATUS_PROCESS_IS_TERMINATING },
-- 
2.30.2




More information about the wine-devel mailing list