SHLWAPI merging #4

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hiya,

Merging part 4.

<question>
Does anyone object to my moving SHLWAPI_1 & 2 into url.c and moving out the 
definitions from ordinal.h in there as well?

I want to tidy this up because at some point in the not too distant future the 
ordinal code will get a lot bigger. So it makes sense to me to implement 
ordinals that are related in the same files (like the MIME ord. functions in 
url.c), and to split out other ord. groups (gdi/windows/com/ie/perfmon etc) 
into their own files as well. OK?
</question>

Cheers,
Jon

License: X11

ChangeLog:

  Jon Griffiths <jon_p_griffiths@yahoo.com>

  +dlls/shlwapi/reg.c,dlls/shlwapi/shlwapi.spec,dlls/shlwapi/test/shreg.c
   Implementation and test for SHCopyKeyA/W

  +dlls/shlwapi/url.c
   Trivial - Make hex digits static const & share them
diff -ur wine/dlls/shlwapi/reg.c wine-develop/dlls/shlwapi/reg.c
--- wine/dlls/shlwapi/reg.c	Tue Sep 10 21:44:26 2002
+++ wine-develop/dlls/shlwapi/reg.c	Fri Sep 13 00:59:10 2002
@@ -1792,3 +1792,135 @@
     TRACE("new key is %08x\n", newKey);
     return newKey;
 }
