[0.4.9][MKHIVE] Fix leaks and Implement RegDeleteKeyW() to mute a compile-time-warning CORE-18031

The motivation to upgrade this host-tool is to fix a compile-time warning:
  [4890/10620] Generating boot/bootdata/...oot/bootdata/system, boot/bootdata/BCD
  Binary hive maker
->RegDeleteKeyW(0x0xcab210, '') is UNIMPLEMENTED!
  [145/10684] Generating boot/bootdata/BCD
  Binary hive maker
  Creating binary hive: /home/jhenze/Release_WorkDir/Repo/output-MinGW-i386/reactos/boot/bootdata/BCD

Thw warning was most likely introduced when we started using mkhive in the hosttools, and is triggered
by livecd.inf having a [DelReg] section.

Warning fixed by implementing RegDeleteKeyW().
It can not delete full trees yet, but we also don't need that for our mkhive-usage yet.

While touching it, do also fix some other minor glitches and leaks.

This is a PARTIAL backport of the 15 commits from 0.4.11-dev, all to mkhive from 2018-10-09 to 2018-10-20 by hbelusca.
This commit is contained in:
Joachim Henze 2022-01-30 03:25:02 +01:00
parent e9fe2a29e4
commit 4ab44d7a80
6 changed files with 157 additions and 46 deletions

View file

@ -24,6 +24,8 @@
* PROGRAMMER: Hervé Poussineau
*/
#pragma once
#define VERIFY_KEY_CELL(key)
NTSTATUS

View file

@ -61,6 +61,7 @@ VOID NTAPI
RtlInitUnicodeString(
IN OUT PUNICODE_STRING DestinationString,
IN PCWSTR SourceString);
WCHAR NTAPI
RtlUpcaseUnicodeChar(
IN WCHAR Source);
@ -83,6 +84,10 @@ RegSetValueExW(
IN const UCHAR* lpData,
IN ULONG cbData);
LONG WINAPI
RegCloseKey(
IN HKEY hKey);
LONG WINAPI
RegDeleteKeyW(
IN HKEY hKey,

View file

@ -463,8 +463,11 @@ registry_callback(HINF hInf, PWCHAR Section, BOOL Delete)
/* and now do it */
if (!do_reg_operation(KeyHandle, ValuePtr, Context, Flags))
{
RegCloseKey(KeyHandle);
return FALSE;
}
RegCloseKey(KeyHandle);
}
InfHostFreeContext(Context);

View file

