>From 0251b4d91d13134100ffe91ea6c953924d48f4eb Mon Sep 17 00:00:00 2001
From: Nikolay Sivov <nsivov@codeweavers.com>
Date: Thu, 1 Dec 2011 20:19:29 +0300
Subject: [PATCH 1/1] Partially implement SHRegCreateUSKeyW

---
 dlls/shlwapi/reg.c         |   47 ++++++++++++++++++++++++++++---
 dlls/shlwapi/tests/shreg.c |   66 ++++++++++++++++++++++++++++----------------
 2 files changed, 84 insertions(+), 29 deletions(-)

diff --git a/dlls/shlwapi/reg.c b/dlls/shlwapi/reg.c
index 09fce55..26f83bf 100644
--- a/dlls/shlwapi/reg.c
+++ b/dlls/shlwapi/reg.c
@@ -235,12 +235,49 @@ LONG WINAPI SHRegCreateUSKeyA(LPCSTR pszPath, REGSAM samDesired, HUSKEY hRelativ
  *
  * See SHRegCreateUSKeyA.
  */
-LONG WINAPI SHRegCreateUSKeyW(LPCWSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
-                              PHUSKEY phNewUSKey, DWORD dwFlags)
+LONG WINAPI SHRegCreateUSKeyW(LPCWSTR path, REGSAM samDesired, HUSKEY relative_key,
+                              PHUSKEY new_uskey, DWORD flags)
 {
-    FIXME("(%s, 0x%08x, %p, %p, 0x%08x) stub\n", debugstr_w(pszPath), samDesired,
-          hRelativeUSKey, phNewUSKey, dwFlags);
-    return ERROR_SUCCESS;
+    LONG ret = ERROR_CALL_NOT_IMPLEMENTED;
+    SHUSKEY *ret_key;
+
+    TRACE("(%s, 0x%08x, %p, %p, 0x%08x)\n", debugstr_w(path), samDesired,
+          relative_key, new_uskey, flags);
+
+    if (!new_uskey) return ERROR_INVALID_PARAMETER;
+
+    *new_uskey = NULL;
+
+    if (flags & ~SHREGSET_FORCE_HKCU)
+    {
+        FIXME("unsupported flags 0x%08x\n", flags);
+        return ERROR_SUCCESS;
+    }
+
+    ret_key = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret_key));
+    lstrcpynW(ret_key->lpszPath, path, sizeof(ret_key->lpszPath)/sizeof(WCHAR));
+
+    if (relative_key)
+    {
+        ret_key->HKCUstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(relative_key, REG_HKCU));
+        ret_key->HKLMstart = SHRegDuplicateHKey(REG_GetHKEYFromHUSKEY(relative_key, REG_HKLM));
+    }
+    else
+    {
+        ret_key->HKCUstart = HKEY_CURRENT_USER;
+        ret_key->HKLMstart = HKEY_LOCAL_MACHINE;
+    }
+
+    if (flags & SHREGSET_FORCE_HKCU)
+    {
+        ret = RegCreateKeyExW(ret_key->HKCUstart, path, 0, NULL, 0, samDesired, NULL, &ret_key->HKCUkey, NULL);
+        if (ret == ERROR_SUCCESS)
+            *new_uskey = ret_key;
+        else
+            HeapFree(GetProcessHeap(), 0, ret_key);
+    }
+
+    return ret;
 }
 
 /*************************************************************************
diff --git a/dlls/shlwapi/tests/shreg.c b/dlls/shlwapi/tests/shreg.c
index 3cee765..3634041 100644
--- a/dlls/shlwapi/tests/shreg.c
+++ b/dlls/shlwapi/tests/shreg.c
@@ -33,12 +33,11 @@
 #define REG_CURRENT_VERSION "Software\\Microsoft\\Windows\\CurrentVersion\\explorer"
 
 static HMODULE hshlwapi;
-typedef DWORD (WINAPI *SHCopyKeyA_func)(HKEY,LPCSTR,HKEY,DWORD);
-static SHCopyKeyA_func pSHCopyKeyA;
-typedef DWORD (WINAPI *SHRegGetPathA_func)(HKEY,LPCSTR,LPCSTR,LPSTR,DWORD);
-static SHRegGetPathA_func pSHRegGetPathA;
-typedef LSTATUS (WINAPI *SHRegGetValueA_func)(HKEY,LPCSTR,LPCSTR,SRRF,LPDWORD,LPVOID,LPDWORD);
-static SHRegGetValueA_func pSHRegGetValueA;
+
+static DWORD (WINAPI *pSHCopyKeyA)(HKEY,LPCSTR,HKEY,DWORD);
+static DWORD (WINAPI *pSHRegGetPathA)(HKEY,LPCSTR,LPCSTR,LPSTR,DWORD);
+static LSTATUS (WINAPI *pSHRegGetValueA)(HKEY,LPCSTR,LPCSTR,SRRF,LPDWORD,LPVOID,LPDWORD);
+static LSTATUS (WINAPI *pSHRegCreateUSKeyW)(LPCWSTR,REGSAM,HUSKEY,PHUSKEY,DWORD);
 
 static char sTestpath1[] = "%LONGSYSTEMVAR%\\subdir1";
 static char sTestpath2[] = "%FOO%\\subdir1";
@@ -444,28 +443,47 @@ static void test_SHDeleteKey(void)
         ok( 0, "Could not set up SHDeleteKey test\n");
 }
 
+static void test_SHRegCreateUSKeyW(void)
+{
+    static const WCHAR subkeyW[] = {'s','u','b','k','e','y',0};
+    LONG ret;
+
+    if (!pSHRegCreateUSKeyW)
+    {
+        win_skip("SHRegCreateUSKeyW not available\n");
+        return;
+    }
+
+    ret = pSHRegCreateUSKeyW(subkeyW, KEY_ALL_ACCESS, NULL, NULL, SHREGSET_FORCE_HKCU);
+    ok(ret == ERROR_INVALID_PARAMETER, "got %d\n", ret);
+}
+
 START_TEST(shreg)
 {
-	HKEY hkey = create_test_entries();
+    HKEY hkey = create_test_entries();
 
-        if (!hkey) return;
+    if (!hkey) return;
 
-	hshlwapi = GetModuleHandleA("shlwapi.dll");
+    hshlwapi = GetModuleHandleA("shlwapi.dll");
 
-        /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
-        if(!GetProcAddress(hshlwapi, "SHCreateStreamOnFileEx")){
-            win_skip("Too old shlwapi version\n");
-            return;
-        }
+    /* SHCreateStreamOnFileEx was introduced in shlwapi v6.0 */
+    if(!GetProcAddress(hshlwapi, "SHCreateStreamOnFileEx")){
+        win_skip("Too old shlwapi version\n");
+        return;
+    }
+
+    pSHCopyKeyA = (void*)GetProcAddress(hshlwapi,"SHCopyKeyA");
+    pSHRegGetPathA = (void*)GetProcAddress(hshlwapi,"SHRegGetPathA");
+    pSHRegGetValueA = (void*)GetProcAddress(hshlwapi,"SHRegGetValueA");
+    pSHRegCreateUSKeyW = (void*)GetProcAddress(hshlwapi, "SHRegCreateUSKeyW");
+
+    test_SHGetValue();
+    test_SHRegGetValue();
+    test_SHQueryValueEx();
+    test_SHGetRegPath();
+    test_SHCopyKey();
+    test_SHDeleteKey();
+    test_SHRegCreateUSKeyW();
 
-        pSHCopyKeyA=(SHCopyKeyA_func)GetProcAddress(hshlwapi,"SHCopyKeyA");
-        pSHRegGetPathA=(SHRegGetPathA_func)GetProcAddress(hshlwapi,"SHRegGetPathA");
-        pSHRegGetValueA=(SHRegGetValueA_func)GetProcAddress(hshlwapi,"SHRegGetValueA");
-	test_SHGetValue();
-        test_SHRegGetValue();
-	test_SHQueryValueEx();
-	test_SHGetRegPath();
-	test_SHCopyKey();
-        test_SHDeleteKey();
-        delete_key( hkey, "Software\\Wine", "Test" );
+    delete_key( hkey, "Software\\Wine", "Test" );
 }
-- 
1.5.6.5

