[RESEND] [bug9037] advpack should strip single quotes (with tests) on reg keys

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


Tests show setupapi ignores single quotes and that advpack strips them
off. Note tests show another bug in that windows (probably setupapi) treats
%24% as C:\  but %24%\dir as C:\dir, ie it must be applying some
intelligence for the quotes. (but thats outside this bug but prevents all 
the tests from being 100% successful).

Resent alongside following patch which fixes the additional problem identified.

---
 dlls/advpack/advpack.c       |   18 ++++++++++++-
 dlls/advpack/tests/advpack.c |   59 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 75 insertions(+), 2 deletions(-)

diff --git a/dlls/advpack/advpack.c b/dlls/advpack/advpack.c
index 157413f..4f8d93c 100644
--- a/dlls/advpack/advpack.c
+++ b/dlls/advpack/advpack.c
@@ -49,6 +49,18 @@ static const WCHAR setup_key[] = {
     'C','o','m','p','o','n','e','n','t','s',0
 };
 
+/* Strip single quotes from a token - note size includes NULL */
+void strip_quotes(WCHAR *buffer, DWORD *size) {
+    if (buffer[0] == '\'' && (*size > 1) && buffer[*size-2]=='\'') 
+    {
+        WCHAR value[MAX_PATH];
+        buffer[*size-2] = 0x00;
+        lstrcpyW(value, &buffer[1]);
+        *size = *size - 2;
+        lstrcpyW(buffer, value);
+    }
+}
+
 /* parses the destination directory parameters from pszSection
  * the parameters are of the form: root,key,value,unknown,fallback
  * we first read the reg value root\\key\\value and if that fails,
@@ -68,8 +80,11 @@ static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dw
     /* load the destination parameters */
     SetupFindFirstLineW(hInf, pszSection, NULL, &context);
     SetupGetStringFieldW(&context, 1, prefix, PREFIX_LEN, &size);
+    strip_quotes(prefix, &size);
     SetupGetStringFieldW(&context, 2, key, MAX_PATH, &size);
+    strip_quotes(key, &size);
     SetupGetStringFieldW(&context, 3, value, MAX_PATH, &size);
+    strip_quotes(value, &size);
 
     if (!lstrcmpW(prefix, hklm))
         root = HKEY_LOCAL_MACHINE;
@@ -84,7 +99,8 @@ static void get_dest_dir(HINF hInf, PCWSTR pszSection, PWSTR pszBuffer, DWORD dw
     if (RegOpenKeyW(root, key, &subkey) ||
         RegQueryValueExW(subkey, value, NULL, NULL, (LPBYTE)pszBuffer, &size))
     {
-        SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, NULL);
+        SetupGetStringFieldW(&context, 5, pszBuffer, dwSize, &size);
+        strip_quotes(pszBuffer, &size);
     }
 
     RegCloseKey(subkey);
diff --git a/dlls/advpack/tests/advpack.c b/dlls/advpack/tests/advpack.c
index 7218b59..9d65cb3 100644
--- a/dlls/advpack/tests/advpack.c
+++ b/dlls/advpack/tests/advpack.c
@@ -43,6 +43,7 @@ static HRESULT (WINAPI *pTranslateInfString)(LPCSTR,LPCSTR,LPCSTR,LPCSTR,LPSTR,D
 static HRESULT (WINAPI *pTranslateInfStringEx)(HINF,PCSTR,PCSTR,PCSTR,PSTR,DWORD,PDWORD,PVOID);
 
 static CHAR inf_file[MAX_PATH];
+static CHAR PROG_FILES_ROOT[MAX_PATH];
 static CHAR PROG_FILES[MAX_PATH];
 static DWORD PROG_FILES_LEN;
 
@@ -52,9 +53,10 @@ static void get_progfiles_dir(void)
     DWORD size = MAX_PATH;
 
     RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion", &hkey);
-    RegQueryValueExA(hkey, "ProgramFilesDir", NULL, NULL, (LPBYTE)PROG_FILES, &size);
+    RegQueryValueExA(hkey, "ProgramFilesDir", NULL, NULL, (LPBYTE)PROG_FILES_ROOT, &size);
     RegCloseKey(hkey);
 
+    lstrcpyA(PROG_FILES, PROG_FILES_ROOT);
     lstrcatA(PROG_FILES, TEST_STRING1);
     PROG_FILES_LEN = lstrlenA(PROG_FILES) + 1;
 }
