[0.4.8][MKHIVE] Fix leaks and Implement RegDeleteKeyW() to mute a compile-time-warnin...
authorJoachim Henze <Joachim.Henze@reactos.org>
Sun, 30 Jan 2022 02:26:32 +0000 (03:26 +0100)
committerJoachim Henze <Joachim.Henze@reactos.org>
Sun, 30 Jan 2022 02:26:32 +0000 (03:26 +0100)
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
sdk/tools/mkhive/mkhive.h
sdk/tools/mkhive/reginf.c
sdk/tools/mkhive/registry.c
sdk/tools/mkhive/registry.h
sdk/tools/mkhive/rtl.c

index 2d17623..aa6f1e4 100644 (file)
@@ -24,6 +24,8 @@
  * PROGRAMMER:      HervĂ© Poussineau
  */
 
+#pragma once
+
 #define VERIFY_KEY_CELL(key)
 
 NTSTATUS
index 519ee91..d28c0a0 100644 (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,
index 931fc2f..02e7ef0 100644 (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);
index e7a8cc9..5741740 100644 (file)
@@ -26,7 +26,7 @@
 
 /*
  * TODO:
- *   - Implement RegDeleteKeyW() and RegDeleteValueW()
+ *   - Implement RegDeleteValueW()
  */
 
 #include <stdlib.h>
@@ -465,31 +465,24 @@ RegpOpenOrCreateKey(
 }
 
 LONG WINAPI
-RegCreateKeyW(
-    IN HKEY hKey,
-    IN LPCWSTR lpSubKey,
-    OUT PHKEY phkResult)
+RegCloseKey(
+    IN HKEY hKey)
 {
-    return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
-}
+    PMEMKEY Key = HKEY_TO_MEMKEY(hKey); // ParentKey
+
+    /* Free the object */
+    free(Key);
 
-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(
+RegCreateKeyW(
     IN HKEY hKey,
     IN LPCWSTR lpSubKey,
     OUT PHKEY phkResult)
 {
-    return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
+    return RegpOpenOrCreateKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
 }
 
 LONG WINAPI
@@ -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,
index 0215a31..1945bc9 100644 (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
index f2c84c7..c7979af 100644 (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);
-   }
-
-   //DbgBreakPoint();
+    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();
 }
 
 // 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);
 }