mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[ADVAPI32_VISTA] Move RegLoadMUIStringW to reg.c
This commit is contained in:
parent
d69ff10113
commit
ad3c102e65
3 changed files with 190 additions and 196 deletions
|
@ -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 */
|
||||
|
|
|
@ -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})
|
||||
|
|
|
@ -1,195 +0,0 @@
|
|||
#include "advapi32_vista.h"
|
||||
|
||||
#include <winuser.h>
|
||||
#include <wine/debug.h>
|
||||
#include <wine/unicode.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in a new issue