Akihiro Sagawa : advapi32: Support the base directory parameter in RegLoadMUIString.

Alexandre Julliard julliard at winehq.org
Mon May 13 16:24:17 CDT 2019


Module: wine
Branch: master
Commit: 1b7f3698f076458a2bb5aff808ef49f4d2ec8229
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1b7f3698f076458a2bb5aff808ef49f4d2ec8229

Author: Akihiro Sagawa <sagawa.aki at gmail.com>
Date:   Thu May  9 22:07:27 2019 +0900

advapi32: Support the base directory parameter in RegLoadMUIString.

Signed-off-by: Akihiro Sagawa <sagawa.aki at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/advapi32/registry.c       | 45 +++++++++++++++++++++++++++++++-----------
 dlls/advapi32/tests/registry.c |  4 ++--
 dlls/kernel32/time.c           |  2 +-
 3 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/dlls/advapi32/registry.c b/dlls/advapi32/registry.c
index 43ea3b3..469818c 100644
--- a/dlls/advapi32/registry.c
+++ b/dlls/advapi32/registry.c
@@ -3161,7 +3161,7 @@ static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMa
  *  cbBuffer   [I] Size of the destination buffer in bytes.
  *  pcbData    [O] Number of bytes written to pszBuffer (optional, may be NULL).
  *  dwFlags    [I] None supported yet.
- *  pszBaseDir [I] Not supported yet.
+ *  pszBaseDir [I] Base directory of loading path. If NULL, use the current directory.
  *
  * RETURNS
  *  Success: ERROR_SUCCESS,
@@ -3177,7 +3177,7 @@ LSTATUS WINAPI RegLoadMUIStringW(HKEY hKey, LPCWSTR pwszValue, LPWSTR pwszBuffer
     DWORD dwValueType, cbData;
     LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL;
     LONG result;
-        
+
     TRACE("(hKey = %p, pwszValue = %s, pwszBuffer = %p, cbBuffer = %d, pcbData = %p, "
           "dwFlags = %d, pwszBaseDir = %s)\n", hKey, debugstr_w(pwszValue), pwszBuffer,
           cbBuffer, pcbData, dwFlags, debugstr_w(pwszBaseDir));
@@ -3186,11 +3186,6 @@ LSTATUS WINAPI RegLoadMUIStringW(HKEY hKey, LPCWSTR pwszValue, LPWSTR pwszBuffer
     if (!hKey || !pwszBuffer)
         return ERROR_INVALID_PARAMETER;
 
-    if (pwszBaseDir && *pwszBaseDir) {
-        FIXME("BaseDir parameter not yet supported!\n");
-        return ERROR_INVALID_PARAMETER;
-    }
-
     /* Check for value existence and correctness of its type, allocate a buffer and load it. */
     result = RegQueryValueExW(hKey, pwszValue, NULL, &dwValueType, NULL, &cbData);
     if (result != ERROR_SUCCESS) goto cleanup;
@@ -3215,7 +3210,7 @@ LSTATUS WINAPI RegLoadMUIStringW(HKEY hKey, LPCWSTR pwszValue, LPWSTR pwszBuffer
             result = ERROR_NOT_ENOUGH_MEMORY;
             goto cleanup;
         }
-        ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData);
+        ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData / sizeof(WCHAR));
     } else {
         pwszExpandedBuffer = heap_alloc(cbData);
         memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData);
