[PATCH 2/2] advapi32: Path management for HKCR merge (try 2)
George Stephanos
gaf.stephanos at gmail.com
Thu Jan 23 18:05:39 CST 2014
---
dlls/advapi32/registry.c | 71 ++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 62 insertions(+), 9 deletions(-)
diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 851f414..80b941b 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -44,10 +44,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(reg);
#define HKEY_SPECIAL_ROOT_FIRST HKEY_CLASSES_ROOT
#define HKEY_SPECIAL_ROOT_LAST HKEY_DYN_DATA
-static const WCHAR name_CLASSES_ROOT[] =
- {'M','a','c','h','i','n','e','\\',
- 'S','o','f','t','w','a','r','e','\\',
- 'C','l','a','s','s','e','s',0};
static const WCHAR name_LOCAL_MACHINE[] =
{'M','a','c','h','i','n','e',0};
static const WCHAR name_USERS[] =
@@ -82,6 +78,8 @@ static BOOL hkcu_cache_disabled;
typedef struct {
BOOL init;
HKEY hklm;
+ DWORD samDesired;
+ WCHAR *path;
} opened_hkcr_t;
/* ############################### */
@@ -333,12 +331,58 @@ static HKEY resolve_hkcr( HKEY hkey )
if (!hkcr) return NULL;
EnterCriticalSection( &hkcr_handles_cs );
+ if (!hkcr->hklm) RegOpenKeyExW( HKEY_LOCAL_MACHINE, hkcr->path, 0, hkcr->samDesired, &hkcr->hklm );
ret = hkcr->hklm;
LeaveCriticalSection( &hkcr_handles_cs );
return ret;
}
+static LSTATUS get_hkcr_path( HKEY hkey, const WCHAR *path, WCHAR **buf )
+{
+ LSTATUS ret = ERROR_SUCCESS;
+ 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;
+ int len = 0;
+ WCHAR *s;
+
+ if (path && *path == '\\') path++;
+
+ /* calculate len */
+ if (hkey)
+ {
+ hkcr = get_opened_hkcr( hkey );
+ if (!hkcr) return ERROR_INVALID_HANDLE;
+ EnterCriticalSection( &hkcr_handles_cs );
+ }
+
+ len += hkcr ? lstrlenW(hkcr->path) + 1 : sizeof(root);
+
+ if (path && *path) len += lstrlenW(path)+1;
+
+ /* allocate string */
+ *buf = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len*sizeof(WCHAR) );
+ if (!*buf)
+ {
+ ret = ERROR_NOT_ENOUGH_MEMORY;
+ goto end;
+ }
+
+ /* copy */
+ lstrcpyW( *buf, hkcr ? hkcr->path : root );
+
+ if (path && *path)
+ {
+ s = *buf + lstrlenW(*buf);
+ *s++ = '\\';
+ lstrcpyW( s, path );
+ }
+
+end:
+ if (hkcr) LeaveCriticalSection( &hkcr_handles_cs );
+ return ret;
+}
+
static LSTATUS WINAPI create_hkcr( HKEY hkey, const WCHAR *name, WCHAR *class,
DWORD options, REGSAM samDesired,
SECURITY_ATTRIBUTES *sa, HKEY *retkey, DWORD *dispos )
@@ -346,10 +390,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)))
@@ -360,6 +406,8 @@ static LSTATUS WINAPI create_hkcr( HKEY hkey, const WCHAR *name, WCHAR *class,
EnterCriticalSection( &hkcr_handles_cs );
hkcr->hklm = hklm;
+ hkcr->path = buf;
+ hkcr->samDesired = samDesired;
LeaveCriticalSection( &hkcr_handles_cs );
return res;
@@ -370,10 +418,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)))
@@ -384,6 +434,8 @@ static LSTATUS WINAPI open_hkcr( HKEY hkey, const WCHAR *name, REGSAM samDesired
EnterCriticalSection( &hkcr_handles_cs );
hkcr->hklm = hklm;
+ hkcr->path = buf;
+ hkcr->samDesired = samDesired;
LeaveCriticalSection( &hkcr_handles_cs );
return res;
@@ -398,7 +450,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))
{
@@ -466,6 +518,7 @@ static LSTATUS close_hkcr( HKEY hkey )
EnterCriticalSection( &hkcr_handles_cs );
RegCloseKey( hkcr->hklm );
+ HeapFree( GetProcessHeap(), 0, hkcr->path );
hkcr->init = FALSE;
hkcr_handles_free[nb_hkcr_handles_free++] = (UINT_PTR)hkey >> 2;
LeaveCriticalSection( &hkcr_handles_cs );
--
1.8.2.3
More information about the wine-patches
mailing list