Alexandre Julliard : advapi32: Add support for the KEY_WOW64_32KEY flag in RegOpenKey on 64-bit.

Alexandre Julliard julliard at winehq.org
Fri Apr 2 10:17:11 CDT 2010


Module: wine
Branch: master
Commit: 21da080dbd71ed5b5d00ed9dcd4370c771edf2a4
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=21da080dbd71ed5b5d00ed9dcd4370c771edf2a4

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Apr  2 12:14:21 2010 +0200

advapi32: Add support for the KEY_WOW64_32KEY flag in RegOpenKey on 64-bit.

---

 dlls/advapi32/registry.c |   53 ++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index ba9d9a7..abaf09d 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -174,6 +174,55 @@ static NTSTATUS create_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES
     return status;
 }
 
+/* wrapper for NtOpenKey to handle Wow6432 nodes */
+static NTSTATUS open_key( HKEY *retkey, ACCESS_MASK access, OBJECT_ATTRIBUTES *attr )
+{
+    NTSTATUS status;
+    BOOL force_wow32 = is_win64 && (access & KEY_WOW64_32KEY);
+    HANDLE subkey, root = attr->RootDirectory;
+    WCHAR *buffer = attr->ObjectName->Buffer;
+    DWORD attrs, pos = 0, i = 0, len = attr->ObjectName->Length / sizeof(WCHAR);
+    UNICODE_STRING str;
+
+    if (!force_wow32) return NtOpenKey( (HANDLE *)retkey, access, attr );
+
+    if (len && buffer[0] == '\\') return STATUS_OBJECT_PATH_INVALID;
+    while (i < len && buffer[i] != '\\') i++;
+    attrs = attr->Attributes;
+    attr->Attributes &= ~OBJ_OPENLINK;
+    attr->ObjectName = &str;
+
+    while (i < len)
+    {
+        str.Buffer = buffer + pos;
+        str.Length = (i - pos) * sizeof(WCHAR);
+        if (force_wow32 && pos)
+        {
+            if (is_wow6432node( &str )) force_wow32 = FALSE;
+            else if ((subkey = open_wow6432node( attr->RootDirectory, &str )))
+            {
+                if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
+                attr->RootDirectory = subkey;
+                force_wow32 = FALSE;
+            }
+        }
+        status = NtOpenKey( &subkey, access, attr );
+        if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
+        if (status) return status;
+        attr->RootDirectory = subkey;
+        while (i < len && buffer[i] == '\\') i++;
+        pos = i;
+        while (i < len && buffer[i] != '\\') i++;
+    }
+    str.Buffer = buffer + pos;
+    str.Length = (i - pos) * sizeof(WCHAR);
+    attr->Attributes = attrs;
+    status = NtOpenKey( (PHANDLE)retkey, access, attr );
+    if (attr->RootDirectory != root) NtClose( attr->RootDirectory );
+    return status;
+
+}
+
 /* create one of the HKEY_* special root keys */
 static HKEY create_special_root_hkey( HKEY hkey, DWORD access )
 {
@@ -404,7 +453,7 @@ LSTATUS WINAPI RegOpenKeyExW( HKEY hkey, LPCWSTR name, DWORD options, REGSAM acc
     attr.SecurityQualityOfService = NULL;
     if (options & REG_OPTION_OPEN_LINK) attr.Attributes |= OBJ_OPENLINK;
     RtlInitUnicodeString( &nameW, name );
-    return RtlNtStatusToDosError( NtOpenKey( (PHANDLE)retkey, access, &attr ) );
+    return RtlNtStatusToDosError( open_key( retkey, access, &attr ) );
 }
 
 
@@ -455,7 +504,7 @@ LSTATUS WINAPI RegOpenKeyExA( HKEY hkey, LPCSTR name, DWORD options, REGSAM acce
     if (!(status = RtlAnsiStringToUnicodeString( &NtCurrentTeb()->StaticUnicodeString,
                                                  &nameA, FALSE )))
     {
-        status = NtOpenKey( (PHANDLE)retkey, access, &attr );
+        status = open_key( retkey, access, &attr );
     }
     return RtlNtStatusToDosError( status );
 }




More information about the wine-cvs mailing list