mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
[ADVAPI32] Unify source for vista registry functions
- In advapi32_vista compile the code from advapi32/reg/reg.c - Export RegCopyTreeW from advapi32_vista
This commit is contained in:
parent
d28bbf458a
commit
eef22cc036
6 changed files with 219 additions and 328 deletions
|
@ -322,6 +322,7 @@ OpenCurrentConfigKey (PHANDLE KeyHandle)
|
||||||
&Attributes);
|
&Attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegDisablePredefinedCache
|
* RegDisablePredefinedCache
|
||||||
|
@ -444,6 +445,7 @@ RegCloseKey(HKEY hKey)
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // _ADVAPI32_VISTA_
|
||||||
|
|
||||||
static NTSTATUS
|
static NTSTATUS
|
||||||
RegpCopyTree(IN HKEY hKeySrc,
|
RegpCopyTree(IN HKEY hKeySrc,
|
||||||
|
@ -803,6 +805,7 @@ Cleanup2:
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegCopyTreeA
|
* RegCopyTreeA
|
||||||
|
@ -1734,6 +1737,7 @@ Cleanup:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegDeleteTreeW
|
* RegDeleteTreeW
|
||||||
|
@ -1856,6 +1860,7 @@ RegDeleteTreeA(IN HKEY hKey,
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegDisableReflectionKey
|
* RegDisableReflectionKey
|
||||||
|
@ -2161,6 +2166,7 @@ RegGetValueA(HKEY hKey,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegSetKeyValueW
|
* RegSetKeyValueW
|
||||||
|
@ -2231,6 +2237,7 @@ Cleanup:
|
||||||
return Ret;
|
return Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef _ADVAPI32_VISTA_
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* RegSetKeyValueA
|
* RegSetKeyValueA
|
||||||
|
@ -5136,4 +5143,196 @@ RegUnLoadKeyW(HKEY hKey,
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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 */
|
/* EOF */
|
||||||
|
|
|
@ -2,19 +2,22 @@
|
||||||
remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
|
remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502)
|
||||||
add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
|
add_definitions(-D_WIN32_WINNT=0x600 -DWINVER=0x600)
|
||||||
|
|
||||||
add_definitions(-D_ADVAPI32_)
|
add_definitions(-D_ADVAPI32_ -D_ADVAPI32_VISTA_)
|
||||||
spec2def(advapi32_vista.dll advapi32_vista.spec ADD_IMPORTLIB)
|
spec2def(advapi32_vista.dll advapi32_vista.spec ADD_IMPORTLIB)
|
||||||
|
|
||||||
|
include_directories(
|
||||||
|
../advapi32
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/../advapi32
|
||||||
|
)
|
||||||
|
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
DllMain.c
|
DllMain.c
|
||||||
RegDeleteTree.c
|
../advapi32/reg/reg.c
|
||||||
RegSetKeyValue.c
|
|
||||||
RegLoadMUIString.c
|
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/advapi32_vista.def)
|
${CMAKE_CURRENT_BINARY_DIR}/advapi32_vista.def)
|
||||||
|
|
||||||
add_library(advapi32_vista MODULE ${SOURCE})
|
add_library(advapi32_vista MODULE ${SOURCE})
|
||||||
set_module_type(advapi32_vista win32dll ENTRYPOINT DllMain 12)
|
set_module_type(advapi32_vista win32dll ENTRYPOINT DllMain 12)
|
||||||
target_link_libraries(advapi32_vista wine)
|
target_link_libraries(advapi32_vista wine ${PSEH_LIB})
|
||||||
add_importlibs(advapi32_vista advapi32 kernel32 ntdll)
|
add_importlibs(advapi32_vista advapi32 kernel32 ntdll)
|
||||||
add_dependencies(advapi32_vista psdk)
|
add_dependencies(advapi32_vista psdk advapi32)
|
||||||
add_cd_file(TARGET advapi32_vista DESTINATION reactos/system32 FOR all)
|
add_cd_file(TARGET advapi32_vista DESTINATION reactos/system32 FOR all)
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
#include "advapi32_vista.h"
|
#include "advapi32_vista.h"
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
RegInitialize(VOID);
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
DllMain(HANDLE hDll,
|
DllMain(HANDLE hDll,
|
||||||
|
@ -9,6 +12,14 @@ DllMain(HANDLE hDll,
|
||||||
{
|
{
|
||||||
/* For now, there isn't much to do */
|
/* For now, there isn't much to do */
|
||||||
if (dwReason == DLL_PROCESS_ATTACH)
|
if (dwReason == DLL_PROCESS_ATTACH)
|
||||||
|
{
|
||||||
DisableThreadLibraryCalls(hDll);
|
DisableThreadLibraryCalls(hDll);
|
||||||
|
|
||||||
|
if (!RegInitialize())
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,102 +0,0 @@
|
||||||
|
|
||||||
#include "advapi32_vista.h"
|
|
||||||
|
|
||||||
/* heap allocation helpers */
|
|
||||||
static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1);
|
|
||||||
static inline void *heap_alloc( size_t len )
|
|
||||||
{
|
|
||||||
return HeapAlloc( GetProcessHeap(), 0, len );
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline BOOL heap_free( void *mem )
|
|
||||||
{
|
|
||||||
return HeapFree( GetProcessHeap(), 0, mem );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Taken from Wine advapi32/registry.c */
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* RegDeleteTreeW [ADVAPI32.@]
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
LSTATUS WINAPI RegDeleteTreeW(HKEY hKey, LPCWSTR lpszSubKey)
|
|
||||||
{
|
|
||||||
LONG ret;
|
|
||||||
DWORD dwMaxSubkeyLen, dwMaxValueLen;
|
|
||||||
DWORD dwMaxLen, dwSize;
|
|
||||||
WCHAR szNameBuf[MAX_PATH], *lpszName = szNameBuf;
|
|
||||||
HKEY hSubKey = hKey;
|
|
||||||
|
|
||||||
if(lpszSubKey)
|
|
||||||
{
|
|
||||||
ret = RegOpenKeyExW(hKey, lpszSubKey, 0, KEY_READ, &hSubKey);
|
|
||||||
if (ret) return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get highest length for keys, values */
|
|
||||||
ret = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL,
|
|
||||||
&dwMaxSubkeyLen, NULL, NULL, &dwMaxValueLen, NULL, NULL, NULL);
|
|
||||||
if (ret) goto cleanup;
|
|
||||||
|
|
||||||
dwMaxSubkeyLen++;
|
|
||||||
dwMaxValueLen++;
|
|
||||||
dwMaxLen = max(dwMaxSubkeyLen, dwMaxValueLen);
|
|
||||||
if (dwMaxLen > sizeof(szNameBuf)/sizeof(WCHAR))
|
|
||||||
{
|
|
||||||
/* Name too big: alloc a buffer for it */
|
|
||||||
if (!(lpszName = heap_alloc( dwMaxLen*sizeof(WCHAR))))
|
|
||||||
{
|
|
||||||
ret = ERROR_NOT_ENOUGH_MEMORY;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Recursively delete all the subkeys */
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
dwSize = dwMaxLen;
|
|
||||||
if (RegEnumKeyExW(hSubKey, 0, lpszName, &dwSize, NULL,
|
|
||||||
NULL, NULL, NULL)) break;
|
|
||||||
|
|
||||||
ret = RegDeleteTreeW(hSubKey, lpszName);
|
|
||||||
if (ret) goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lpszSubKey)
|
|
||||||
ret = RegDeleteKeyW(hKey, lpszSubKey);
|
|
||||||
else
|
|
||||||
while (TRUE)
|
|
||||||
{
|
|
||||||
dwSize = dwMaxLen;
|
|
||||||
if (RegEnumValueW(hKey, 0, lpszName, &dwSize,
|
|
||||||
NULL, NULL, NULL, NULL)) break;
|
|
||||||
|
|
||||||
ret = RegDeleteValueW(hKey, lpszName);
|
|
||||||
if (ret) goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
/* Free buffer if allocated */
|
|
||||||
if (lpszName != szNameBuf)
|
|
||||||
heap_free( lpszName);
|
|
||||||
if(lpszSubKey)
|
|
||||||
RegCloseKey(hSubKey);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* RegDeleteTreeA [ADVAPI32.@]
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
LSTATUS WINAPI RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
|
||||||
{
|
|
||||||
LONG ret;
|
|
||||||
UNICODE_STRING lpszSubKeyW;
|
|
||||||
|
|
||||||
if (lpszSubKey) RtlCreateUnicodeStringFromAsciiz( &lpszSubKeyW, lpszSubKey);
|
|
||||||
else lpszSubKeyW.Buffer = NULL;
|
|
||||||
ret = RegDeleteTreeW( hKey, lpszSubKeyW.Buffer);
|
|
||||||
RtlFreeUnicodeString( &lpszSubKeyW );
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
|
|
||||||
#include "advapi32_vista.h"
|
|
||||||
|
|
||||||
/* Taken from Wine advapi32/registry.c */
|
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* RegSetKeyValueW [ADVAPI32.@]
|
|
||||||
*/
|
|
||||||
LONG WINAPI RegSetKeyValueW( HKEY hkey, LPCWSTR subkey, LPCWSTR name, DWORD type, const void *data, DWORD len )
|
|
||||||
{
|
|
||||||
HKEY hsubkey = NULL;
|
|
||||||
DWORD ret;
|
|
||||||
|
|
||||||
//TRACE("(%p,%s,%s,%d,%p,%d)\n", hkey, debugstr_w(subkey), debugstr_w(name), type, data, len );
|
|
||||||
|
|
||||||
if (subkey && subkey[0]) /* need to create the subkey */
|
|
||||||
{
|
|
||||||
if ((ret = RegCreateKeyW( hkey, subkey, &hsubkey )) != ERROR_SUCCESS) return ret;
|
|
||||||
hkey = hsubkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = RegSetValueExW( hkey, name, 0, type, (const BYTE*)data, len );
|
|
||||||
if (hsubkey) RegCloseKey( hsubkey );
|
|
||||||
return ret;
|
|
||||||
}
|
|
Loading…
Reference in a new issue