Sync to Wine-20050211
James Hawkins <truiken@gmail.com>
- use only stored result of Interlocked* in AddRef/Release
- expand TRACEs to display the ref count
Hans Leidekker <hans@it.vu.nl>
- Stub implementations for PathUnExpandEnvStringsSHRegEnumUSValue{A,W},
  SHRegCreateUSKey{A,W}, SHRegDeleteEmptyUSKey{A,W},
  SHRegDeleteUSValue{A,W}, SHRegEnumUSValue{A,W}.
- Implement and test PathIsValidChar{A,W}.
Paul Vriens <Paul.Vriens@xs4all.nl>
- Change the order of Src and Dst in CopyKey calls/functions.
Modified: trunk/reactos/lib/shlwapi/assoc.c
Modified: trunk/reactos/lib/shlwapi/istream.c
Modified: trunk/reactos/lib/shlwapi/path.c
Modified: trunk/reactos/lib/shlwapi/reg.c
Modified: trunk/reactos/lib/shlwapi/regstream.c
Modified: trunk/reactos/lib/shlwapi/shlwapi.spec

Modified: trunk/reactos/lib/shlwapi/assoc.c
--- trunk/reactos/lib/shlwapi/assoc.c	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/assoc.c	2005-02-14 14:50:45 UTC (rev 13559)
@@ -467,10 +467,11 @@
 static ULONG WINAPI IQueryAssociations_fnAddRef(IQueryAssociations *iface)
 {
   IQueryAssociationsImpl *This = (IQueryAssociationsImpl *)iface;
+  ULONG refCount = InterlockedIncrement(&This->ref);
+  
+  TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
 
-  TRACE("(%p)->(ref before=%lu)\n",This, This->ref);
-
-  return InterlockedIncrement(&This->ref);
+  return refCount;
 }
 
 /**************************************************************************
@@ -481,16 +482,17 @@
 static ULONG WINAPI IQueryAssociations_fnRelease(IQueryAssociations *iface)
 {
   IQueryAssociationsImpl *This = (IQueryAssociationsImpl *)iface;
-  ULONG ulRet;
+  ULONG refCount = InterlockedDecrement(&This->ref);
 
-  TRACE("(%p)->(ref before=%lu)\n",This, This->ref);
+  TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
 
-  if (!(ulRet = InterlockedDecrement(&This->ref)))
+  if (!refCount)
   {
     TRACE("Destroying IQueryAssociations (%p)\n", This);
     HeapFree(GetProcessHeap(), 0, This);
   }
-  return ulRet;
+  
+  return refCount;
 }
 
 /**************************************************************************

Modified: trunk/reactos/lib/shlwapi/istream.c
--- trunk/reactos/lib/shlwapi/istream.c	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/istream.c	2005-02-14 14:50:45 UTC (rev 13559)
@@ -78,9 +78,11 @@
 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
 {
   ISHFileStream *This = (ISHFileStream *)iface;
+  ULONG refCount = InterlockedIncrement(&This->ref);
+  
+  TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
 
-  TRACE("(%p)\n", This);
-  return InterlockedIncrement(&This->ref);
+  return refCount;
 }
 
 /**************************************************************************
@@ -89,18 +91,19 @@
 static ULONG WINAPI IStream_fnRelease(IStream *iface)
 {
   ISHFileStream *This = (ISHFileStream *)iface;
-  ULONG ulRet;
+  ULONG refCount = InterlockedDecrement(&This->ref); 
 
-  TRACE("(%p)\n", This);
-
-  if (!(ulRet = InterlockedDecrement(&This->ref)))
+  TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
+  
+  if (!refCount)
   {
     IStream_fnCommit(iface, 0); /* If ever buffered, this will be needed */
     LocalFree((HLOCAL)This->lpszPath);
     CloseHandle(This->hFile);
     HeapFree(GetProcessHeap(), 0, This);
   }
