[v2 PATCH] shell32: Implement SHCreateSessionKey.

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Tue Apr 17 19:25:24 CDT 2018


This implementation is based on the Geoff Chappell description.

Based off patch by Dmitry Timoshkov.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/shell32/shellreg.c       | 35 ++++++++++++++++++++++++++++++++---
 dlls/shell32/tests/shellole.c | 26 ++++++++++++++++++++++----
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/dlls/shell32/shellreg.c b/dlls/shell32/shellreg.c
index 356ec4e8bd..cacf3ac19f 100644
--- a/dlls/shell32/shellreg.c
+++ b/dlls/shell32/shellreg.c
@@ -34,6 +34,7 @@
 
 #include "undocshell.h"
 
+#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
@@ -148,13 +149,41 @@ HRESULT WINAPI SHRegCloseKey (HKEY hkey)
 	return RegCloseKey( hkey );
 }
 
+static BOOL WINAPI create_session_key(INIT_ONCE *once, void *param, void **context)
+{
+    static const WCHAR session_format[] = {
+                'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+                'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                'E','x','p','l','o','r','e','r','\\','S','e','s','s','i','o','n','I','n','f','o','\\','%','d',0};
+    DWORD session;
+    HKEY hkey_session;
+    LPWSTR session_reg_str = param;
+
+    if(!ProcessIdToSessionId( GetCurrentProcessId(), &session))
+        return FALSE;
+
+    sprintfW(session_reg_str, session_format, session);
+
+    if (RegCreateKeyExW(HKEY_CURRENT_USER, session_reg_str, 0, NULL,
+                        REG_OPTION_VOLATILE, KEY_WRITE, NULL, &hkey_session, NULL))
+        return FALSE;
+
+    RegCloseKey(hkey_session);
+    TRACE("session key %s\n", debugstr_w(session_reg_str));
+    return TRUE;
+}
+
 /*************************************************************************
  * SHCreateSessionKey                   [SHELL32.723]
  *
  */
 HRESULT WINAPI SHCreateSessionKey(REGSAM access, HKEY *hkey)
 {
-    FIXME("stub: %d %p\n", access, hkey);
-    *hkey = NULL;
-    return E_NOTIMPL;
+    static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
+    static WCHAR session_reg_str[MAX_PATH];
+
+    InitOnceExecuteOnce(&init_once, create_session_key, session_reg_str, NULL);
+
+    TRACE("using session key %s\n", debugstr_w(session_reg_str));
+    return RegOpenKeyExW(HKEY_CURRENT_USER, session_reg_str, 0, access, hkey);
 }
diff --git a/dlls/shell32/tests/shellole.c b/dlls/shell32/tests/shellole.c
index f611faf908..1f61bef0f0 100644
--- a/dlls/shell32/tests/shellole.c
+++ b/dlls/shell32/tests/shellole.c
@@ -76,6 +76,7 @@ static HRESULT (WINAPI *pSHPropStgWriteMultiple)(IPropertyStorage*, UINT*,
         ULONG, const PROPSPEC*, PROPVARIANT*, PROPID);
 static HRESULT (WINAPI *pSHCreateQueryCancelAutoPlayMoniker)(IMoniker**);
 static HRESULT (WINAPI *pSHCreateSessionKey)(REGSAM, HKEY*);
+static BOOL    (WINAPI *pSHGetPathFromIDListEx)(PCIDLIST_ABSOLUTE,WCHAR*,DWORD,GPFIDL_FLAGS);
 
 static void init(void)
 {
@@ -86,6 +87,7 @@ static void init(void)
     pSHPropStgWriteMultiple = (void*)GetProcAddress(hmod, "SHPropStgWriteMultiple");
     pSHCreateQueryCancelAutoPlayMoniker = (void*)GetProcAddress(hmod, "SHCreateQueryCancelAutoPlayMoniker");
     pSHCreateSessionKey = (void*)GetProcAddress(hmod, (char*)723);
+    pSHGetPathFromIDListEx = (void*)GetProcAddress(hmod, "SHGetPathFromIDListEx");
 }
 
 static HRESULT WINAPI PropertyStorage_QueryInterface(IPropertyStorage *This,
@@ -862,8 +864,15 @@ static void test_DragQueryFile(void)
 
 static void test_SHCreateSessionKey(void)
 {
+    static const WCHAR session_format[] = {
+                'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
+                'W','i','n','d','o','w','s','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
+                'E','x','p','l','o','r','e','r','\\','S','e','s','s','i','o','n','I','n','f','o','\\','%','d',0};
     HKEY hkey, hkey2;
     HRESULT hr;
+    DWORD session;
+    WCHAR sessionW[MAX_PATH];
+    LONG ret;
 
     if (!pSHCreateSessionKey)
     {
@@ -877,17 +886,26 @@ static void test_SHCreateSessionKey(void)
     hkey = (HKEY)0xdeadbeef;
     hr = pSHCreateSessionKey(0, &hkey);
     todo_wine ok(hr == E_ACCESSDENIED, "got 0x%08x\n", hr);
-    ok(hkey == NULL, "got %p\n", hkey);
+    todo_wine ok(hkey == NULL, "got %p\n", hkey);
 
     hr = pSHCreateSessionKey(KEY_READ, &hkey);
-    todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
 
     hr = pSHCreateSessionKey(KEY_READ, &hkey2);
-    todo_wine ok(hr == S_OK, "got 0x%08x\n", hr);
-    todo_wine ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2);
+    ok(hr == S_OK, "got 0x%08x\n", hr);
+    ok(hkey != hkey2, "got %p, %p\n", hkey, hkey2);
 
     RegCloseKey(hkey);
     RegCloseKey(hkey2);
+
+    /* Check the registery */
+    ProcessIdToSessionId( GetCurrentProcessId(), &session);
+    wsprintfW(sessionW, session_format, session);
+
+    ret = RegOpenKeyW(HKEY_CURRENT_USER, sessionW, &hkey);
+    /* Fails on XP and w2k3, SHGetPathFromIDListEx available for Vista+ */
+    ok(!ret || (ret && !pSHGetPathFromIDListEx), "key not found\n");
+    RegCloseKey(hkey);
 }
 
 static void test_dragdrophelper(void)
-- 
2.17.0




More information about the wine-devel mailing list