This implementation is based on the Geoff Chappell description.
Based off patch by Dmitry Timoshkov.
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@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)