+
+
+/*************************************************************************
+ * SHCopyKeyA	[SHLWAPI.@]
+ *
+ * Copy a key and its values/sub keys to another location.
+ *
+ * PARAMS
+ *  hKeyDst    [I] Destination key
+ *  lpszSubKey [I] Sub key under hKeyDst, or NULL to use hKeyDst directly
+ *  hKeySrc    [I] Source key to copy from
+ *  dwReserved [I] Reserved, must be 0
+ *
+ * RETURNS
+ *  Success: ERROR_SUCCESS. The key is copied to the destination key.
+ *  Failure: A standard windows error code.
+ *
+ * NOTES
+ *  If hKeyDst is a key under hKeySrc, this function will misbehave
+ *  (It will loop until out of stack, or the registry is full).
+ */
+DWORD WINAPI SHCopyKeyA(HKEY hKeyDst, LPCSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+{
+  WCHAR szSubKeyW[MAX_PATH];
+
+  TRACE("(hkey=0x%08x,%s,%0x08x,%ld)\n", hKeyDst, debugstr_a(lpszSubKey), hKeySrc, dwReserved);
+
+  if (lpszSubKey)
+    MultiByteToWideChar(0, 0, lpszSubKey, -1, szSubKeyW, MAX_PATH);
+
+  return SHCopyKeyW(hKeyDst, lpszSubKey ? szSubKeyW : NULL, hKeySrc, dwReserved);
+}
+
+/*************************************************************************
+ * SHCopyKeyW	[SHLWAPI.@]
+ *
+ * See SHCopyKeyA.
+ */
+DWORD WINAPI SHCopyKeyW(HKEY hKeyDst, LPCWSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+{
+  DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0;
+  DWORD  dwMaxValueLen = 0, dwMaxDataLen = 0, i;
+  BYTE buff[1024];
+  LPVOID lpBuff = (LPVOID)buff;
+  WCHAR szName[MAX_PATH], *lpszName = szName;
+  DWORD dwRet = S_OK;
+
+  TRACE("hkey=0x%08x,%s,%0x08x,%ld)\n", hKeyDst, debugstr_w(lpszSubKey), hKeySrc, dwReserved);
+
+  if(!hKeyDst || !hKeySrc)
+    dwRet = ERROR_INVALID_PARAMETER;
+  else
+  {
+    /* Open destination key */
+    if(lpszSubKey)
+      dwRet = RegOpenKeyExW(hKeyDst, lpszSubKey, 0, KEY_ALL_ACCESS, &hKeyDst);
+
+    if(dwRet)
+      hKeyDst = 0; /* Don't close this key since we didn't open it */
+    else
+    {
+      /* Get details about sub keys and values */
+      dwRet = RegQueryInfoKeyW(hKeySrc, NULL, NULL, NULL, &dwKeyCount, &dwMaxKeyLen,
+                               NULL, &dwValueCount, &dwMaxValueLen, &dwMaxDataLen,
+                               NULL, NULL);
+      if(!dwRet)
+      {
+        if (dwMaxValueLen > dwMaxKeyLen)
+          dwMaxKeyLen = dwMaxValueLen; /* Get max size for key/value names */
+
+        if (dwMaxKeyLen++ > MAX_PATH - 1)
+          lpszName = HeapAlloc(GetProcessHeap(), 0, dwMaxKeyLen * sizeof(WCHAR));
+
+        if (dwMaxDataLen > sizeof(buff))
+          lpBuff = HeapAlloc(GetProcessHeap(), 0, dwMaxDataLen);
+
+        if (!lpszName || !lpBuff)
+          dwRet = ERROR_NOT_ENOUGH_MEMORY;
+      }
+    }
+  }
+
+  /* Copy all the sub keys */
+  for(i = 0; i < dwKeyCount && !dwRet; i++)
+  {
+    HKEY hSubKeySrc, hSubKeyDst;
+    DWORD dwSize = dwMaxKeyLen;
+
+    dwRet = RegEnumKeyExW(hKeySrc, i, lpszName, &dwSize, NULL, NULL, NULL, NULL);
+
+    if(!dwRet)
+    {
+      /* Open source sub key */
+      dwRet = RegOpenKeyExW(hKeySrc, lpszName, 0, KEY_READ, &hSubKeySrc);
+
+      if(!dwRet)
+      {
+        /* Create destination sub key */
+        dwRet = RegCreateKeyW(hKeyDst, lpszName, &hSubKeyDst);
+
+        if(!dwRet)
+        {
+          /* Recursively copy keys and values from the sub key */
+          dwRet = SHCopyKeyW(hSubKeyDst, NULL, hSubKeySrc, 0);
+          RegCloseKey(hSubKeyDst);
+        }
+      }
+      RegCloseKey(hSubKeySrc);
+    }
+  }
+
+  /* Copy all the values in this key */
+  for (i = 0; i < dwValueCount && !dwRet; i++)
+  {
+    DWORD dwNameSize = dwMaxKeyLen, dwType, dwLen = dwMaxDataLen;
+
+    dwRet = RegEnumValueW(hKeySrc, i, lpszName, &dwNameSize, NULL, &dwType, buff, &dwLen);
+
+    if (!dwRet)
+      dwRet = SHSetValueW(hKeyDst, NULL, lpszName, dwType, lpBuff, dwLen);
+  }
+
+  /* Free buffers if allocated */
+  if (lpszName != szName)
+    HeapFree(GetProcessHeap(), 0, lpszName);
+  if (lpBuff != buff)
+    HeapFree(GetProcessHeap(), 0, lpBuff);
+
+  if (lpszSubKey && hKeyDst)
+    RegCloseKey(hKeyDst);
+  return dwRet;
+}
diff -ur wine/dlls/shlwapi/shlwapi.spec wine-develop/dlls/shlwapi/shlwapi.spec
--- wine/dlls/shlwapi/shlwapi.spec	Tue Sep 10 21:44:26 2002
+++ wine-develop/dlls/shlwapi/shlwapi.spec	Tue Sep 10 23:08:57 2002
@@ -705,8 +705,8 @@
 @ stdcall PathUndecorateW(wstr) PathUndecorateW
 @ stub    PathUnExpandEnvStringsA
 @ stub    PathUnExpandEnvStringsW
-@ stub    SHCopyKeyA
-@ stub    SHCopyKeyW
+@ stdcall SHCopyKeyA(long str long long) SHCopyKeyA
+@ stdcall SHCopyKeyW(long wstr long long) SHCopyKeyW
 @ stub    SHAutoComplete
 @ stdcall SHCreateStreamOnFileA(str long ptr) SHCreateStreamOnFileA
 @ stdcall SHCreateStreamOnFileW(wstr long ptr) SHCreateStreamOnFileW
diff -ur wine/dlls/shlwapi/tests/shreg.c wine-develop/dlls/shlwapi/tests/shreg.c
--- wine/dlls/shlwapi/tests/shreg.c	Sun Aug 11 17:22:24 2002
+++ wine-develop/dlls/shlwapi/tests/shreg.c	Fri Sep 13 00:38:53 2002
@@ -28,6 +28,10 @@
 #include "winuser.h"
 #include "shlwapi.h"
 
+// Keys used for testing
+#define REG_TEST_KEY        "Software\\Wine\\Test"
+#define REG_CURRENT_VERSION "Software\\Microsoft\\Windows NT\\CurrentVersion"
+
 static char * sTestpath1 = "%LONGSYSTEMVAR%\\subdir1";
 static char * sTestpath2 = "%FOO%\\subdir1";
 
@@ -45,7 +49,7 @@
         SetEnvironmentVariableA("LONGSYSTEMVAR", "bar");
         SetEnvironmentVariableA("FOO", "ImARatherLongButIndeedNeededString");
 
-	ok(!RegCreateKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Test", &hKey), "RegCreateKeyA failed");
+	ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY, &hKey), "RegCreateKeyA failed");
 
 	if (hKey)
 	{
@@ -71,24 +75,24 @@
 	strcpy(buf, sEmptyBuffer);
 	dwSize = MAX_PATH;
 	dwType = -1;
-	ok(! SHGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "Test1", &dwType, buf, &dwSize), "SHGetValueA failed");
+	ok(! SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", &dwType, buf, &dwSize), "SHGetValueA failed");
 	ok( 0 == strcmp(sExpTestpath1, buf), "(%s,%s)", buf, sExpTestpath1);
 	ok( REG_SZ == dwType, "(%lx)", dwType);
 
 	strcpy(buf, sEmptyBuffer);
 	dwSize = MAX_PATH;
 	dwType = -1;
-	ok(! SHGetValueA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "Test2", &dwType, buf, &dwSize), "SHGetValueA failed");
+	ok(! SHGetValueA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test2", &dwType, buf, &dwSize), "SHGetValueA failed");
 	ok( 0 == strcmp(sTestpath1, buf) , "(%s)", buf);
 	ok( REG_SZ == dwType , "(%lx)", dwType);
 }
 
-static void test_SHGetTegPath(void)
+static void test_SHGetRegPath(void)
 {
 	char buf[MAX_PATH];
 
 	strcpy(buf, sEmptyBuffer);
-	ok(! SHRegGetPathA(HKEY_CURRENT_USER, "Software\\Wine\\Test", "Test1", buf, 0), "SHRegGetPathA failed");
+	ok(! SHRegGetPathA(HKEY_CURRENT_USER, REG_TEST_KEY, "Test1", buf, 0), "SHRegGetPathA failed");
 	ok( 0 == strcmp(sExpTestpath1, buf) , "(%s)", buf);
 }
 
@@ -103,7 +107,7 @@
 	int nUsedBuffer1;
 	int nUsedBuffer2;
 
-	ok(! RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\Wine\\Test", 0,  KEY_QUERY_VALUE, &hKey), "test4 RegOpenKey");
+	ok(! RegOpenKeyExA(HKEY_CURRENT_USER, REG_TEST_KEY, 0,  KEY_QUERY_VALUE, &hKey), "test4 RegOpenKey");
 
 	/****** SHQueryValueExA ******/
 
@@ -189,10 +193,59 @@
 	RegCloseKey(hKey);
 }
 
+
+static void test_SHCopyKey(void)
+{
+	HKEY hKeySrc, hKeyDst;
+
+	// Delete existing destination sub keys
+	hKeyDst = (HKEY)0;
+	if (!RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst) && hKeyDst)
+	{
+		SHDeleteKeyA(hKeyDst, NULL);
+		RegCloseKey(hKeyDst);
+	}
+
+	hKeyDst = (HKEY)0;
+	if (RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination", &hKeyDst) || !hKeyDst)
+	{
+		ok(0, "didn't open dest");
+		return;
+	}
+
+	hKeySrc = (HKEY)0;
+	if (RegOpenKeyA(HKEY_LOCAL_MACHINE, REG_CURRENT_VERSION, &hKeySrc) || !hKeySrc)
+	{
+		ok(0, "didn't open source");
+		return;
+	}
+
+
+	ok (!SHCopyKeyA(hKeyDst, NULL, hKeySrc, 0), "failed copy");
+
+	RegCloseKey(hKeySrc);
+	RegCloseKey(hKeyDst);
+
+	/* Check we copied the sub keys, i.e. AeDebug from the default wine registry */
+	hKeyDst = (HKEY)0;
+	if (RegOpenKeyA(HKEY_CURRENT_USER, REG_TEST_KEY "\\CopyDestination\\AeDebug", &hKeyDst) || !hKeyDst)
+	{
+		ok(0, "didn't open copy");
+		return;
+	}
+
+	/* And the we copied the values too */
+	ok(!SHQueryValueExA(hKeyDst, "Debugger", NULL, NULL, NULL, NULL), "SHQueryValueExA failed");
+
+	RegCloseKey(hKeyDst);
+}
+
+
 START_TEST(shreg)
 {
 	create_test_entrys();
 	test_SHGetValue();
 	test_SHQUeryValueEx();
-	test_SHGetTegPath();
+	test_SHGetRegPath();
+	test_SHCopyKey();
 }
diff -ur wine/dlls/shlwapi/url.c wine-develop/dlls/shlwapi/url.c
--- wine/dlls/shlwapi/url.c	Thu Aug 29 11:14:14 2002
+++ wine-develop/dlls/shlwapi/url.c	Sun Sep  8 20:43:19 2002
@@ -56,6 +56,8 @@
     USERPASS,
 } WINE_URL_SCAN_TYPE;
 