-  return ulRet;
+  
+  return refCount;
 }
 
 /**************************************************************************

Modified: trunk/reactos/lib/shlwapi/path.c
--- trunk/reactos/lib/shlwapi/path.c	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/path.c	2005-02-14 14:50:45 UTC (rev 13559)
@@ -3911,6 +3911,38 @@
 }
 
 /*************************************************************************
+ * PathUnExpandEnvStringsA [SHLWAPI.@]
+ *
+ * Substitute folder names in a path with their corresponding environment
+ * strings.
+ *
+ * PARAMS
+ *  pszPath  [I] Buffer containing the path to unexpand.
+ *  pszBuf   [O] Buffer to receive the unexpanded path.
+ *  cchBuf   [I] Size of pszBuf in characters.
+ *
+ * RETURNS
+ *  Success: TRUE
+ *  Failure: FALSE
+ */
+BOOL WINAPI PathUnExpandEnvStringsA(LPCSTR pszPath, LPSTR pszBuf, UINT cchBuf)
+{
+    FIXME("(%s,%s,0x%08x)\n", debugstr_a(pszPath), debugstr_a(pszBuf), cchBuf);
+    return FALSE;
+}
+
+/*************************************************************************
+ * PathUnExpandEnvStringsW [SHLWAPI.@]
+ *
+ * Unicode version of PathUnExpandEnvStringsA.
+ */
+BOOL WINAPI PathUnExpandEnvStringsW(LPCWSTR pszPath, LPWSTR pszBuf, UINT cchBuf)
+{
+    FIXME("(%s,%s,0x%08x)\n", debugstr_w(pszPath), debugstr_w(pszBuf), cchBuf);
+    return FALSE;
+}
+
+/*************************************************************************
  * @     [SHLWAPI.440]
  *
  * Find localised or default web content in "%WINDOWS%\web\".
@@ -3990,100 +4022,110 @@
   return E_FAIL;
 }
 
-#define PATH_CHAR_CLASS_LETTER      0x0001
-#define PATH_CHAR_CLASS_ASTERIX     0x0002
-#define PATH_CHAR_CLASS_DOT         0x0004
-#define PATH_CHAR_CLASS_BACKSLASH   0x0008
-#define PATH_CHAR_CLASS_COLON       0x0010
-#define PATH_CHAR_CLASS_SEMICOLON   0x0020
-#define PATH_CHAR_CLASS_COMMA       0x0040
-#define PATH_CHAR_CLASS_SPACE       0x0080
-#define PATH_CHAR_CLASS_OTHER_VALID 0x0100
-#define PATH_CHAR_CLASS_DOUBLEQUOTE 0x0200
+#define PATH_CHAR_CLASS_LETTER      0x00000001
+#define PATH_CHAR_CLASS_ASTERIX     0x00000002
+#define PATH_CHAR_CLASS_DOT         0x00000004
+#define PATH_CHAR_CLASS_BACKSLASH   0x00000008
+#define PATH_CHAR_CLASS_COLON       0x00000010
+#define PATH_CHAR_CLASS_SEMICOLON   0x00000020
+#define PATH_CHAR_CLASS_COMMA       0x00000040
+#define PATH_CHAR_CLASS_SPACE       0x00000080
+#define PATH_CHAR_CLASS_OTHER_VALID 0x00000100
+#define PATH_CHAR_CLASS_DOUBLEQUOTE 0x00000200
 
-/*************************************************************************
- * PathIsValidCharAW     [internal]
- *
- * Check if a char is of a certain class
- */
-static BOOL WINAPI PathIsValidCharAW(unsigned Ch, DWORD Class)
+#define PATH_CHAR_CLASS_INVALID     0x00000000
+#define PATH_CHAR_CLASS_ANY         0xffffffff
+
+static const DWORD SHELL_charclass[] =
 {
-  static struct
-  {
-    char Ch;
-    DWORD Class;
-  } CharClass[] =
-  {
-    { ' ', PATH_CHAR_CLASS_SPACE },
-    { '!', PATH_CHAR_CLASS_OTHER_VALID },
-    { '"', PATH_CHAR_CLASS_DOUBLEQUOTE },
-    { '#', PATH_CHAR_CLASS_OTHER_VALID },
-    { '$', PATH_CHAR_CLASS_OTHER_VALID },
-    { '%', PATH_CHAR_CLASS_OTHER_VALID },
-    { '&', PATH_CHAR_CLASS_OTHER_VALID },
-    { '\'', PATH_CHAR_CLASS_OTHER_VALID },
-    { '(', PATH_CHAR_CLASS_OTHER_VALID },
-    { ')', PATH_CHAR_CLASS_OTHER_VALID },
-    { '*', PATH_CHAR_CLASS_ASTERIX },
-    { '+', PATH_CHAR_CLASS_OTHER_VALID },
-    { ',', PATH_CHAR_CLASS_COMMA },
-    { '-', PATH_CHAR_CLASS_OTHER_VALID },
-    { '.', PATH_CHAR_CLASS_DOT },
-    { ':', PATH_CHAR_CLASS_COLON },
-    { ';', PATH_CHAR_CLASS_SEMICOLON },
-    { '=', PATH_CHAR_CLASS_OTHER_VALID },
-    { '?', PATH_CHAR_CLASS_LETTER },
-    { '@', PATH_CHAR_CLASS_OTHER_VALID },
-    { '[', PATH_CHAR_CLASS_OTHER_VALID },
-    { '\\', PATH_CHAR_CLASS_BACKSLASH },
-    { ']', PATH_CHAR_CLASS_OTHER_VALID },
-    { '^', PATH_CHAR_CLASS_OTHER_VALID },
-    { '_', PATH_CHAR_CLASS_OTHER_VALID },
-    { '`', PATH_CHAR_CLASS_OTHER_VALID },
-    { '{', PATH_CHAR_CLASS_OTHER_VALID },
-    { '}', PATH_CHAR_CLASS_OTHER_VALID },
-    { '~', PATH_CHAR_CLASS_OTHER_VALID },
-    { 0x7f, PATH_CHAR_CLASS_OTHER_VALID }
-  };
-  unsigned Index;
+    /* 0x00 */  PATH_CHAR_CLASS_INVALID,      /* 0x01 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x02 */  PATH_CHAR_CLASS_INVALID,      /* 0x03 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x04 */  PATH_CHAR_CLASS_INVALID,      /* 0x05 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x06 */  PATH_CHAR_CLASS_INVALID,      /* 0x07 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x08 */  PATH_CHAR_CLASS_INVALID,      /* 0x09 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x0a */  PATH_CHAR_CLASS_INVALID,      /* 0x0b */  PATH_CHAR_CLASS_INVALID,
+    /* 0x0c */  PATH_CHAR_CLASS_INVALID,      /* 0x0d */  PATH_CHAR_CLASS_INVALID,
+    /* 0x0e */  PATH_CHAR_CLASS_INVALID,      /* 0x0f */  PATH_CHAR_CLASS_INVALID,
+    /* 0x10 */  PATH_CHAR_CLASS_INVALID,      /* 0x11 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x12 */  PATH_CHAR_CLASS_INVALID,      /* 0x13 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x14 */  PATH_CHAR_CLASS_INVALID,      /* 0x15 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x16 */  PATH_CHAR_CLASS_INVALID,      /* 0x17 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x18 */  PATH_CHAR_CLASS_INVALID,      /* 0x19 */  PATH_CHAR_CLASS_INVALID,
+    /* 0x1a */  PATH_CHAR_CLASS_INVALID,      /* 0x1b */  PATH_CHAR_CLASS_INVALID,
+    /* 0x1c */  PATH_CHAR_CLASS_INVALID,      /* 0x1d */  PATH_CHAR_CLASS_INVALID,
+    /* 0x1e */  PATH_CHAR_CLASS_INVALID,      /* 0x1f */  PATH_CHAR_CLASS_INVALID,
+    /* ' '  */  PATH_CHAR_CLASS_SPACE,        /* '!'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '"'  */  PATH_CHAR_CLASS_DOUBLEQUOTE,  /* '#'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '$'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '%'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '&'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '\'' */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '('  */  PATH_CHAR_CLASS_OTHER_VALID,  /* ')'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '*'  */  PATH_CHAR_CLASS_ASTERIX,      /* '+'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* ','  */  PATH_CHAR_CLASS_COMMA,        /* '-'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '.'  */  PATH_CHAR_CLASS_DOT,          /* '/'  */  PATH_CHAR_CLASS_INVALID,
+    /* '0'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '1'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '2'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '3'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '4'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '5'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '6'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '7'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '8'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '9'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* ':'  */  PATH_CHAR_CLASS_COLON,        /* ';'  */  PATH_CHAR_CLASS_SEMICOLON,
+    /* '<'  */  PATH_CHAR_CLASS_INVALID,      /* '='  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '>'  */  PATH_CHAR_CLASS_INVALID,      /* '?'  */  PATH_CHAR_CLASS_LETTER,
+    /* '@'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* 'A'  */  PATH_CHAR_CLASS_ANY,
+    /* 'B'  */  PATH_CHAR_CLASS_ANY,          /* 'C'  */  PATH_CHAR_CLASS_ANY,
+    /* 'D'  */  PATH_CHAR_CLASS_ANY,          /* 'E'  */  PATH_CHAR_CLASS_ANY,
+    /* 'F'  */  PATH_CHAR_CLASS_ANY,          /* 'G'  */  PATH_CHAR_CLASS_ANY,
+    /* 'H'  */  PATH_CHAR_CLASS_ANY,          /* 'I'  */  PATH_CHAR_CLASS_ANY,
+    /* 'J'  */  PATH_CHAR_CLASS_ANY,          /* 'K'  */  PATH_CHAR_CLASS_ANY,
+    /* 'L'  */  PATH_CHAR_CLASS_ANY,          /* 'M'  */  PATH_CHAR_CLASS_ANY,
+    /* 'N'  */  PATH_CHAR_CLASS_ANY,          /* 'O'  */  PATH_CHAR_CLASS_ANY,
+    /* 'P'  */  PATH_CHAR_CLASS_ANY,          /* 'Q'  */  PATH_CHAR_CLASS_ANY,
+    /* 'R'  */  PATH_CHAR_CLASS_ANY,          /* 'S'  */  PATH_CHAR_CLASS_ANY,
+    /* 'T'  */  PATH_CHAR_CLASS_ANY,          /* 'U'  */  PATH_CHAR_CLASS_ANY,
+    /* 'V'  */  PATH_CHAR_CLASS_ANY,          /* 'W'  */  PATH_CHAR_CLASS_ANY,
+    /* 'X'  */  PATH_CHAR_CLASS_ANY,          /* 'Y'  */  PATH_CHAR_CLASS_ANY,
+    /* 'Z'  */  PATH_CHAR_CLASS_ANY,          /* '['  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '\\' */  PATH_CHAR_CLASS_BACKSLASH,    /* ']'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '^'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* '_'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '`'  */  PATH_CHAR_CLASS_OTHER_VALID,  /* 'a'  */  PATH_CHAR_CLASS_ANY,
+    /* 'b'  */  PATH_CHAR_CLASS_ANY,          /* 'c'  */  PATH_CHAR_CLASS_ANY,
+    /* 'd'  */  PATH_CHAR_CLASS_ANY,          /* 'e'  */  PATH_CHAR_CLASS_ANY,
+    /* 'f'  */  PATH_CHAR_CLASS_ANY,          /* 'g'  */  PATH_CHAR_CLASS_ANY,
+    /* 'h'  */  PATH_CHAR_CLASS_ANY,          /* 'i'  */  PATH_CHAR_CLASS_ANY,
+    /* 'j'  */  PATH_CHAR_CLASS_ANY,          /* 'k'  */  PATH_CHAR_CLASS_ANY,
+    /* 'l'  */  PATH_CHAR_CLASS_ANY,          /* 'm'  */  PATH_CHAR_CLASS_ANY,
+    /* 'n'  */  PATH_CHAR_CLASS_ANY,          /* 'o'  */  PATH_CHAR_CLASS_ANY,
+    /* 'p'  */  PATH_CHAR_CLASS_ANY,          /* 'q'  */  PATH_CHAR_CLASS_ANY,
+    /* 'r'  */  PATH_CHAR_CLASS_ANY,          /* 's'  */  PATH_CHAR_CLASS_ANY,
+    /* 't'  */  PATH_CHAR_CLASS_ANY,          /* 'u'  */  PATH_CHAR_CLASS_ANY,
+    /* 'v'  */  PATH_CHAR_CLASS_ANY,          /* 'w'  */  PATH_CHAR_CLASS_ANY,
+    /* 'x'  */  PATH_CHAR_CLASS_ANY,          /* 'y'  */  PATH_CHAR_CLASS_ANY,
+    /* 'z'  */  PATH_CHAR_CLASS_ANY,          /* '{'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '|'  */  PATH_CHAR_CLASS_INVALID,      /* '}'  */  PATH_CHAR_CLASS_OTHER_VALID,
+    /* '~'  */  PATH_CHAR_CLASS_OTHER_VALID
+};
 
