https://git.reactos.org/?p=reactos.git;a=commitdiff;h=eef22cc03666b24de5e022638125cc06f554b46f
commit eef22cc03666b24de5e022638125cc06f554b46f Author: Timo Kreuzer <timo.kreu...@reactos.org> AuthorDate: Mon Nov 20 21:28:25 2023 +0200 Commit: Timo Kreuzer <timo.kreu...@reactos.org> CommitDate: Mon Dec 18 23:14:14 2023 +0200 [ADVAPI32] Unify source for vista registry functions - In advapi32_vista compile the code from advapi32/reg/reg.c - Export RegCopyTreeW from advapi32_vista --- dll/win32/advapi32/reg/reg.c | 199 ++++++++++++++++++++++++++++ dll/win32/advapi32_vista/CMakeLists.txt | 15 ++- 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 ---- 6 files changed, 219 insertions(+), 328 deletions(-) diff --git a/dll/win32/advapi32/reg/reg.c b/dll/win32/advapi32/reg/reg.c index 1e06f67a919..38a434fddd7 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 @@ Cleanup2: return ERROR_SUCCESS; } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegCopyTreeA @@ -1734,6 +1737,7 @@ Cleanup: } #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 @@ Cleanup: return Ret; } +#ifndef _ADVAPI32_VISTA_ /************************************************************************ * RegSetKeyValueA @@ -5136,4 +5143,196 @@ 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 ab6e406876a..3af7909efb7 100644 --- a/dll/win32/advapi32_vista/CMakeLists.txt +++ b/dll/win32/advapi32_vista/CMakeLists.txt @@ -2,19 +2,22 @@ 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 + ${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_dependencies(advapi32_vista psdk advapi32) 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 0902d8455d7..6ed5bb68a67 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 0a9f6192fb7..00000000000 --- 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 8d80949660c..00000000000 --- a/dll/win32/advapi32_vista/RegLoadMUIString.c +++ /dev/null @@ -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; -} diff --git a/dll/win32/advapi32_vista/RegSetKeyValue.c b/dll/win32/advapi32_vista/RegSetKeyValue.c deleted file mode 100644 index 8701eb87df4..00000000000 --- 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; -}