@@ -3227,8 +3222,10 @@ LSTATUS WINAPI RegLoadMUIStringW(HKEY hKey, LPCWSTR pwszValue, LPWSTR pwszBuffer
     if (*pwszExpandedBuffer != '@') { /* '@' is the prefix for resource based string entries. */
         lstrcpynW(pwszBuffer, pwszExpandedBuffer, cbBuffer / sizeof(WCHAR));
     } else {
-        WCHAR *pComma = strrchrW(pwszExpandedBuffer, ',');
+        WCHAR *pComma = strrchrW(pwszExpandedBuffer, ','), *pNewBuffer;
+        const WCHAR backslashW[] = {'\\',0};
         UINT uiStringId;
+        DWORD baseDirLen;
         HMODULE hModule;
 
         /* Format of the expanded value is 'path_to_dll,-resId' */
@@ -3236,17 +3233,41 @@ LSTATUS WINAPI RegLoadMUIStringW(HKEY hKey, LPCWSTR pwszValue, LPWSTR pwszBuffer
             result = ERROR_BADKEY;
             goto cleanup;
         }
- 
+
         uiStringId = atoiW(pComma+2);
         *pComma = '\0';
 
-        hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL,
+        /* Build a resource dll path. */
+        baseDirLen = pwszBaseDir ? strlenW(pwszBaseDir) : 0;
+        cbData = (baseDirLen + 1 + strlenW(pwszExpandedBuffer + 1) + 1) * sizeof(WCHAR);
+        pNewBuffer = heap_realloc(pwszTempBuffer, cbData);
+        if (!pNewBuffer) {
+            result = ERROR_NOT_ENOUGH_MEMORY;
+            goto cleanup;
+        }
+        pwszTempBuffer = pNewBuffer;
+        pwszTempBuffer[0] = '\0';
+        if (baseDirLen) {
+            strcpyW(pwszTempBuffer, pwszBaseDir);
+            if (pwszBaseDir[baseDirLen - 1] != '\\')
+                strcatW(pwszTempBuffer, backslashW);
+        }
+        strcatW(pwszTempBuffer, pwszExpandedBuffer + 1);
+
+        /* Verify the file existence. i.e. We don't rely on PATH variable */
+        if (GetFileAttributesW(pwszTempBuffer) == INVALID_FILE_ATTRIBUTES) {
+            result = ERROR_FILE_NOT_FOUND;
+            goto cleanup;
+        }
+
+        /* Load the file */
+        hModule = LoadLibraryExW(pwszTempBuffer, NULL,
                                  LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
         if (!hModule || !load_string(hModule, uiStringId, pwszBuffer, cbBuffer/sizeof(WCHAR)))
             result = ERROR_BADKEY;
         FreeLibrary(hModule);
     }
- 
+
 cleanup:
     heap_free(pwszTempBuffer);
     heap_free(pwszExpandedBuffer);
diff --git a/dlls/advapi32/tests/registry.c b/dlls/advapi32/tests/registry.c
index f5bcbf3..d6edb02 100644
--- a/dlls/advapi32/tests/registry.c
+++ b/dlls/advapi32/tests/registry.c
@@ -3925,7 +3925,7 @@ static void test_RegLoadMUIString(void)
     size = 0xdeadbeef;
     memset(bufW, 0xff, sizeof(bufW));
     ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, ARRAY_SIZE(bufW), &size, 0, sysdirW);
-    todo_wine ok(ret == ERROR_SUCCESS, "got %d, expected ERROR_SUCCESS\n", ret);
+    ok(ret == ERROR_SUCCESS, "got %d, expected ERROR_SUCCESS\n", ret);
     todo_wine ok(size == text_size, "got %u, expected %u\n", size, text_size);
     size = min(size, sizeof(bufW));
     todo_wine ok(!memcmp(textW, bufW, size), "got %s, expected %s\n",
@@ -3935,7 +3935,7 @@ static void test_RegLoadMUIString(void)
     todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED, "got %d, expected ERROR_CALL_NOT_IMPLEMENTED\n", ret);
 
     ret = pRegLoadMUIStringW(hkey, tz_valueW, bufW, ARRAY_SIZE(bufW), &size, 0, NULL);
-    todo_wine ok(ret == ERROR_FILE_NOT_FOUND, "got %d, expected ERROR_FILE_NOT_FOUND\n", ret);
+    ok(ret == ERROR_FILE_NOT_FOUND, "got %d, expected ERROR_FILE_NOT_FOUND\n", ret);
 
     ret = pRegLoadMUIStringA(hkey, tz_value, buf, ARRAY_SIZE(buf), &size, 0, NULL);
     todo_wine ok(ret == ERROR_CALL_NOT_IMPLEMENTED, "got %d, expected ERROR_CALL_NOT_IMPLEMENTED\n", ret);
diff --git a/dlls/kernel32/time.c b/dlls/kernel32/time.c
index 4a4c494..256cd62 100644
--- a/dlls/kernel32/time.c
+++ b/dlls/kernel32/time.c
@@ -380,7 +380,7 @@ static BOOL reg_load_mui_string(HKEY hkey, LPCWSTR value, LPWSTR buffer, DWORD s
     if (hDll) {
         pRegLoadMUIStringW = (void *)GetProcAddress(hDll, "RegLoadMUIStringW");
         if (pRegLoadMUIStringW &&
-            !pRegLoadMUIStringW(hkey, value, buffer, size, NULL, 0, NULL))
+            !pRegLoadMUIStringW(hkey, value, buffer, size, NULL, 0, DIR_System))
             ret = TRUE;
         FreeLibrary(hDll);
     }




More information about the wine-cvs mailing list