@ -26,7 +26,7 @@
/*
* TODO:
* - Implement RegDeleteKeyW() and RegDeleteValueW()
* - Implement RegDeleteValueW()
*/
#include <stdlib.h>
@ -464,6 +464,18 @@ RegpOpenOrCreateKey(
return ERROR_SUCCESS;
}
LONG WINAPI
RegCloseKey(
IN HKEY hKey)
{
PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
/* Free the object */
free(Key);
return ERROR_SUCCESS;
}
LONG WINAPI
RegCreateKeyW(
IN HKEY hKey,
@ -473,25 +485,6 @@ RegCreateKeyW(
return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
}
LONG WINAPI
RegDeleteKeyW(
IN HKEY hKey,
IN LPCWSTR lpSubKey)
{
DPRINT1("RegDeleteKeyW(0x%p, '%S') is UNIMPLEMENTED!\n",
hKey, (lpSubKey ? lpSubKey : L""));
return ERROR_SUCCESS;
}
LONG WINAPI
RegOpenKeyW(
IN HKEY hKey,
IN LPCWSTR lpSubKey,
OUT PHKEY phkResult)
{
return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
}
LONG WINAPI
RegCreateKeyExW(
IN HKEY hKey,
@ -511,6 +504,110 @@ RegCreateKeyExW(
phkResult);
}
LONG WINAPI
RegDeleteKeyW(
IN HKEY hKey,
IN LPCWSTR lpSubKey)
{
LONG rc;
NTSTATUS Status;
HKEY hTargetKey;
PMEMKEY Key; // ParentKey
PHHIVE Hive;
PCM_KEY_NODE KeyNode; // ParentNode
PCM_KEY_NODE Parent;
HCELL_INDEX ParentCell;
if (lpSubKey)
{
rc = RegOpenKeyW(hKey, lpSubKey, &hTargetKey);
if (rc != ERROR_SUCCESS)
return rc;
}
else
{
hTargetKey = hKey;
rc = ERROR_SUCCESS;
}
/* Don't allow deleting the root */
if (hTargetKey == RootKey)
{
/* Fail */
rc = ERROR_ACCESS_DENIED; // STATUS_CANNOT_DELETE;
goto Quit;
}
/* Get the hive and node */
Key = HKEY_TO_MEMKEY(hTargetKey);
Hive = &Key->RegistryHive->Hive;
/* Get the key node */
KeyNode = (PCM_KEY_NODE)HvGetCell(Hive, Key->KeyCellOffset);
if (!KeyNode)
{
rc = ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
goto Quit;
}
ASSERT(KeyNode->Signature == CM_KEY_NODE_SIGNATURE);
/* Check if we don't have any children */
if (!(KeyNode->SubKeyCounts[Stable] + KeyNode->SubKeyCounts[Volatile]) &&
!(KeyNode->Flags & KEY_NO_DELETE))
{
/* Get the parent and free the cell */
ParentCell = KeyNode->Parent;
Status = CmpFreeKeyByCell(Hive, Key->KeyCellOffset, TRUE);
if (NT_SUCCESS(Status))
{
/* Get the parent node */
Parent = (PCM_KEY_NODE)HvGetCell(Hive, ParentCell);
if (Parent)
{
/* Make sure we're dirty */
ASSERT(HvIsCellDirty(Hive, ParentCell));
/* Update the write time */
KeQuerySystemTime(&Parent->LastWriteTime);
/* Release the cell */
HvReleaseCell(Hive, ParentCell);
}
rc = ERROR_SUCCESS;
}
else
{
/* Fail */
rc = ERROR_GEN_FAILURE; // STATUS_UNSUCCESSFUL;
}
}
else
{
/* Fail */
rc = ERROR_ACCESS_DENIED; // STATUS_CANNOT_DELETE;
}
/* Release the cell */
HvReleaseCell(Hive, Key->KeyCellOffset);
Quit:
if (lpSubKey)
RegCloseKey(hTargetKey);
return rc;
}
LONG WINAPI
RegOpenKeyW(
IN HKEY hKey,
IN LPCWSTR lpSubKey,
OUT PHKEY phkResult)
{
return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
}
LONG WINAPI
RegSetValueExW(
IN HKEY hKey,

View file

@ -36,10 +36,12 @@ extern CMHIVE BcdHive; /* \Registry\Machine\BCD00000000 */
#define ERROR_SUCCESS 0L
#define ERROR_UNSUCCESSFUL 1L
#define ERROR_FILE_NOT_FOUND 2L
#define ERROR_ACCESS_DENIED 5L
#define ERROR_OUTOFMEMORY 14L
#define ERROR_GEN_FAILURE 31L
#define ERROR_INVALID_PARAMETER 87L
#define ERROR_MORE_DATA 234L
#define ERROR_NO_MORE_ITEMS 259L
// #define ERROR_MORE_DATA 234L
// #define ERROR_NO_MORE_ITEMS 259L
#define REG_NONE 0
#define REG_SZ 1

View file

@ -131,28 +131,28 @@ DbgPrint(
VOID
NTAPI
RtlAssert(PVOID FailedAssertion,
PVOID FileName,
ULONG LineNumber,
PCHAR Message)
RtlAssert(IN PVOID FailedAssertion,
IN PVOID FileName,
IN ULONG LineNumber,
IN PCHAR Message OPTIONAL)
{
if (NULL != Message)
{
DbgPrint("Assertion \'%s\' failed at %s line %d: %s\n",
(PCHAR)FailedAssertion,
(PCHAR)FileName,
LineNumber,
Message);
}
else
{
DbgPrint("Assertion \'%s\' failed at %s line %d\n",
(PCHAR)FailedAssertion,
(PCHAR)FileName,
LineNumber);
}
if (Message != NULL)
{
DbgPrint("Assertion \'%s\' failed at %s line %u: %s\n",
(PCHAR)FailedAssertion,
(PCHAR)FileName,
LineNumber,
Message);
}
else
{
DbgPrint("Assertion \'%s\' failed at %s line %u\n",
(PCHAR)FailedAssertion,
(PCHAR)FileName,
LineNumber);
}
//DbgBreakPoint();
//DbgBreakPoint();
}
// DECLSPEC_NORETURN
@ -165,10 +165,12 @@ KeBugCheckEx(
IN ULONG_PTR BugCheckParameter3,
IN ULONG_PTR BugCheckParameter4)
{
char Buffer[70];
printf("*** STOP: 0x%08X (0x%08lX, 0x%08lX, 0x%08lX, 0x%08lX)",
BugCheckCode, BugCheckParameter1, BugCheckParameter2,
BugCheckParameter3, BugCheckParameter4);
printf("*** STOP: 0x%08X (0x%p,0x%p,0x%p,0x%p)",
BugCheckCode,
(PVOID)BugCheckParameter1,
(PVOID)BugCheckParameter2,
(PVOID)BugCheckParameter3,
(PVOID)BugCheckParameter4);
ASSERT(FALSE);
}