[PATCH] [bug9037] Fix setupapi intelligence to remove duplicate \\'s

Jason Edmeades jason.edmeades at googlemail.com
Fri Aug 10 16:28:35 CDT 2007


I noticed the paths were still wrong after the single quote fix
(still unapplied, includes additional test showing this bug).
This fix adds tests to prove that if an integer directory replacement
occurs, then it avoids a double slash (if one ends in slash and the
other starts with it). It also adds tests to prove this does not
occur if it is a standard string replacement.
---
 dlls/advpack/tests/advpack.c |   10 ++++------
 dlls/setupapi/parser.c       |   17 +++++++++++++++--
 dlls/setupapi/tests/parser.c |   12 ++++++++++++
 3 files changed, 31 insertions(+), 8 deletions(-)

diff --git a/dlls/advpack/tests/advpack.c b/dlls/advpack/tests/advpack.c
index 9d65cb3..0b4d254 100644
--- a/dlls/advpack/tests/advpack.c
+++ b/dlls/advpack/tests/advpack.c
@@ -419,12 +419,10 @@ static void translateinfstringex_test(void)
     hr = pTranslateInfStringEx(hinf, inf_file, "Options.NTx86", "Result1",
                               buffer, size, &size, NULL);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
-    todo_wine {  /* Wine returns C:\\Program Files, not C:\Program Files */
-      ok(!lstrcmpi(buffer, PROG_FILES_ROOT), 
-             "Expected %s, got %s\n", PROG_FILES_ROOT, buffer);
-      ok(size == lstrlenA(PROG_FILES_ROOT)+1, "Expected size %d, got %d\n", 
-             lstrlenA(PROG_FILES_ROOT)+1, size);
-    }
+    ok(!lstrcmpi(buffer, PROG_FILES_ROOT), 
+           "Expected %s, got %s\n", PROG_FILES_ROOT, buffer);
+    ok(size == lstrlenA(PROG_FILES_ROOT)+1, "Expected size %d, got %d\n", 
+           lstrlenA(PROG_FILES_ROOT)+1, size);
 
     memset(buffer, 'a', PROG_FILES_LEN);
     buffer[PROG_FILES_LEN - 1] = '\0';
diff --git a/dlls/setupapi/parser.c b/dlls/setupapi/parser.c
index ea410f8..c69525d 100644
--- a/dlls/setupapi/parser.c
+++ b/dlls/setupapi/parser.c
@@ -316,7 +316,8 @@ static const WCHAR *get_dirid_subst( struct inf_file *file, int dirid, unsigned
 
 /* retrieve the string substitution for a given string, or NULL if not found */
 /* if found, len is set to the substitution length */
-static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, unsigned int *len )
+static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, unsigned int *len,
+                                      BOOL *wasInt )
 {
     static const WCHAR percent = '%';
 
@@ -353,6 +354,7 @@ static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, u
         dirid_str[*len] = 0;
         dirid = strtolW( dirid_str, &end, 10 );
         if (!*end) ret = get_dirid_subst( file, dirid, len );
+        if (ret) *wasInt = TRUE;
         HeapFree( GetProcessHeap(), 0, dirid_str );
         return ret;
     }
@@ -386,8 +388,9 @@ unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCH
         }
         else /* end of the %xx% string, find substitution */
         {
+            BOOL wasInt = FALSE;
             len = p - start - 1;
-            subst = get_string_subst( file, start + 1, &len );
+            subst = get_string_subst( file, start + 1, &len, &wasInt );
             if (!subst)
             {
                 subst = start;
@@ -398,6 +401,16 @@ unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCH
             total += len;
             size -= len;
             start = p + 1;
+
+            /* If an integer ID was used and it ends in '\' and the next
+               character to replace is a '\' only insert one             */
+            if (wasInt && subst) {
+                if (subst[lstrlenW(subst) - 1] == '\\' &&
+                    p[1] == '\\') {
+                    total = total - 1;
+                    size  = size + 1;
+                }
+            }
         }
     }
 
diff --git a/dlls/setupapi/tests/parser.c b/dlls/setupapi/tests/parser.c
index 858c889..eeb733f 100644
--- a/dlls/setupapi/tests/parser.c
+++ b/dlls/setupapi/tests/parser.c
@@ -60,6 +60,7 @@ static const char tmpfilename[] = ".\\tmp.inf";
 #define STR_SECTION "[Strings]\nfoo=aaa\nbar=bbb\nloop=%loop2%\nloop2=%loop%\n" \
                     "per%%cent=abcd\nper=1\ncent=2\n22=foo\n" \
                     "big=" A400 "\n" \
+                    "mydrive=\"C:\\\"\n" \
                     "verybig=" A400 A400 A400 "\n"
 
 /* create a new file with specified contents and open it */
@@ -284,6 +285,7 @@ static const struct
  { "ab=cd\",\"ef",         "ab",            { "cd,ef" } },
  { "ab=cd\",ef",           "ab",            { "cd,ef" } },
  { "ab=cd\",ef\\\nab",     "ab",            { "cd,ef\\" } },
+
  /* single quotes (unhandled)*/
  { "HKLM,A,B,'C',D",       NULL,            { "HKLM", "A","B","'C'","D" } },
  /* spaces */
@@ -317,6 +319,16 @@ static const struct
  { "a=%big%%big%%big%%big%\n" STR_SECTION,   "a", { A400 A400 A400 A400 } },
  { "a=%big%%big%%big%%big%%big%%big%%big%%big%%big%\n" STR_SECTION,   "a", { A400 A400 A400 A400 A400 A400 A400 A400 A400 } },
  { "a=%big%%big%%big%%big%%big%%big%%big%%big%%big%%big%%big%\n" STR_SECTION,   "a", { A4097 /*MAX_INF_STRING_LENGTH+1*/ } },
+ 
+ /* Prove expansion of system entries removes extra \'s and string
+    replacements doesnt                                            */
+ { "ab=\"%24%\"\n" STR_SECTION,           "ab", { "C:\\" } },
+ { "ab=\"%mydrive%\"\n" STR_SECTION,      "ab", { "C:\\" } },
+ { "ab=\"%24%\\fred\"\n" STR_SECTION,     "ab", { "C:\\fred" } },
+ { "ab=\"%mydrive%\\fred\"\n" STR_SECTION,"ab", { "C:\\\\fred" } },
+ /* Confirm duplicate \'s kept */
+ { "ab=\"%24%\\\\fred\"",      "ab",            { "C:\\\\fred" } },  
+ { "ab=C:\\\\FRED",            "ab",            { "C:\\\\FRED" } },
 };
 
 /* check the key of a certain line */
-- 
1.5.0




More information about the wine-patches mailing list