-  if (('A' <= Ch && Ch <= 'Z') || ('a' <= Ch && Ch <= 'z'))
-  {
-    return (Class & PATH_CHAR_CLASS_LETTER);
-  }
-
-  if (('0' <= Ch && Ch <= '9') || 0x80 <= Ch)
-  {
-    return (Class & PATH_CHAR_CLASS_OTHER_VALID);
-  }
-
-  for (Index = 0; Index < sizeof(CharClass) / sizeof(CharClass[0]); Index++)
-  {
-    if (Ch == CharClass[Index].Ch)
-    {
-      return (Class & CharClass[Index].Class);
-    }
-  }
-
-  return FALSE;
-}
-
 /*************************************************************************
  * @     [SHLWAPI.455]
  *
- * Check if an Ascii char is of a certain class
+ * Check if an ASCII char is of a certain class
  */
-BOOL WINAPI PathIsValidCharA(char Ch, DWORD Class)
+BOOL WINAPI PathIsValidCharA( char c, DWORD class )
 {
-  return PathIsValidCharAW((unsigned) Ch, Class);
+    if ((unsigned)c > 0x7e)
+        return class & PATH_CHAR_CLASS_OTHER_VALID;
+
+    return class & SHELL_charclass[(unsigned)c];
 }
 
 /*************************************************************************
  * @     [SHLWAPI.456]
  *
- * Check if an Unicode char is of a certain class
+ * Check if a Unicode char is of a certain class
  */
