From 9dbbd6df9424ab5ec00b1ace624c07295e63a828 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Thu, 5 Oct 2023 09:54:53 +0300 Subject: [PATCH] [ADVAPI32][USERENV][SERVICES] Unify source for vista registry functions - In advapi32_vista compile the code from advapi32/reg/reg.c - Export RegCopyTreeW from advapi32_vista - Remove duplicated code / hacks from advap32_vista, userenv and services --- base/system/services/CMakeLists.txt | 2 +- base/system/services/controlset.c | 343 +------------------ dll/win32/advapi32/reg/reg.c | 197 +++++++++++ dll/win32/advapi32_vista/CMakeLists.txt | 16 +- dll/win32/advapi32_vista/DllMain.c | 11 + dll/win32/advapi32_vista/RegDeleteTree.c | 102 ------ dll/win32/advapi32_vista/RegLoadMUIString.c | 195 ----------- dll/win32/advapi32_vista/RegSetKeyValue.c | 25 -- dll/win32/advapi32_vista/advapi32_vista.spec | 1 + dll/win32/userenv/CMakeLists.txt | 2 +- dll/win32/userenv/registry.c | 226 +----------- 11 files changed, 226 insertions(+), 894 deletions(-) delete mode 100644 dll/win32/advapi32_vista/RegDeleteTree.c delete mode 100644 dll/win32/advapi32_vista/RegLoadMUIString.c delete mode 100644 dll/win32/advapi32_vista/RegSetKeyValue.c diff --git a/base/system/services/CMakeLists.txt b/base/system/services/CMakeLists.txt index ba38f656da2c3..7961dd54ce10b 100644 --- a/base/system/services/CMakeLists.txt +++ b/base/system/services/CMakeLists.txt @@ -23,6 +23,6 @@ add_executable(services ${SOURCE} services.rc) target_link_libraries(services ${PSEH_LIB}) set_module_type(services win32gui UNICODE) -add_importlibs(services userenv user32 advapi32 rpcrt4 msvcrt kernel32 ntdll) +add_importlibs(services userenv user32 advapi32 advapi32_vista rpcrt4 msvcrt kernel32 ntdll) add_pch(services services.h SOURCE) add_cd_file(TARGET services DESTINATION reactos/system32 FOR all) diff --git a/base/system/services/controlset.c b/base/system/services/controlset.c index b387ffd335ced..e9fdc967e12a4 100644 --- a/base/system/services/controlset.c +++ b/base/system/services/controlset.c @@ -14,6 +14,8 @@ #define NDEBUG #include +LSTATUS WINAPI RegCopyTreeW(_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY); +LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR); /* GLOBALS *******************************************************************/ @@ -22,337 +24,6 @@ static BOOL bBootAccepted = FALSE; /* FUNCTIONS *****************************************************************/ -#if (_WIN32_WINNT < 0x0600) -static -DWORD -ScmCopyTree( - HKEY hSrcKey, - HKEY hDstKey) -{ - DWORD dwSubKeys; - DWORD dwValues; - DWORD dwType; - DWORD dwMaxSubKeyNameLength; - DWORD dwSubKeyNameLength; - DWORD dwMaxValueNameLength; - DWORD dwValueNameLength; - DWORD dwMaxValueLength; - DWORD dwValueLength; - DWORD dwDisposition; - DWORD i; - LPWSTR lpNameBuffer; - LPBYTE lpDataBuffer; - HKEY hDstSubKey; - HKEY hSrcSubKey; - DWORD dwError; - - DPRINT("ScmCopyTree()\n"); - - dwError = RegQueryInfoKey(hSrcKey, - NULL, - NULL, - NULL, - &dwSubKeys, - &dwMaxSubKeyNameLength, - NULL, - &dwValues, - &dwMaxValueNameLength, - &dwMaxValueLength, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("RegQueryInfoKey() failed (Error %lu)\n", dwError); - return dwError; - } - - dwMaxSubKeyNameLength++; - dwMaxValueNameLength++; - - DPRINT("dwSubKeys %lu\n", dwSubKeys); - DPRINT("dwMaxSubKeyNameLength %lu\n", dwMaxSubKeyNameLength); - DPRINT("dwValues %lu\n", dwValues); - DPRINT("dwMaxValueNameLength %lu\n", dwMaxValueNameLength); - DPRINT("dwMaxValueLength %lu\n", dwMaxValueLength); - - /* Copy subkeys */ - if (dwSubKeys != 0) - { - lpNameBuffer = HeapAlloc(GetProcessHeap(), - 0, - dwMaxSubKeyNameLength * sizeof(WCHAR)); - if (lpNameBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - for (i = 0; i < dwSubKeys; i++) - { - dwSubKeyNameLength = dwMaxSubKeyNameLength; - dwError = RegEnumKeyExW(hSrcKey, - i, - lpNameBuffer, - &dwSubKeyNameLength, - NULL, - NULL, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Subkey enumeration failed (Error %lu)\n", dwError); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - - dwError = RegCreateKeyExW(hDstKey, - lpNameBuffer, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_WRITE, - NULL, - &hDstSubKey, - &dwDisposition); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Subkey creation failed (Error %lu)\n", dwError); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - - dwError = RegOpenKeyExW(hSrcKey, - lpNameBuffer, - 0, - KEY_READ, - &hSrcSubKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", dwError); - RegCloseKey(hDstSubKey); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - - dwError = ScmCopyTree(hSrcSubKey, - hDstSubKey); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", dwError); - RegCloseKey (hSrcSubKey); - RegCloseKey (hDstSubKey); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - - RegCloseKey(hSrcSubKey); - RegCloseKey(hDstSubKey); - } - - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - } - - /* Copy values */ - if (dwValues != 0) - { - lpNameBuffer = HeapAlloc(GetProcessHeap(), - 0, - dwMaxValueNameLength * sizeof(WCHAR)); - if (lpNameBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - return ERROR_NOT_ENOUGH_MEMORY; - } - - /* RegSetValueExW tries to read behind the maximum length, so give it space for that */ - lpDataBuffer = HeapAlloc(GetProcessHeap(), - HEAP_ZERO_MEMORY, - dwMaxValueLength + sizeof(WCHAR)); - if (lpDataBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return ERROR_NOT_ENOUGH_MEMORY; - } - - for (i = 0; i < dwValues; i++) - { - dwValueNameLength = dwMaxValueNameLength; - dwValueLength = dwMaxValueLength; - dwError = RegEnumValueW(hSrcKey, - i, - lpNameBuffer, - &dwValueNameLength, - NULL, - &dwType, - lpDataBuffer, - &dwValueLength); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", dwError); - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - - dwError = RegSetValueExW(hDstKey, - lpNameBuffer, - 0, - dwType, - lpDataBuffer, - dwValueLength); - if (dwError != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", dwError); - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return dwError; - } - } - - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - } - - DPRINT("ScmCopyTree() done\n"); - - return ERROR_SUCCESS; -} - - -DWORD -ScmDeleteTree( - HKEY hKey, - PCWSTR pszSubKey) -{ - DWORD dwMaxSubkeyLength, dwMaxValueLength; - DWORD dwMaxLength, dwSize; - PWSTR pszName = NULL; - HKEY hSubKey = NULL; - DWORD dwError; - - if (pszSubKey != NULL) - { - dwError = RegOpenKeyExW(hKey, pszSubKey, 0, KEY_READ, &hSubKey); - if (dwError != ERROR_SUCCESS) - return dwError; - } - else - { - hSubKey = hKey; - } - - /* Get highest length for keys, values */ - dwError = RegQueryInfoKeyW(hSubKey, - NULL, - NULL, - NULL, - NULL, - &dwMaxSubkeyLength, - NULL, - NULL, - &dwMaxValueLength, - NULL, - NULL, - NULL); - if (dwError != ERROR_SUCCESS) - goto done; - - dwMaxSubkeyLength++; - dwMaxValueLength++; - dwMaxLength = max(dwMaxSubkeyLength, dwMaxValueLength); - - /* Allocate a buffer for key and value names */ - pszName = HeapAlloc(GetProcessHeap(), - 0, - dwMaxLength * sizeof(WCHAR)); - if (pszName == NULL) - { - dwError = ERROR_NOT_ENOUGH_MEMORY; - goto done; - } - - /* Recursively delete all the subkeys */ - while (TRUE) - { - dwSize = dwMaxLength; - if (RegEnumKeyExW(hSubKey, - 0, - pszName, - &dwSize, - NULL, - NULL, - NULL, - NULL)) - break; - - dwError = ScmDeleteTree(hSubKey, pszName); - if (dwError != ERROR_SUCCESS) - goto done; - } - - if (pszSubKey != NULL) - { - dwError = RegDeleteKeyW(hKey, pszSubKey); - } - else - { - while (TRUE) - { - dwSize = dwMaxLength; - if (RegEnumValueW(hKey, - 0, - pszName, - &dwSize, - NULL, - NULL, - NULL, - NULL)) - break; - - dwError = RegDeleteValueW(hKey, pszName); - if (dwError != ERROR_SUCCESS) - goto done; - } - } - -done: - if (pszName != NULL) - HeapFree(GetProcessHeap(), 0, pszName); - - if (pszSubKey != NULL) - RegCloseKey(hSubKey); - - return dwError; -} -#endif - - static DWORD ScmGetControlSetValues( @@ -546,14 +217,9 @@ ScmCopyControlSet( goto done; /* Copy the source control set to the destination control set */ -#if (_WIN32_WINNT >= 0x0600) dwError = RegCopyTreeW(hSourceControlSetKey, NULL, hDestinationControlSetKey); -#else - dwError = ScmCopyTree(hSourceControlSetKey, - hDestinationControlSetKey); -#endif if (dwError != ERROR_SUCCESS) goto done; @@ -595,13 +261,8 @@ ScmDeleteControlSet( return dwError; /* Delete the control set */ -#if (_WIN32_WINNT >= 0x0600) dwError = RegDeleteTreeW(hControlSetKey, NULL); -#else - dwError = ScmDeleteTree(hControlSetKey, - NULL); -#endif /* Open the system key */ RegCloseKey(hControlSetKey); diff --git a/dll/win32/advapi32/reg/reg.c b/dll/win32/advapi32/reg/reg.c index e14f29c3648b9..d9e77aa2c6c86 100644 --- a/dll/win32/advapi32/reg/reg.c +++ b/dll/win32/advapi32/reg/reg.c @@ -322,6 +322,7 @@ OpenCurrentConfigKey (PHANDLE KeyHandle) &Attributes); } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegDisablePredefinedCache @@ -444,6 +445,7 @@ RegCloseKey(HKEY hKey) return ERROR_SUCCESS; } +#endif // _ADVAPI32_VISTA_ static NTSTATUS RegpCopyTree(IN HKEY hKeySrc, @@ -803,6 +805,7 @@ RegCopyTreeW(IN HKEY hKeySrc, return ERROR_SUCCESS; } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegCopyTreeA @@ -1734,6 +1737,7 @@ RegDeleteTreeW(IN HKEY hKey, } #endif +#endif // _ADVAPI32_VISTA_ /************************************************************************ * RegDeleteTreeW @@ -1856,6 +1860,7 @@ RegDeleteTreeA(IN HKEY hKey, return Ret; } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegDisableReflectionKey @@ -2161,6 +2166,7 @@ RegGetValueA(HKEY hKey, return ret; } +#endif // _ADVAPI32_VISTA_ /************************************************************************ * RegSetKeyValueW @@ -2231,6 +2237,7 @@ RegSetKeyValueW(IN HKEY hKey, return Ret; } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegSetKeyValueA @@ -5131,4 +5138,194 @@ RegUnLoadKeyW(HKEY hKey, 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 */ diff --git a/dll/win32/advapi32_vista/CMakeLists.txt b/dll/win32/advapi32_vista/CMakeLists.txt index ab6e406876a5c..d89c9c4a1e22d 100644 --- a/dll/win32/advapi32_vista/CMakeLists.txt +++ b/dll/win32/advapi32_vista/CMakeLists.txt @@ -2,19 +2,25 @@ remove_definitions(-D_WIN32_WINNT=0x502 -DWINVER=0x502) 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) +include_directories( + ../advapi32 + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/idl + ${REACTOS_SOURCE_DIR}/sdk/include/reactos/drivers/ksecdd + ${REACTOS_SOURCE_DIR}/sdk/lib/cryptlib + ${CMAKE_CURRENT_BINARY_DIR}/../advapi32 +) + list(APPEND SOURCE DllMain.c - RegDeleteTree.c - RegSetKeyValue.c - RegLoadMUIString.c + ../advapi32/reg/reg.c ${CMAKE_CURRENT_BINARY_DIR}/advapi32_vista.def) add_library(advapi32_vista MODULE ${SOURCE}) 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_dependencies(advapi32_vista psdk) add_cd_file(TARGET advapi32_vista DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/advapi32_vista/DllMain.c b/dll/win32/advapi32_vista/DllMain.c index 0902d8455d7f3..6ed5bb68a6759 100644 --- a/dll/win32/advapi32_vista/DllMain.c +++ b/dll/win32/advapi32_vista/DllMain.c @@ -1,6 +1,9 @@ #include "advapi32_vista.h" +BOOL +RegInitialize(VOID); + BOOL WINAPI DllMain(HANDLE hDll, @@ -9,6 +12,14 @@ DllMain(HANDLE hDll, { /* For now, there isn't much to do */ if (dwReason == DLL_PROCESS_ATTACH) + { DisableThreadLibraryCalls(hDll); + + if (!RegInitialize()) + { + return FALSE; + } + } + return TRUE; } diff --git a/dll/win32/advapi32_vista/RegDeleteTree.c b/dll/win32/advapi32_vista/RegDeleteTree.c deleted file mode 100644 index 0a9f6192fb764..0000000000000 --- a/dll/win32/advapi32_vista/RegDeleteTree.c +++ /dev/null @@ -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; -} diff --git a/dll/win32/advapi32_vista/RegLoadMUIString.c b/dll/win32/advapi32_vista/RegLoadMUIString.c deleted file mode 100644 index 8d80949660cf8..0000000000000 --- 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; -} diff --git a/dll/win32/advapi32_vista/RegSetKeyValue.c b/dll/win32/advapi32_vista/RegSetKeyValue.c deleted file mode 100644 index 8701eb87df428..0000000000000 --- a/dll/win32/advapi32_vista/RegSetKeyValue.c +++ /dev/null @@ -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; -} diff --git a/dll/win32/advapi32_vista/advapi32_vista.spec b/dll/win32/advapi32_vista/advapi32_vista.spec index 969207292f622..9ca098974812f 100644 --- a/dll/win32/advapi32_vista/advapi32_vista.spec +++ b/dll/win32/advapi32_vista/advapi32_vista.spec @@ -1,4 +1,5 @@ +@ stdcall RegCopyTreeW(ptr wstr ptr) @ stdcall RegDeleteTreeA(long str) @ stdcall RegDeleteTreeW(long wstr) @ stdcall RegSetKeyValueW(long wstr wstr long ptr long) diff --git a/dll/win32/userenv/CMakeLists.txt b/dll/win32/userenv/CMakeLists.txt index 28b272697b58f..8e372f16001ee 100644 --- a/dll/win32/userenv/CMakeLists.txt +++ b/dll/win32/userenv/CMakeLists.txt @@ -24,6 +24,6 @@ add_library(userenv MODULE set_module_type(userenv win32dll) target_link_libraries(userenv uuid) -add_importlibs(userenv advapi32 user32 msvcrt kernel32 ntdll) +add_importlibs(userenv advapi32 advapi32_vista user32 msvcrt kernel32 ntdll) add_pch(userenv precomp.h "${PCH_SKIP_SOURCE}") add_cd_file(TARGET userenv DESTINATION reactos/system32 FOR all) diff --git a/dll/win32/userenv/registry.c b/dll/win32/userenv/registry.c index a7fc4fee49cd5..326832a1164e7 100644 --- a/dll/win32/userenv/registry.c +++ b/dll/win32/userenv/registry.c @@ -29,6 +29,8 @@ #define NDEBUG #include +LSTATUS WINAPI RegCopyTreeW(_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY); + /* FUNCTIONS ***************************************************************/ static @@ -38,7 +40,6 @@ CopyKey(HKEY hDstKey, { LONG Error; -#if (_WIN32_WINNT >= 0x0600) Error = RegCopyTreeW(hSrcKey, NULL, hDstKey); @@ -49,229 +50,6 @@ CopyKey(HKEY hDstKey, } return TRUE; - -#else - FILETIME LastWrite; - DWORD dwSubKeys; - DWORD dwValues; - DWORD dwType; - DWORD dwMaxSubKeyNameLength; - DWORD dwSubKeyNameLength; - DWORD dwMaxValueNameLength; - DWORD dwValueNameLength; - DWORD dwMaxValueLength; - DWORD dwValueLength; - DWORD dwDisposition; - DWORD i; - LPWSTR lpNameBuffer; - LPBYTE lpDataBuffer; - HKEY hDstSubKey; - HKEY hSrcSubKey; - - DPRINT ("CopyKey() called\n"); - - Error = RegQueryInfoKey(hSrcKey, - NULL, - NULL, - NULL, - &dwSubKeys, - &dwMaxSubKeyNameLength, - NULL, - &dwValues, - &dwMaxValueNameLength, - &dwMaxValueLength, - NULL, - NULL); - if (Error != ERROR_SUCCESS) - { - DPRINT1("RegQueryInfoKey() failed (Error %lu)\n", Error); - SetLastError((DWORD)Error); - return FALSE; - } - - dwMaxSubKeyNameLength++; - dwMaxValueNameLength++; - - DPRINT("dwSubKeys %lu\n", dwSubKeys); - DPRINT("dwMaxSubKeyNameLength %lu\n", dwMaxSubKeyNameLength); - DPRINT("dwValues %lu\n", dwValues); - DPRINT("dwMaxValueNameLength %lu\n", dwMaxValueNameLength); - DPRINT("dwMaxValueLength %lu\n", dwMaxValueLength); - - /* Copy subkeys */ - if (dwSubKeys != 0) - { - lpNameBuffer = HeapAlloc(GetProcessHeap(), - 0, - dwMaxSubKeyNameLength * sizeof(WCHAR)); - if (lpNameBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - for (i = 0; i < dwSubKeys; i++) - { - dwSubKeyNameLength = dwMaxSubKeyNameLength; - Error = RegEnumKeyExW(hSrcKey, - i, - lpNameBuffer, - &dwSubKeyNameLength, - NULL, - NULL, - NULL, - &LastWrite); - if (Error != ERROR_SUCCESS) - { - DPRINT1("Subkey enumeration failed (Error %lu)\n", Error); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError((DWORD)Error); - return FALSE; - } - - Error = RegCreateKeyExW(hDstKey, - lpNameBuffer, - 0, - NULL, - REG_OPTION_NON_VOLATILE, - KEY_WRITE, - NULL, - &hDstSubKey, - &dwDisposition); - if (Error != ERROR_SUCCESS) - { - DPRINT1("Subkey creation failed (Error %lu)\n", Error); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError((DWORD)Error); - return FALSE; - } - - Error = RegOpenKeyExW(hSrcKey, - lpNameBuffer, - 0, - KEY_READ, - &hSrcSubKey); - if (Error != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", Error); - RegCloseKey(hDstSubKey); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError((DWORD)Error); - return FALSE; - } - - if (!CopyKey(hDstSubKey, - hSrcSubKey)) - { - DPRINT1("Error: %lu\n", GetLastError()); - RegCloseKey (hSrcSubKey); - RegCloseKey (hDstSubKey); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - return FALSE; - } - - RegCloseKey(hSrcSubKey); - RegCloseKey(hDstSubKey); - } - - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - } - - /* Copy values */ - if (dwValues != 0) - { - lpNameBuffer = HeapAlloc(GetProcessHeap(), - 0, - dwMaxValueNameLength * sizeof(WCHAR)); - if (lpNameBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - lpDataBuffer = HeapAlloc(GetProcessHeap(), - 0, - dwMaxValueLength); - if (lpDataBuffer == NULL) - { - DPRINT1("Buffer allocation failed\n"); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } - - for (i = 0; i < dwValues; i++) - { - dwValueNameLength = dwMaxValueNameLength; - dwValueLength = dwMaxValueLength; - Error = RegEnumValueW(hSrcKey, - i, - lpNameBuffer, - &dwValueNameLength, - NULL, - &dwType, - lpDataBuffer, - &dwValueLength); - if (Error != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", Error); - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError((DWORD)Error); - return FALSE; - } - - Error = RegSetValueExW(hDstKey, - lpNameBuffer, - 0, - dwType, - lpDataBuffer, - dwValueLength); - if (Error != ERROR_SUCCESS) - { - DPRINT1("Error: %lu\n", Error); - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - SetLastError((DWORD)Error); - return FALSE; - } - } - - HeapFree(GetProcessHeap(), - 0, - lpDataBuffer); - - HeapFree(GetProcessHeap(), - 0, - lpNameBuffer); - } - - DPRINT("CopyKey() done\n"); - - return TRUE; -#endif }