From 1b7f3698f076458a2bb5aff808ef49f4d2ec8229 Mon Sep 17 00:00:00 2001 From: Akihiro Sagawa Date: Thu, 9 May 2019 22:07:27 +0900 Subject: [PATCH] advapi32: Support the base directory parameter in RegLoadMUIString. Signed-off-by: Akihiro Sagawa Signed-off-by: Alexandre Julliard --- 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 43ea3b3d2a8..469818cbb40 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 f5bcbf34e04..d6edb02ba4b 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 4a4c494b4fc..256cd625d4a 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); }