-BOOL WINAPI PathIsValidCharW(WCHAR Ch, DWORD Class)
+BOOL WINAPI PathIsValidCharW( WCHAR c, DWORD class )
 {
-  return PathIsValidCharAW((unsigned) Ch, Class);
+    if (c > 0x7e)
+        return class & PATH_CHAR_CLASS_OTHER_VALID;
+
+    return class & SHELL_charclass[c];
 }

Modified: trunk/reactos/lib/shlwapi/reg.c
--- trunk/reactos/lib/shlwapi/reg.c	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/reg.c	2005-02-14 14:50:45 UTC (rev 13559)
@@ -207,6 +207,150 @@
 }
 
 /*************************************************************************
+ * SHRegCreateUSKeyA  [SHLWAPI.@]
+ *
+ * Create or open a user-specific registry key.
+ * 
+ * PARAMS
+ *  pszPath        [I] Key name to create or open.
+ *  samDesired     [I] Wanted security access.
+ *  hRelativeUSKey [I] Base path if pszPath is relative. NULL otherwise.
+ *  phNewUSKey     [O] Receives a handle to the new or openened key.
+ *  dwFlags        [I] Base key under which the key should be opened.
+ *
+ * RETURNS
+ *  Success: ERROR_SUCCESS
+ *  Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegCreateUSKeyA(LPCSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
+                              PHUSKEY phNewUSKey, DWORD dwFlags)
+{
+    FIXME("(%s, 0x%08lx, %p, %p, 0x%08lx) stub\n", debugstr_a(pszPath), samDesired,
+          hRelativeUSKey, phNewUSKey, dwFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegCreateUSKeyW  [SHLWAPI.@]
+ *
+ * See SHRegCreateUSKeyA.
+ */
+LONG WINAPI SHRegCreateUSKeyW(LPCWSTR pszPath, REGSAM samDesired, HUSKEY hRelativeUSKey,
+                              PHUSKEY phNewUSKey, DWORD dwFlags)
+{
+    FIXME("(%s, 0x%08lx, %p, %p, 0x%08lx) stub\n", debugstr_w(pszPath), samDesired,
+          hRelativeUSKey, phNewUSKey, dwFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteEmptyUSKeyA  [SHLWAPI.@]
+ *
+ * Delete an empty user-specific registry key.
+ *
+ * PARAMS
+ *  hUSKey      [I] Handle to an open registry key.
+ *  pszValue    [I] Empty key name.
+ *  delRegFlags [I] Flag that specifies the base from which to delete 
+ *                  the key.
+ *
+ * RETURNS
+ *  Success: ERROR_SUCCESS
+ *  Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegDeleteEmptyUSKeyA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+    FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteEmptyUSKeyW  [SHLWAPI.@]
+ *
+ * See SHRegDeleteEmptyUSKeyA.
+ */
+LONG WINAPI SHRegDeleteEmptyUSKeyW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+    FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteUSValueA  [SHLWAPI.@]
+ *
+ * Delete a user-specific registry value.
+ *
+ * PARAMS
+ *  hUSKey      [I] Handle to an open registry key.
+ *  pszValue    [I] Specifies the value to delete.
+ *  delRegFlags [I] Flag that specifies the base of the key from which to
+ *                  delete the value.
+ *
+ * RETURNS
+ *  Success: ERROR_SUCCESS
+ *  Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegDeleteUSValueA(HUSKEY hUSKey, LPCSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+    FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_a(pszValue), delRegFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegDeleteUSValueW  [SHLWAPI.@]
+ *
+ * See SHRegDeleteUSValueA.
+ */
+LONG WINAPI SHRegDeleteUSValueW(HUSKEY hUSKey, LPCWSTR pszValue, SHREGDEL_FLAGS delRegFlags)
+{
+    FIXME("(%p, %s, 0x%08x) stub\n", hUSKey, debugstr_w(pszValue), delRegFlags);
+    return ERROR_SUCCESS;
+}
+
+/*************************************************************************
+ * SHRegEnumUSValueA  [SHLWAPI.@]
+ *
+ * Enumerate values of a specified registry key.
+ *
+ * PARAMS
+ *  hUSKey           [I]   Handle to an open registry key.
+ *  dwIndex          [I]   Index of the value to be retrieved.
+ *  pszValueName     [O]   Buffer to receive the value name.
+ *  pcchValueNameLen [I]   Size of pszValueName in characters.
+ *  pdwType          [O]   Receives data type of the value.
+ *  pvData           [O]   Receives value data. May be NULL.
+ *  pcbData          [I/O] Size of pvData in bytes.
+ *  enumRegFlags     [I]   Flag that specifies the base key under which to
+ *                         enumerate values.
+ *
+ * RETURNS
+ *  Success: ERROR_SUCCESS
+ *  Failure: Nonzero error code from winerror.h
+ */
+LONG WINAPI SHRegEnumUSValueA(HUSKEY hUSKey, DWORD dwIndex, LPSTR pszValueName,
+                              LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
+                              LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
+{
+    FIXME("(%p, 0x%08lx, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
+          debugstr_a(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
+    return ERROR_INVALID_FUNCTION;
+}
+
+/*************************************************************************
+ * SHRegEnumUSValueW  [SHLWAPI.@]
+ *
+ * See SHRegEnumUSValueA.
+ */
+LONG WINAPI SHRegEnumUSValueW(HUSKEY hUSKey, DWORD dwIndex, LPWSTR pszValueName,
+                              LPDWORD pcchValueNameLen, LPDWORD pdwType, LPVOID pvData,
+                              LPDWORD pcbData, SHREGENUM_FLAGS enumRegFlags)
+{
+    FIXME("(%p, 0x%08lx, %s, %p, %p, %p, %p, 0x%08x) stub\n", hUSKey, dwIndex,
+          debugstr_w(pszValueName), pcchValueNameLen, pdwType, pvData, pcbData, enumRegFlags);
+    return ERROR_INVALID_FUNCTION;
+}
+
+/*************************************************************************
  *      SHRegQueryUSValueA	[SHLWAPI.@]
  *
  * Query a user-specific registry value.
@@ -2038,9 +2182,9 @@
  * Copy a key and its values/sub keys to another location.
  *
  * PARAMS
+ *  hKeySrc    [I] Source key to copy from
+ *  lpszSubKey [I] Sub key under hKeyDst, or NULL to use hKeyDst directly
  *  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
@@ -2052,16 +2196,16 @@
  *  (It will loop until out of stack, or the registry is full). This
  *  bug is present in Win32 also.
  */
-DWORD WINAPI SHCopyKeyA(HKEY hKeyDst, LPCSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+DWORD WINAPI SHCopyKeyA(HKEY hKeySrc, LPCSTR lpszSubKey, HKEY hKeyDst, DWORD dwReserved)
 {
   WCHAR szSubKeyW[MAX_PATH];
 
-  TRACE("(hkey=%p,%s,%p08x,%ld)\n", hKeyDst, debugstr_a(lpszSubKey), hKeySrc, dwReserved);
+  TRACE("(hkey=%p,%s,%p08x,%ld)\n", hKeySrc, debugstr_a(lpszSubKey), hKeyDst, dwReserved);
 
   if (lpszSubKey)
     MultiByteToWideChar(0, 0, lpszSubKey, -1, szSubKeyW, MAX_PATH);
 
-  return SHCopyKeyW(hKeyDst, lpszSubKey ? szSubKeyW : NULL, hKeySrc, dwReserved);
+  return SHCopyKeyW(hKeySrc, lpszSubKey ? szSubKeyW : NULL, hKeyDst, dwReserved);
 }
 
 /*************************************************************************
@@ -2069,7 +2213,7 @@
  *
  * See SHCopyKeyA.
  */
-DWORD WINAPI SHCopyKeyW(HKEY hKeyDst, LPCWSTR lpszSubKey, HKEY hKeySrc, DWORD dwReserved)
+DWORD WINAPI SHCopyKeyW(HKEY hKeySrc, LPCWSTR lpszSubKey, HKEY hKeyDst, DWORD dwReserved)
 {
   DWORD dwKeyCount = 0, dwValueCount = 0, dwMaxKeyLen = 0;
   DWORD  dwMaxValueLen = 0, dwMaxDataLen = 0, i;
@@ -2078,7 +2222,7 @@
   WCHAR szName[MAX_PATH], *lpszName = szName;
   DWORD dwRet = S_OK;
 
-  TRACE("hkey=%p,%s,%p08x,%ld)\n", hKeyDst, debugstr_w(lpszSubKey), hKeySrc, dwReserved);
+  TRACE("hkey=%p,%s,%p08x,%ld)\n", hKeySrc, debugstr_w(lpszSubKey), hKeyDst, dwReserved);
 
   if(!hKeyDst || !hKeySrc)
     dwRet = ERROR_INVALID_PARAMETER;
@@ -2134,7 +2278,7 @@
         if(!dwRet)
         {
           /* Recursively copy keys and values from the sub key */
-          dwRet = SHCopyKeyW(hSubKeyDst, NULL, hSubKeySrc, 0);
+          dwRet = SHCopyKeyW(hSubKeySrc, NULL, hSubKeyDst, 0);
           RegCloseKey(hSubKeyDst);
         }
       }

Modified: trunk/reactos/lib/shlwapi/regstream.c
--- trunk/reactos/lib/shlwapi/regstream.c	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/regstream.c	2005-02-14 14:50:45 UTC (rev 13559)
@@ -75,10 +75,11 @@
 static ULONG WINAPI IStream_fnAddRef(IStream *iface)
 {
 	ISHRegStream *This = (ISHRegStream *)iface;
+	ULONG refCount = InterlockedIncrement(&This->ref);
+	
+	TRACE("(%p)->(ref before=%lu)\n",This, refCount - 1);
 
-	TRACE("(%p)->(count=%lu)\n",This, This->ref);
-
-	return InterlockedIncrement(&This->ref);
+	return refCount;
 }
 
 /**************************************************************************
@@ -87,10 +88,11 @@
 static ULONG WINAPI IStream_fnRelease(IStream *iface)
 {
 	ISHRegStream *This = (ISHRegStream *)iface;
+	ULONG refCount = InterlockedDecrement(&This->ref);
 
-	TRACE("(%p)->()\n",This);
+	TRACE("(%p)->(ref before=%lu)\n",This, refCount + 1);
 
-	if (!InterlockedDecrement(&This->ref))
+	if (!refCount)
 	{
 	  TRACE(" destroying SHReg IStream (%p)\n",This);
 
@@ -102,7 +104,8 @@
 	  HeapFree(GetProcessHeap(),0,This);
 	  return 0;
 	}
-	return This->ref;
+
+	return refCount;
 }
 
 /**************************************************************************

Modified: trunk/reactos/lib/shlwapi/shlwapi.spec
--- trunk/reactos/lib/shlwapi/shlwapi.spec	2005-02-14 14:36:03 UTC (rev 13558)
+++ trunk/reactos/lib/shlwapi/shlwapi.spec	2005-02-14 14:50:45 UTC (rev 13559)
@@ -687,16 +687,16 @@
 @ stdcall SHQueryValueExA(long str ptr ptr ptr ptr)
 @ stdcall SHQueryValueExW(long wstr ptr ptr ptr ptr)
 @ stdcall SHRegCloseUSKey(ptr)
-@ stub    SHRegCreateUSKeyA
-@ stub    SHRegCreateUSKeyW
-@ stub    SHRegDeleteEmptyUSKeyA
-@ stub    SHRegDeleteEmptyUSKeyW
-@ stub    SHRegDeleteUSValueA
-@ stub    SHRegDeleteUSValueW
+@ stdcall SHRegCreateUSKeyA(str long long ptr long)
+@ stdcall SHRegCreateUSKeyW(wstr long long ptr long)
+@ stdcall SHRegDeleteEmptyUSKeyA(long str long)
+@ stdcall SHRegDeleteEmptyUSKeyW(long wstr long)
+@ stdcall SHRegDeleteUSValueA(long str long)
+@ stdcall SHRegDeleteUSValueW(long wstr long)
 @ stdcall SHRegEnumUSKeyA(long long str ptr long)
 @ stdcall SHRegEnumUSKeyW(long long wstr ptr long)
-@ stub    SHRegEnumUSValueA
-@ stub    SHRegEnumUSValueW
+@ stdcall SHRegEnumUSValueA(long long ptr ptr ptr ptr ptr long)
+@ stdcall SHRegEnumUSValueW(long long ptr ptr ptr ptr ptr long)
 @ stdcall SHRegGetBoolUSValueA(str str long long)
 @ stdcall SHRegGetBoolUSValueW(wstr wstr long long)
 @ stdcall SHRegGetUSValueA ( str str ptr ptr ptr long ptr long )
@@ -814,8 +814,8 @@
 @ stdcall _SHGetInstanceExplorer(ptr)
 @ stdcall PathUndecorateA(str)
 @ stdcall PathUndecorateW(wstr)
-@ stub    PathUnExpandEnvStringsA
-@ stub    PathUnExpandEnvStringsW
+@ stdcall PathUnExpandEnvStringsA(str ptr long)
+@ stdcall PathUnExpandEnvStringsW(wstr ptr long)
 @ stdcall SHCopyKeyA(long str long long)
 @ stdcall SHCopyKeyW(long wstr long long)
 @ stdcall SHAutoComplete(ptr long)