[PATCH v5 3/3] kernelbase: Return HKEY_PERFORMANCE_TEXT when trying to open the Perflib\009 key.

Zebediah Figura z.figura12 at gmail.com
Thu Jul 1 17:25:02 CDT 2021


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

diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 829bf3b0c61..4daf40b7aad 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -3832,10 +3832,10 @@ static void test_perflib_key(void)
     ok(!ret, "got %u\n", ret);
 
     ret = RegOpenKeyExA(perflib_key, "009", 0, KEY_READ, &key);
-    todo_wine ok(!ret, "got %u\n", ret);
+    ok(!ret, "got %u\n", ret);
     /* English always returns TEXT; most other languages return NLSTEXT, but
      * some (e.g. Hindi) return TEXT */
-    todo_wine ok(key == HKEY_PERFORMANCE_TEXT || key == HKEY_PERFORMANCE_NLSTEXT, "got key %p\n", key);
+    ok(key == HKEY_PERFORMANCE_TEXT || key == HKEY_PERFORMANCE_NLSTEXT, "got key %p\n", key);
 
     ret = RegCloseKey(key);
     ok(!ret, "got %u\n", ret);
diff --git a/dlls/kernelbase/registry.c b/dlls/kernelbase/registry.c
index 2ed5e268119..d9d62e81b31 100644
--- a/dlls/kernelbase/registry.c
+++ b/dlls/kernelbase/registry.c
@@ -121,6 +121,25 @@ static HANDLE open_wow6432node( HANDLE key )
     return ret;
 }
 
+static HKEY get_perflib_key( HANDLE key )
+{
+    static const WCHAR performance_text[] =
+            L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009";
+    char buffer[200];
+    OBJECT_NAME_INFORMATION *info = (OBJECT_NAME_INFORMATION *)buffer;
+
+    if (!NtQueryObject( key, ObjectNameInformation, buffer, sizeof(buffer), NULL ))
+    {
+        if (!wcsicmp( info->Name.Buffer, performance_text ))
+        {
+            NtClose( key );
+            return HKEY_PERFORMANCE_TEXT;
+        }
+    }
+
+    return key;
+}
+
 /* wrapper for NtCreateKey that creates the key recursively if necessary */
 static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr,
                             const UNICODE_STRING *class, ULONG options, PULONG dispos )
@@ -172,7 +191,7 @@ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES
                                       options & ~REG_OPTION_CREATE_LINK, dispos );
             }
             if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
-            if (status) return status;
+            if (!NT_SUCCESS(status)) return status;
             if (i == len) break;
             attr->RootDirectory = subkey;
             while (i < len && buffer[i] == '\\') i++;
@@ -186,6 +205,11 @@ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES
         if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
         attr->RootDirectory = subkey;
     }
+    if (status == STATUS_PREDEFINED_HANDLE)
+    {
+        attr->RootDirectory = get_perflib_key( attr->RootDirectory );
+        status = STATUS_SUCCESS;
+    }
     *retkey = attr->RootDirectory;
     return status;
 }
@@ -205,7 +229,13 @@ static NTSTATUS open_key( HKEY *retkey, DWORD options, ACCESS_MASK access, OBJEC
     if (!force_wow32)
     {
         if (options & REG_OPTION_OPEN_LINK) attr->Attributes |= OBJ_OPENLINK;
-        return NtOpenKeyEx( (HANDLE *)retkey, access, attr, options );
+        status = NtOpenKeyEx( (HANDLE *)retkey, access, attr, options );
+        if (status == STATUS_PREDEFINED_HANDLE)
+        {
+            *retkey = get_perflib_key( *retkey );
+            status = STATUS_SUCCESS;
+        }
+        return status;
     }
 
     if (len && buffer[0] == '\\') return STATUS_OBJECT_PATH_INVALID;
@@ -249,6 +279,11 @@ static NTSTATUS open_key( HKEY *retkey, DWORD options, ACCESS_MASK access, OBJEC
         if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
         attr->RootDirectory = subkey;
     }
+    if (status == STATUS_PREDEFINED_HANDLE)
+    {
+        attr->RootDirectory = get_perflib_key( attr->RootDirectory );
+        status = STATUS_SUCCESS;
+    }
     *retkey = attr->RootDirectory;
     return status;
 }
-- 
2.30.2




More information about the wine-devel mailing list