+static const CHAR hexDigits[] = "0123456789ABCDEF";
+
 static const WCHAR fileW[] = {'f','i','l','e','\0'};
 
 static const unsigned char HashDataLookup[256] = {
@@ -730,7 +732,6 @@
     DWORD needed = 0, ret;
     BOOL stop_escaping = FALSE;
     char next[3], *dst = pszEscaped;
-    char hex[] = "0123456789ABCDEF";
     INT len;
 
     TRACE("(%s %p %p 0x%08lx)\n", debugstr_a(pszUrl), pszEscaped,
@@ -762,8 +763,8 @@
 	if(URL_NeedEscapeA(*src, dwFlags) && stop_escaping == FALSE) {
 	    /* TRACE("escaping %c\n", *src); */
 	    next[0] = '%';
-	    next[1] = hex[(*src >> 4) & 0xf];
-	    next[2] = hex[*src & 0xf];
+	    next[1] = hexDigits[(*src >> 4) & 0xf];
+	    next[2] = hexDigits[*src & 0xf];
 	    len = 3;
 	} else {
 	    /* TRACE("passing %c\n", *src); */
@@ -804,7 +805,6 @@
     DWORD needed = 0, ret;
     BOOL stop_escaping = FALSE;
     WCHAR next[5], *dst = pszEscaped;
-    CHAR hex[] = "0123456789ABCDEF";
     INT len;
 
     TRACE("(%s %p %p 0x%08lx)\n", debugstr_w(pszUrl), pszEscaped,
@@ -846,14 +846,14 @@
 	     * the character with 4 hex digits (or even 8),
 	     * however, experiments show that native shlwapi escapes
 	     * with only 2 hex digits.
-	     *   next[1] = hex[(*src >> 12) & 0xf];
-	     *   next[2] = hex[(*src >> 8) & 0xf];
-	     *   next[3] = hex[(*src >> 4) & 0xf];
-	     *   next[4] = hex[*src & 0xf];
+	     *   next[1] = hexDigits[(*src >> 12) & 0xf];
+	     *   next[2] = hexDigits[(*src >> 8) & 0xf];
+	     *   next[3] = hexDigits[(*src >> 4) & 0xf];
+	     *   next[4] = hexDigits[*src & 0xf];
 	     *   len = 5;
 	     */
-	    next[1] = hex[(*src >> 4) & 0xf];
-	    next[2] = hex[*src & 0xf];
+	    next[1] = hexDigits[(*src >> 4) & 0xf];
+	    next[2] = hexDigits[*src & 0xf];
 	    len = 3;
 	} else {
 	    /* TRACE("passing %c\n", *src); */

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux