[PATCH] advapi32: Make RegOpenCurrentUser() return real key handles for current SID

Nikolay Sivov nsivov at codeweavers.com
Sun Dec 27 16:18:00 CST 2015


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---

For https://bugs.winehq.org/show_bug.cgi?id=39475

 dlls/advapi32/registry.c       | 48 +++++++++++++++++++++++++++++++++++++++++-
 dlls/advapi32/tests/registry.c | 13 ++++++++++++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 8317698..3508407 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -37,6 +37,7 @@
 #include "winerror.h"
 #include "winternl.h"
 #include "winuser.h"
+#include "sddl.h"
 #include "advapi32_misc.h"
 
 #include "wine/unicode.h"
@@ -648,6 +649,21 @@ LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey )
     return RegOpenKeyExA( hkey, name, 0, MAXIMUM_ALLOWED, retkey );
 }
 
+static WCHAR *get_thread_token_user_sid(HANDLE token)
+{
+    WCHAR *sidstring = NULL;
+    TOKEN_USER *info;
+    DWORD len = 0;
+
+    GetTokenInformation(token, TokenUser, NULL, 0, &len);
+
+    info = heap_alloc(len);
+    if (GetTokenInformation(token, TokenUser, info, len, &len))
+        ConvertSidToStringSidW(info->User.Sid, &sidstring);
+    heap_free(info);
+
+    return sidstring;
+}
 
 /******************************************************************************
  * RegOpenCurrentUser   [ADVAPI32.@]
@@ -671,7 +687,37 @@ LSTATUS WINAPI RegOpenKeyA( HKEY hkey, LPCSTR name, PHKEY retkey )
  */
 LSTATUS WINAPI RegOpenCurrentUser( REGSAM access, PHKEY retkey )
 {
-    return RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey );
+    WCHAR *sidstring = NULL;
+    HANDLE threadtoken;
+    LSTATUS ret;
+
+    /* get current user SID */
+    if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken))
+    {
+       sidstring = get_thread_token_user_sid(threadtoken);
+       CloseHandle(threadtoken);
+    }
+
+    if (!sidstring)
+    {
+        ImpersonateSelf(SecurityIdentification);
+        if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &threadtoken))
+        {
+            sidstring = get_thread_token_user_sid(threadtoken);
+            CloseHandle(threadtoken);
+        }
+        RevertToSelf();
+    }
+
+    if (sidstring)
+    {
+        ret = RegOpenKeyExW( HKEY_USERS, sidstring, 0, access, retkey );
+        LocalFree(sidstring);
+    }
+    else
+        ret = RegOpenKeyExA( HKEY_CURRENT_USER, "", 0, access, retkey );
+
+    return ret;
 }
 
 
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index 254a8b6..ef5d989 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -3278,6 +3278,18 @@ static void test_delete_key_value(void)
     RegCloseKey(subkey);
 }
 
+static void test_RegOpenCurrentUser(void)
+{
+    HKEY key;
+    LONG ret;
+
+    key = HKEY_CURRENT_USER;
+    ret = RegOpenCurrentUser(KEY_READ, &key);
+    ok(!ret, "got %d, error %d\n", ret, GetLastError());
+    ok(key != HKEY_CURRENT_USER, "got %p\n", key);
+    RegCloseKey(key);
+}
+
 START_TEST(registry)
 {
     /* Load pointers for functions that are not available in all Windows versions */
@@ -3310,6 +3322,7 @@ START_TEST(registry)
     test_deleted_key();
     test_delete_value();
     test_delete_key_value();
+    test_RegOpenCurrentUser();
 
     /* cleanup */
     delete_key( hkey_main );
-- 
2.6.4




More information about the wine-patches mailing list