[PATCH 2/2] advapi32: HKCR merge: added path management

George Stephanos gaf.stephanos at gmail.com
Mon Sep 16 09:05:23 CDT 2013


---
 dlls/advapi32/registry.c | 69 +++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 63 insertions(+), 6 deletions(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index ab16a12..60a4c45 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -81,6 +81,8 @@ static BOOL hkcu_cache_disabled;
 
 typedef struct {
     HKEY  hklm;
+    DWORD samDesired;
+    WCHAR *path;
 } opened_hkcr_t;
 
 /* ############################### */
@@ -314,6 +316,7 @@ static HKEY resolve_hkcr( HKEY hkey )
             return NULL;
         }
 
+        if (!hkcr->hklm) RegOpenKeyExW( HKEY_LOCAL_MACHINE, hkcr->path, 0, hkcr->samDesired, &hkcr->hklm );
         ret = hkcr->hklm;
 
         LeaveCriticalSection( &hkcr_handles_cs );
@@ -322,6 +325,52 @@ static HKEY resolve_hkcr( HKEY hkey )
     return NULL;
 }
 
+static LSTATUS get_hkcr_path( HKEY hkey, CONST WCHAR *path, WCHAR **buf )
+{
+    const static WCHAR root[] = {'S','o','f','t','w','a','r','e','\\','C','l','a','s','s','e','s',0};
+    opened_hkcr_t *hkcr = NULL;
+    UINT_PTR idx = (UINT_PTR)(hkey) >> 2;
+    int len = 0;
+    WCHAR *s;
+
+    if (path && *path == '\\') path++;
+
+    // calculate len
+    if (hkey)
+    {
+        EnterCriticalSection( &hkcr_handles_cs );
+        if (idx > nb_hkcr_handles || !hkcr_handles[idx])
+        {
+            LeaveCriticalSection( &hkcr_handles_cs );
+            return ERROR_INVALID_HANDLE;
+        }
+        hkcr = hkcr_handles[idx];
+        LeaveCriticalSection( &hkcr_handles_cs );
+
+        len += lstrlenW(hkcr->path)+1;
+    }
+    else len += sizeof(root);
+
+    if (path && *path) len += lstrlenW(path)+1;
+
+    // allocate string
+    *buf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR) );
+    if (!*buf) return ERROR_NOT_ENOUGH_MEMORY;
+
+    // copy
+    if (hkey) lstrcpyW( *buf, hkcr->path );
+    else lstrcpyW( *buf, root );
+
+    if (path && *path) 
+    {
+        s = *buf + lstrlenW(*buf);
+        *s++ = '\\';
+        lstrcpyW( s, path );
+    }
+
+    return ERROR_SUCCESS;
+}
+
 static LSTATUS WINAPI create_hkcr( HKEY hkey, CONST WCHAR *name, WCHAR *class,
                                    DWORD options, REGSAM samDesired,
                                    SECURITY_ATTRIBUTES *sa, HKEY *retkey, DWORD *dispos )
@@ -329,10 +378,12 @@ static LSTATUS WINAPI create_hkcr( HKEY hkey, CONST WCHAR *name, WCHAR *class,
     HKEY hklm;
     opened_hkcr_t *hkcr = NULL;
     LSTATUS res;
+    WCHAR *buf = NULL;
     *retkey = 0;
 
-    if (hkey != HKEY_LOCAL_MACHINE) hkey = resolve_hkcr( hkey );
-    res = RegCreateKeyExW( hkey, name, 0, class, options, samDesired, sa, &hklm, dispos );
+    if ((res = get_hkcr_path( hkey, name, &buf ))) return res;
+
+    res = RegCreateKeyExW( HKEY_LOCAL_MACHINE, buf, 0, class, options, samDesired, sa, &hklm, dispos );
     if (res) return res;
 
     if ((res = create_hkcr_struct(retkey, &hkcr)))
@@ -342,6 +393,8 @@ static LSTATUS WINAPI create_hkcr( HKEY hkey, CONST WCHAR *name, WCHAR *class,
     }
 
     hkcr->hklm = hklm;
+    hkcr->path = buf;
+    hkcr->samDesired = samDesired;
 
     return res;
 }
@@ -351,10 +404,12 @@ static LSTATUS WINAPI open_hkcr( HKEY hkey, CONST WCHAR *name, REGSAM samDesired
     HKEY hklm;
     opened_hkcr_t *hkcr = NULL;
     LSTATUS res;
+    WCHAR *buf = NULL;
     *retkey = 0;
 
-    hkey = resolve_hkcr( hkey );
-    res = RegOpenKeyExW( hkey, name, 0, samDesired, &hklm );
+    if ((res = get_hkcr_path( hkey, name, &buf ))) return res;
+
+    res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, buf, 0, samDesired, &hklm );
     if (res) return res;
 
     if ((res = create_hkcr_struct(retkey, &hkcr)))
@@ -364,6 +419,8 @@ static LSTATUS WINAPI open_hkcr( HKEY hkey, CONST WCHAR *name, REGSAM samDesired
     }
 
     hkcr->hklm = hklm;
+    hkcr->path = buf;
+    hkcr->samDesired = samDesired;
 
     return res;
 }
@@ -377,7 +434,7 @@ static HKEY create_special_root_hkey( HKEY hkey, DWORD access )
 
     if (HandleToUlong(hkey) == HandleToUlong(HKEY_CLASSES_ROOT))
     {
-        if (create_hkcr( HKEY_LOCAL_MACHINE, name_CLASSES_ROOT + 8, NULL, 0, access, NULL, &hkey, NULL )) return 0;
+        if (create_hkcr( NULL, NULL, NULL, 0, access, NULL, &hkey, NULL )) return 0;
     }
     else if (HandleToUlong(hkey) == HandleToUlong(HKEY_CURRENT_USER))
     {
@@ -442,7 +499,7 @@ static LSTATUS close_hkcr( HKEY hkey )
         }
 
         RegCloseKey(hkcr->hklm);
-
+        HeapFree( GetProcessHeap(), 0, hkcr->path );
         HeapFree( GetProcessHeap(), 0, hkcr );
         hkcr_handles[idx] = 0;
 
-- 
1.8.2.3




More information about the wine-patches mailing list