From 065b3e658cfcbea4ebb76ca49949620e71fdf3dc Mon Sep 17 00:00:00 2001 From: George Stephanos Date: Sun, 25 Aug 2013 01:36:30 +0200 Subject: [PATCH 2/3] advapi32: HKCR merge: added path management --- dlls/advapi32/registry.c | 70 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 6 deletions(-) diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c index 5768272..385d98c 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; /* ############################### */ @@ -313,6 +315,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 ); @@ -321,6 +324,53 @@ 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) & ~HKCR_MASK)/4; + int len; + + if (hkey) /* HKCR handle supplied */ + { + 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 ); + + /* construct path */ + hkcr = hkcr_handles[idx]; + len = lstrlenW(hkcr->path); + *buf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, (len+lstrlenW(path)+2)*sizeof(WCHAR) ); + if (!*buf) return ERROR_NOT_ENOUGH_MEMORY; + lstrcpyW( *buf, hkcr->path ); + (*buf)[len] = '\\'; + lstrcpyW( *buf+len+1, path+(*path=='\\') ); + } + else if (path) /* HKEY_CLASSES_ROOT is root for path */ + { + *buf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(root)+(lstrlenW(path)+2)*sizeof(WCHAR) ); + if (!*buf) return ERROR_NOT_ENOUGH_MEMORY; + lstrcpyW( *buf, root ); + (*buf)[sizeof(root)]='\\'; + lstrcpyW( *buf+sizeof(root)+1, path+(*path=='\\') ); + } + else /* open HKEY_CLASSES_ROOT */ + { + *buf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(root) ); + if (!*buf) return ERROR_NOT_ENOUGH_MEMORY; + lstrcpyW( *buf, root ); + } + 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 ) @@ -328,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))) @@ -341,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; } @@ -350,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))) @@ -363,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; } @@ -376,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)) { @@ -441,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