[SHELL32]
authorAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Apr 2013 22:52:34 +0000 (22:52 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Thu, 25 Apr 2013 22:52:34 +0000 (22:52 +0000)
* Sync DoEnvironmentSubst{A,W} with Wine 1.5.26. Fixes issues spotted by Victor Martinez.
CORE-7124 #resolve

svn path=/trunk/; revision=58854

reactos/dll/win32/shell32/shellord.cpp

index c1616d7..cd6abc1 100644 (file)
@@ -1492,63 +1492,78 @@ EXTERN_C BOOL WINAPI SHValidateUNC (HWND hwndOwner, LPWSTR pszFile, UINT fConnec
 }
 
 /************************************************************************
- *    DoEnvironmentSubstA            [SHELL32.@]
+ * DoEnvironmentSubstA [SHELL32.@]
  *
- * Replace %KEYWORD% in the str with the value of variable KEYWORD
- * from environment. If it is not found the %KEYWORD% is left
- * intact. If the buffer is too small, str is not modified.
- *
- * PARAMS
- *  pszString  [I] '\0' terminated string with %keyword%.
- *             [O] '\0' terminated string with %keyword% substituted.
- *  cchString  [I] size of str.
- *
- * RETURNS
- *     cchString length in the HIWORD;
- *     TRUE in LOWORD if subst was successful and FALSE in other case
+ * See DoEnvironmentSubstW.
  */
 EXTERN_C DWORD WINAPI DoEnvironmentSubstA(LPSTR pszString, UINT cchString)
 {
     LPSTR dst;
     BOOL res = FALSE;
-    FIXME("(%s, %d) stub\n", debugstr_a(pszString), cchString);
+    DWORD len = cchString;
+
+    TRACE("(%s, %d)\n", debugstr_a(pszString), cchString);
     if (pszString == NULL) /* Really return 0? */
         return 0;
     if ((dst = (LPSTR)HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(CHAR))))
     {
-        DWORD num = ExpandEnvironmentStringsA(pszString, dst, cchString);
-        if (num && num < cchString) /* dest buffer is too small */
+        len = ExpandEnvironmentStringsA(pszString, dst, cchString);
+        /* len includes the terminating 0 */
+        if (len && len < cchString)
         {
             res = TRUE;
-            memcpy(pszString, dst, num);
+            memcpy(pszString, dst, len);
         }
+        else
+            len = cchString;
+
         HeapFree(GetProcessHeap(), 0, dst);
     }
-    return MAKELONG(res,cchString); /* Always cchString? */
+    return MAKELONG(len, res);
 }
 
 /************************************************************************
- *    DoEnvironmentSubstW            [SHELL32.@]
+ * DoEnvironmentSubstW [SHELL32.@]
  *
- * See DoEnvironmentSubstA.
+ * Replace all %KEYWORD% in the string with the value of the named
+ * environment variable. If the buffer is too small, the string is not modified.
+ *
+ * PARAMS
+ *  pszString  [I] '\0' terminated string with %keyword%.
+ *             [O] '\0' terminated string with %keyword% substituted.
+ *  cchString  [I] size of str.
+ *
+ * RETURNS
+ *  Success:  The string in the buffer is updated
+ *            HIWORD: TRUE
+ *            LOWORD: characters used in the buffer, including space for the terminating 0
+ *  Failure:  buffer too small. The string is not modified.
+ *            HIWORD: FALSE
+ *            LOWORD: provided size of the buffer in characters
  */
 EXTERN_C DWORD WINAPI DoEnvironmentSubstW(LPWSTR pszString, UINT cchString)
 {
     LPWSTR dst;
     BOOL res = FALSE;
-    FIXME("(%s, %d): stub\n", debugstr_w(pszString), cchString);
-    if ((dst = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(WCHAR))))
+    DWORD len = cchString;
+
+    TRACE("(%s, %d)\n", debugstr_w(pszString), cchString);
+
+    if ((cchString < MAXLONG) && (dst = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cchString * sizeof(WCHAR))))
     {
-        DWORD num = ExpandEnvironmentStringsW(pszString, dst, cchString);
-        if (num)
+        len = ExpandEnvironmentStringsW(pszString, dst, cchString);
+        /* len includes the terminating 0 */
+        if (len && len <= cchString)
         {
             res = TRUE;
-            wcscpy(pszString, dst);
+            memcpy(pszString, dst, len * sizeof(WCHAR));
         }
+        else
+            len = cchString;
+
         HeapFree(GetProcessHeap(), 0, dst);
     }
-
-    return MAKELONG(res,cchString);
+    return MAKELONG(len, res);
 }
 
 /************************************************************************