From ad3c102e6598d6926e0d302f816acccadd9c1e1e Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 14 Dec 2023 20:02:01 +0200 Subject: [PATCH] [ADVAPI32_VISTA] Move RegLoadMUIStringW to reg.c --- dll/win32/advapi32/reg/reg.c | 190 +++++++++++++++++++ dll/win32/advapi32_vista/CMakeLists.txt | 1 - dll/win32/advapi32_vista/RegLoadMUIString.c | 195 -------------------- 3 files changed, 190 insertions(+), 196 deletions(-) delete mode 100644 dll/win32/advapi32_vista/RegLoadMUIString.c diff --git a/dll/win32/advapi32/reg/reg.c b/dll/win32/advapi32/reg/reg.c index 75c37217e72..38a434fddd7 100644 --- a/dll/win32/advapi32/reg/reg.c +++ b/dll/win32/advapi32/reg/reg.c @@ -5145,4 +5145,194 @@ RegUnLoadKeyW(HKEY hKey, #endif // _ADVAPI32_VISTA_ +/****************************************************************************** + * load_string [Internal] + * + * This is basically a copy of user32/resource.c's LoadStringW. Necessary to + * avoid importing user32, which is higher level than advapi32. Helper for + * RegLoadMUIString. + */ +static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars) +{ + HGLOBAL hMemory; + HRSRC hResource; + WCHAR* pString; + int idxString; + + /* Negative values have to be inverted. */ + if (HIWORD(resId) == 0xffff) + resId = (UINT)(-((INT)resId)); + + /* Load the resource into memory and get a pointer to it. */ + hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING); + if (!hResource) return 0; + hMemory = LoadResource(hModule, hResource); + if (!hMemory) return 0; + pString = LockResource(hMemory); + + /* Strings are length-prefixed. Lowest nibble of resId is an index. */ + idxString = resId & 0xf; + while (idxString--) pString += *pString + 1; + + /* If no buffer is given, return length of the string. */ + if (!pwszBuffer) return *pString; + + /* Else copy over the string, respecting the buffer size. */ + cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1); + if (cMaxChars >= 0) + { + memcpy(pwszBuffer, pString + 1, cMaxChars * sizeof(WCHAR)); + pwszBuffer[cMaxChars] = L'\0'; + } + + return cMaxChars; +} + +/************************************************************************ + * RegLoadMUIStringW + * + * @implemented + */ +LONG WINAPI +RegLoadMUIStringW( + IN HKEY hKey, + IN LPCWSTR pszValue OPTIONAL, + OUT LPWSTR pszOutBuf, + IN DWORD cbOutBuf, + OUT LPDWORD pcbData OPTIONAL, + IN DWORD Flags, + IN LPCWSTR pszDirectory OPTIONAL) +{ + DWORD dwValueType, cbData; + LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL; + LONG result; + + /* Parameter sanity checks. */ + if (!hKey || !pszOutBuf) + return ERROR_INVALID_PARAMETER; + + if (pszDirectory && *pszDirectory) + { + FIXME("BaseDir parameter not yet supported!\n"); + return ERROR_INVALID_PARAMETER; + } + + /* Check for value existence and correctness of it's type, allocate a buffer and load it. */ + result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData); + if (result != ERROR_SUCCESS) goto cleanup; + if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData) + { + result = ERROR_FILE_NOT_FOUND; + goto cleanup; + } + pwszTempBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); + if (!pwszTempBuffer) + { + result = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData); + if (result != ERROR_SUCCESS) goto cleanup; + + /* Expand environment variables, if appropriate, or copy the original string over. */ + if (dwValueType == REG_EXPAND_SZ) + { + cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR); + if (!cbData) goto cleanup; + pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); + if (!pwszExpandedBuffer) + { + result = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData); + } + else + { + pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); + memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData); + } + + /* If the value references a resource based string, parse the value and load the string. + * Else just copy over the original value. */ + result = ERROR_SUCCESS; + if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */ + { + lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR)); + } + else + { + WCHAR* pComma = wcsrchr(pwszExpandedBuffer, L','); + UINT uiStringId; + HMODULE hModule; + + /* Format of the expanded value is 'path_to_dll,-resId' */ + if (!pComma || pComma[1] != L'-') + { + result = ERROR_BADKEY; + goto cleanup; + } + + uiStringId = _wtoi(pComma + 2); + *pComma = L'\0'; + + hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE); + if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR))) + result = ERROR_BADKEY; + FreeLibrary(hModule); + } + +cleanup: + HeapFree(GetProcessHeap(), 0, pwszTempBuffer); + HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer); + return result; +} + +/************************************************************************ + * RegLoadMUIStringA + * + * @implemented + */ +LONG WINAPI +RegLoadMUIStringA( + IN HKEY hKey, + IN LPCSTR pszValue OPTIONAL, + OUT LPSTR pszOutBuf, + IN DWORD cbOutBuf, + OUT LPDWORD pcbData OPTIONAL, + IN DWORD Flags, + IN LPCSTR pszDirectory OPTIONAL) +{ + UNICODE_STRING valueW, baseDirW; + WCHAR* pwszBuffer; + DWORD cbData = cbOutBuf * sizeof(WCHAR); + LONG result; + + valueW.Buffer = baseDirW.Buffer = pwszBuffer = NULL; + if (!RtlCreateUnicodeStringFromAsciiz(&valueW, pszValue) || + !RtlCreateUnicodeStringFromAsciiz(&baseDirW, pszDirectory) || + !(pwszBuffer = HeapAlloc(GetProcessHeap(), 0, cbData))) + { + result = ERROR_NOT_ENOUGH_MEMORY; + goto cleanup; + } + + result = RegLoadMUIStringW(hKey, valueW.Buffer, pwszBuffer, cbData, NULL, Flags, + baseDirW.Buffer); + + if (result == ERROR_SUCCESS) + { + cbData = WideCharToMultiByte(CP_ACP, 0, pwszBuffer, -1, pszOutBuf, cbOutBuf, NULL, NULL); + if (pcbData) + *pcbData = cbData; + } + +cleanup: + HeapFree(GetProcessHeap(), 0, pwszBuffer); + RtlFreeUnicodeString(&baseDirW); + RtlFreeUnicodeString(&valueW); + + return result; +} + /* EOF */ diff --git a/dll/win32/advapi32_vista/CMakeLists.txt b/dll/win32/advapi32_vista/CMakeLists.txt index add67945a36..3af7909efb7 100644 --- a/dll/win32/advapi32_vista/CMakeLists.txt +++ b/dll/win32/advapi32_vista/CMakeLists.txt @@ -13,7 +13,6 @@ include_directories( list(APPEND SOURCE DllMain.c ../advapi32/reg/reg.c - RegLoadMUIString.c ${CMAKE_CURRENT_BINARY_DIR}/advapi32_vista.def) add_library(advapi32_vista MODULE ${SOURCE}) diff --git a/dll/win32/advapi32_vista/RegLoadMUIString.c b/dll/win32/advapi32_vista/RegLoadMUIString.c deleted file mode 100644 index 8d80949660c..00000000000 --- a/dll/win32/advapi32_vista/RegLoadMUIString.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "advapi32_vista.h" - -#include -#include -#include - -WINE_DEFAULT_DEBUG_CHANNEL(reg); - -/****************************************************************************** - * load_string [Internal] - * - * This is basically a copy of user32/resource.c's LoadStringW. Necessary to - * avoid importing user32, which is higher level than advapi32. Helper for - * RegLoadMUIString. - */ -static int load_string(HINSTANCE hModule, UINT resId, LPWSTR pwszBuffer, INT cMaxChars) -{ - HGLOBAL hMemory; - HRSRC hResource; - WCHAR *pString; - int idxString; - - /* Negative values have to be inverted. */ - if (HIWORD(resId) == 0xffff) - resId = (UINT)(-((INT)resId)); - - /* Load the resource into memory and get a pointer to it. */ - hResource = FindResourceW(hModule, MAKEINTRESOURCEW(LOWORD(resId >> 4) + 1), (LPWSTR)RT_STRING); - if (!hResource) return 0; - hMemory = LoadResource(hModule, hResource); - if (!hMemory) return 0; - pString = LockResource(hMemory); - - /* Strings are length-prefixed. Lowest nibble of resId is an index. */ - idxString = resId & 0xf; - while (idxString--) pString += *pString + 1; - - /* If no buffer is given, return length of the string. */ - if (!pwszBuffer) return *pString; - - /* Else copy over the string, respecting the buffer size. */ - cMaxChars = (*pString < cMaxChars) ? *pString : (cMaxChars - 1); - if (cMaxChars >= 0) - { - memcpy(pwszBuffer, pString+1, cMaxChars * sizeof(WCHAR)); - pwszBuffer[cMaxChars] = L'\0'; - } - - return cMaxChars; -} - -/************************************************************************ - * RegLoadMUIStringW - * - * @implemented - */ -LONG WINAPI -RegLoadMUIStringW(IN HKEY hKey, - IN LPCWSTR pszValue OPTIONAL, - OUT LPWSTR pszOutBuf, - IN DWORD cbOutBuf, - OUT LPDWORD pcbData OPTIONAL, - IN DWORD Flags, - IN LPCWSTR pszDirectory OPTIONAL) -{ - DWORD dwValueType, cbData; - LPWSTR pwszTempBuffer = NULL, pwszExpandedBuffer = NULL; - LONG result; - - /* Parameter sanity checks. */ - if (!hKey || !pszOutBuf) - return ERROR_INVALID_PARAMETER; - - if (pszDirectory && *pszDirectory) - { - FIXME("BaseDir parameter not yet supported!\n"); - return ERROR_INVALID_PARAMETER; - } - - /* Check for value existence and correctness of it's type, allocate a buffer and load it. */ - result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, NULL, &cbData); - if (result != ERROR_SUCCESS) goto cleanup; - if (!(dwValueType == REG_SZ || dwValueType == REG_EXPAND_SZ) || !cbData) - { - result = ERROR_FILE_NOT_FOUND; - goto cleanup; - } - pwszTempBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); - if (!pwszTempBuffer) - { - result = ERROR_NOT_ENOUGH_MEMORY; - goto cleanup; - } - result = RegQueryValueExW(hKey, pszValue, NULL, &dwValueType, (LPBYTE)pwszTempBuffer, &cbData); - if (result != ERROR_SUCCESS) goto cleanup; - - /* Expand environment variables, if appropriate, or copy the original string over. */ - if (dwValueType == REG_EXPAND_SZ) - { - cbData = ExpandEnvironmentStringsW(pwszTempBuffer, NULL, 0) * sizeof(WCHAR); - if (!cbData) goto cleanup; - pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); - if (!pwszExpandedBuffer) - { - result = ERROR_NOT_ENOUGH_MEMORY; - goto cleanup; - } - ExpandEnvironmentStringsW(pwszTempBuffer, pwszExpandedBuffer, cbData); - } - else - { - pwszExpandedBuffer = HeapAlloc(GetProcessHeap(), 0, cbData); - memcpy(pwszExpandedBuffer, pwszTempBuffer, cbData); - } - - /* If the value references a resource based string, parse the value and load the string. - * Else just copy over the original value. */ - result = ERROR_SUCCESS; - if (*pwszExpandedBuffer != L'@') /* '@' is the prefix for resource based string entries. */ - { - lstrcpynW(pszOutBuf, pwszExpandedBuffer, cbOutBuf / sizeof(WCHAR)); - } - else - { - WCHAR *pComma = wcsrchr(pwszExpandedBuffer, L','); - UINT uiStringId; - HMODULE hModule; - - /* Format of the expanded value is 'path_to_dll,-resId' */ - if (!pComma || pComma[1] != L'-') - { - result = ERROR_BADKEY; - goto cleanup; - } - - uiStringId = _wtoi(pComma+2); - *pComma = L'\0'; - - hModule = LoadLibraryExW(pwszExpandedBuffer + 1, NULL, LOAD_LIBRARY_AS_DATAFILE); - if (!hModule || !load_string(hModule, uiStringId, pszOutBuf, cbOutBuf / sizeof(WCHAR))) - result = ERROR_BADKEY; - FreeLibrary(hModule); - } - -cleanup: - HeapFree(GetProcessHeap(), 0, pwszTempBuffer); - HeapFree(GetProcessHeap(), 0, pwszExpandedBuffer); - return result; -} - -/************************************************************************ - * RegLoadMUIStringA - * - * @implemented - */ -LONG WINAPI -RegLoadMUIStringA(IN HKEY hKey, - IN LPCSTR pszValue OPTIONAL, - OUT LPSTR pszOutBuf, - IN DWORD cbOutBuf, - OUT LPDWORD pcbData OPTIONAL, - IN DWORD Flags, - IN LPCSTR pszDirectory OPTIONAL) -{ - UNICODE_STRING valueW, baseDirW; - WCHAR *pwszBuffer; - DWORD cbData = cbOutBuf * sizeof(WCHAR); - LONG result; - - valueW.Buffer = baseDirW.Buffer = pwszBuffer = NULL; - if (!RtlCreateUnicodeStringFromAsciiz(&valueW, pszValue) || - !RtlCreateUnicodeStringFromAsciiz(&baseDirW, pszDirectory) || - !(pwszBuffer = HeapAlloc(GetProcessHeap(), 0, cbData))) - { - result = ERROR_NOT_ENOUGH_MEMORY; - goto cleanup; - } - - result = RegLoadMUIStringW(hKey, valueW.Buffer, pwszBuffer, cbData, NULL, Flags, - baseDirW.Buffer); - - if (result == ERROR_SUCCESS) - { - cbData = WideCharToMultiByte(CP_ACP, 0, pwszBuffer, -1, pszOutBuf, cbOutBuf, NULL, NULL); - if (pcbData) - *pcbData = cbData; - } - -cleanup: - HeapFree(GetProcessHeap(), 0, pwszBuffer); - RtlFreeUnicodeString(&baseDirW); - RtlFreeUnicodeString(&valueW); - - return result; -}