@@ -198,6 +200,9 @@ static void create_inf_file(void)
     append_str(&ptr, "Signature=\"$Chicago$\"\n");
     append_str(&ptr, "[CustInstDestSection]\n");
     append_str(&ptr, "49001=ProgramFilesDir\n");
+    append_str(&ptr, "49010=DestA,1\n");
+    append_str(&ptr, "49020=DestB\n");
+    append_str(&ptr, "49030=DestC\n");
     append_str(&ptr, "[ProgramFilesDir]\n");
     append_str(&ptr, "HKLM,\"Software\\Microsoft\\Windows\\CurrentVersion\",");
     append_str(&ptr, "\"ProgramFilesDir\",,\"%%24%%\\%%LProgramF%%\"\n");
@@ -207,10 +212,20 @@ static void create_inf_file(void)
     append_str(&ptr, "[Options.NTx86]\n");
     append_str(&ptr, "49001=ProgramFilesDir\n");
     append_str(&ptr, "InstallDir=%%49001%%\\%%DefaultAppPath%%\n");
+    append_str(&ptr, "Result1=%%49010%%\n");
+    append_str(&ptr, "Result2=%%49020%%\n");
+    append_str(&ptr, "Result3=%%49030%%\n");
     append_str(&ptr, "CustomHDestination=CustInstDestSection\n");
     append_str(&ptr, "[Strings]\n");
     append_str(&ptr, "DefaultAppPath=\"Application Name\"\n");
     append_str(&ptr, "LProgramF=\"Program Files\"\n");
+    append_str(&ptr, "[DestA]\n");
+    append_str(&ptr, "HKLM,\"Software\\Garbage\",\"ProgramFilesDir\",,'%%24%%\\%%LProgramF%%'\n");
+    append_str(&ptr, "[DestB]\n");
+    append_str(&ptr, "'HKLM','Software\\Microsoft\\Windows\\CurrentVersion',");
+    append_str(&ptr, "'ProgramFilesDir',,\"%%24%%\"\n");
+    append_str(&ptr, "[DestC]\n");
+    append_str(&ptr, "HKLM,\"Software\\Garbage\",\"ProgramFilesDir\",,'%%24%%'\n");
 
     WriteFile(hf, data, ptr - data, &dwNumberOfBytesWritten, NULL);
     CloseHandle(hf);
@@ -397,6 +412,48 @@ static void translateinfstringex_test(void)
     ok(!strcmp(buffer, PROG_FILES), "Expected %s, got %s\n", PROG_FILES, buffer);
     ok(size == PROG_FILES_LEN, "Expected size %d, got %d\n", PROG_FILES_LEN, size);
 
+    /* Single quote test (Note size includes null on return from call) */
+    memset(buffer, 'a', PROG_FILES_LEN);
+    buffer[PROG_FILES_LEN - 1] = '\0';
+    size = MAX_PATH;
+    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);
+    }
+
+    memset(buffer, 'a', PROG_FILES_LEN);
+    buffer[PROG_FILES_LEN - 1] = '\0';
+    size = MAX_PATH;
+    hr = pTranslateInfStringEx(hinf, inf_file, "Options.NTx86", "Result2",
+                              buffer, size, &size, NULL);
+    ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+    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);
+
+    {
+        char drive[MAX_PATH];
+        lstrcpy(drive, PROG_FILES_ROOT);
+        drive[3] = 0x00; /* Just keep the system drive plus '\' */
+
+        memset(buffer, 'a', PROG_FILES_LEN);
+        buffer[PROG_FILES_LEN - 1] = '\0';
+        size = MAX_PATH;
+        hr = pTranslateInfStringEx(hinf, inf_file, "Options.NTx86", "Result3",
+                                  buffer, size, &size, NULL);
+        ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+        ok(!lstrcmpi(buffer, drive), 
+               "Expected %s, got %s\n", drive, buffer);
+        ok(size == lstrlenA(drive)+1, "Expected size %d, got %d\n", 
+               lstrlenA(drive)+1, size);
+    }
+
     /* close the INF again */
     hr = pCloseINFEngine(hinf);
     ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
-- 
1.5.0




More information about the wine-patches mailing list