Skip to content

Commit

Permalink
[ADVAPI32][USERENV][SERVICES] Unify source for vista registry functions
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
tkreuzer committed Oct 7, 2023
1 parent 6d3c214 commit 9dbbd6d
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 894 deletions.
2 changes: 1 addition & 1 deletion base/system/services/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
343 changes: 2 additions & 341 deletions base/system/services/controlset.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#define NDEBUG
#include <debug.h>

LSTATUS WINAPI RegCopyTreeW(_In_ HKEY, _In_opt_ LPCWSTR, _In_ HKEY);
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR);

/* GLOBALS *******************************************************************/

Expand All @@ -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(
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
Loading

0 comments on commit 9dbbd6d

Please sign in to comment.