From 4ab44d7a80824b2ac3f9bbab1769fc0929f5784e Mon Sep 17 00:00:00 2001 From: Joachim Henze Date: Sun, 30 Jan 2022 03:25:02 +0100 Subject: [PATCH] [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. --- sdk/tools/mkhive/cmi.h | 2 + sdk/tools/mkhive/mkhive.h | 5 ++ sdk/tools/mkhive/reginf.c | 3 + sdk/tools/mkhive/registry.c | 137 ++++++++++++++++++++++++++++++------ sdk/tools/mkhive/registry.h | 6 +- sdk/tools/mkhive/rtl.c | 50 ++++++------- 6 files changed, 157 insertions(+), 46 deletions(-) diff --git a/sdk/tools/mkhive/cmi.h b/sdk/tools/mkhive/cmi.h index 2d1762392ea..aa6f1e4eeaa 100644 --- a/sdk/tools/mkhive/cmi.h +++ b/sdk/tools/mkhive/cmi.h @@ -24,6 +24,8 @@ * PROGRAMMER: Hervé Poussineau */ +#pragma once + #define VERIFY_KEY_CELL(key) NTSTATUS diff --git a/sdk/tools/mkhive/mkhive.h b/sdk/tools/mkhive/mkhive.h index 519ee91758c..d28c0a0d1d8 100644 --- a/sdk/tools/mkhive/mkhive.h +++ b/sdk/tools/mkhive/mkhive.h @@ -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, diff --git a/sdk/tools/mkhive/reginf.c b/sdk/tools/mkhive/reginf.c index 931fc2feab3..02e7ef05889 100644 --- a/sdk/tools/mkhive/reginf.c +++ b/sdk/tools/mkhive/reginf.c @@ -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); diff --git a/sdk/tools/mkhive/registry.c b/sdk/tools/mkhive/registry.c index e7a8cc9100c..57417408e4e 100644 --- a/sdk/tools/mkhive/registry.c +++ b/sdk/tools/mkhive/registry.c @@ -26,7 +26,7 @@ /* * TODO: - * - Implement RegDeleteKeyW() and RegDeleteValueW() + * - Implement RegDeleteValueW() */ #include @@ -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, diff --git a/sdk/tools/mkhive/registry.h b/sdk/tools/mkhive/registry.h index 0215a319a47..1945bc9aa32 100644 --- a/sdk/tools/mkhive/registry.h +++ b/sdk/tools/mkhive/registry.h @@ -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 diff --git a/sdk/tools/mkhive/rtl.c b/sdk/tools/mkhive/rtl.c index f2c84c7fdec..c7979afc6a0 100644 --- a/sdk/tools/mkhive/rtl.c +++ b/sdk/tools/mkhive/rtl.c @@ -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); }