[MKHIVE] Minor improvements.
[reactos.git] / sdk / tools / mkhive / registry.c
index 17030bb..a3cc712 100644 (file)
  *   - Implement RegDeleteKeyW() and RegDeleteValueW()
  */
 
  *   - Implement RegDeleteKeyW() and RegDeleteValueW()
  */
 
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
 #define NDEBUG
 #include "mkhive.h"
 
 #define NDEBUG
 #include "mkhive.h"
 
@@ -370,7 +366,7 @@ LIST_ENTRY CmiHiveListHead;
 LIST_ENTRY CmiReparsePointsHead;
 
 static LONG
 LIST_ENTRY CmiReparsePointsHead;
 
 static LONG
-RegpOpenOrCreateKey(
+RegpCreateOrOpenKey(
     IN HKEY hParentKey,
     IN PCWSTR KeyName,
     IN BOOL AllowCreation,
     IN HKEY hParentKey,
     IN PCWSTR KeyName,
     IN BOOL AllowCreation,
@@ -390,7 +386,7 @@ RegpOpenOrCreateKey(
     PCM_KEY_NODE SubKeyCell;
     HCELL_INDEX BlockOffset;
 
     PCM_KEY_NODE SubKeyCell;
     HCELL_INDEX BlockOffset;
 
-    DPRINT("RegpCreateOpenKey('%S')\n", KeyName);
+    DPRINT("RegpCreateOrOpenKey('%S')\n", KeyName);
 
     if (*KeyName == OBJ_NAME_PATH_SEPARATOR)
     {
 
     if (*KeyName == OBJ_NAME_PATH_SEPARATOR)
     {
@@ -463,11 +459,18 @@ RegpOpenOrCreateKey(
                                   Volatile,
                                   &BlockOffset);
         }
                                   Volatile,
                                   &BlockOffset);
         }
+        else // if (BlockOffset == HCELL_NIL)
+        {
+            Status = STATUS_OBJECT_NAME_NOT_FOUND; // ERROR_PATH_NOT_FOUND;
+        }
 
         HvReleaseCell(&ParentRegistryHive->Hive, ParentCellOffset);
 
         if (!NT_SUCCESS(Status))
 
         HvReleaseCell(&ParentRegistryHive->Hive, ParentCellOffset);
 
         if (!NT_SUCCESS(Status))
+        {
+            DPRINT("RegpCreateOrOpenKey('%S'): Could not create or open subkey '%wZ'\n", KeyName, &KeyString);
             return ERROR_UNSUCCESSFUL;
             return ERROR_UNSUCCESSFUL;
+        }
 
         ParentCellOffset = BlockOffset;
         if (End)
 
         ParentCellOffset = BlockOffset;
         if (End)
@@ -486,31 +489,24 @@ RegpOpenOrCreateKey(
 }
 
 LONG WINAPI
 }
 
 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
     return ERROR_SUCCESS;
 }
 
 LONG WINAPI
-RegOpenKeyW(
+RegCreateKeyW(
     IN HKEY hKey,
     IN LPCWSTR lpSubKey,
     OUT PHKEY phkResult)
 {
     IN HKEY hKey,
     IN LPCWSTR lpSubKey,
     OUT PHKEY phkResult)
 {
-    return RegpOpenOrCreateKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
+    return RegpCreateOrOpenKey(hKey, lpSubKey, TRUE, FALSE, phkResult);
 }
 
 LONG WINAPI
 }
 
 LONG WINAPI
@@ -525,13 +521,32 @@ RegCreateKeyExW(
     OUT PHKEY phkResult,
     OUT LPDWORD lpdwDisposition OPTIONAL)
 {
     OUT PHKEY phkResult,
     OUT LPDWORD lpdwDisposition OPTIONAL)
 {
-    return RegpOpenOrCreateKey(hKey,
+    return RegpCreateOrOpenKey(hKey,
                                lpSubKey,
                                TRUE,
                                (dwOptions & REG_OPTION_VOLATILE) != 0,
                                phkResult);
 }
 
                                lpSubKey,
                                TRUE,
                                (dwOptions & REG_OPTION_VOLATILE) != 0,
                                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 RegpCreateOrOpenKey(hKey, lpSubKey, FALSE, FALSE, phkResult);
+}
+
 LONG WINAPI
 RegSetValueExW(
     IN HKEY hKey,
 LONG WINAPI
 RegSetValueExW(
     IN HKEY hKey,
@@ -545,6 +560,7 @@ RegSetValueExW(
     PHHIVE Hive;
     PCM_KEY_NODE KeyNode; // ParentNode
     PCM_KEY_VALUE ValueCell;
     PHHIVE Hive;
     PCM_KEY_NODE KeyNode; // ParentNode
     PCM_KEY_VALUE ValueCell;
+    ULONG ChildIndex;
     HCELL_INDEX CellIndex;
     UNICODE_STRING ValueNameString;
 
     HCELL_INDEX CellIndex;
     UNICODE_STRING ValueNameString;
 
@@ -588,12 +604,24 @@ RegSetValueExW(
 
     /* Initialize value name string */
     RtlInitUnicodeString(&ValueNameString, lpValueName);
 
     /* Initialize value name string */
     RtlInitUnicodeString(&ValueNameString, lpValueName);
-    CellIndex = CmpFindValueByName(Hive, KeyNode, &ValueNameString);
+    if (!CmpFindNameInList(Hive,
+                           &KeyNode->ValueList,
+                           &ValueNameString,
+                           &ChildIndex,
+                           &CellIndex))
+    {
+        /* Sanity check */
+        ASSERT(CellIndex == HCELL_NIL);
+        /* Fail */
+        // Status = STATUS_INSUFFICIENT_RESOURCES;
+        return ERROR_UNSUCCESSFUL;
+    }
     if (CellIndex == HCELL_NIL)
     {
         /* The value doesn't exist, create a new one */
         Status = CmiAddValueKey(Key->RegistryHive,
                                 KeyNode,
     if (CellIndex == HCELL_NIL)
     {
         /* The value doesn't exist, create a new one */
         Status = CmiAddValueKey(Key->RegistryHive,
                                 KeyNode,
+                                ChildIndex,
                                 &ValueNameString,
                                 &ValueCell,
                                 &CellIndex);
                                 &ValueNameString,
                                 &ValueCell,
                                 &CellIndex);
@@ -686,7 +714,7 @@ RegSetValueExW(
 }
 
 
 }
 
 
-// Synced with freeldr/windows/registry.c
+// Synced with freeldr/ntldr/registry.c
 static
 VOID
 RepGetValueData(
 static
 VOID
 RepGetValueData(
@@ -725,7 +753,7 @@ RepGetValueData(
     }
 }
 
     }
 }
 
-// Similar to RegQueryValue in freeldr/windows/registry.c
+// Similar to RegQueryValue in freeldr/ntldr/registry.c
 LONG WINAPI
 RegQueryValueExW(
     IN HKEY hKey,
 LONG WINAPI
 RegQueryValueExW(
     IN HKEY hKey,
@@ -785,9 +813,9 @@ ConnectRegistry(
     IN PCWSTR Path)
 {
     NTSTATUS Status;
     IN PCWSTR Path)
 {
     NTSTATUS Status;
+    LONG rc;
     PREPARSE_POINT ReparsePoint;
     PMEMKEY NewKey;
     PREPARSE_POINT ReparsePoint;
     PMEMKEY NewKey;
-    LONG rc;
 
     ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
     if (!ReparsePoint)
 
     ReparsePoint = (PREPARSE_POINT)malloc(sizeof(*ReparsePoint));
     if (!ReparsePoint)
@@ -819,7 +847,7 @@ ConnectRegistry(
     if (!NT_SUCCESS(Status))
         DPRINT1("Failed to add security for root key '%S'\n", Path);
 
     if (!NT_SUCCESS(Status))
         DPRINT1("Failed to add security for root key '%S'\n", Path);
 
-    /* Create key */
+    /* Create the key */
     rc = RegCreateKeyExW(RootKey,
                          Path,
                          0,
     rc = RegCreateKeyExW(RootKey,
                          Path,
                          0,
@@ -853,6 +881,7 @@ CreateSymLink(
     // IN PCWSTR TargetKeyPath OPTIONAL,
     IN HKEY TargetKeyHandle)
 {
     // IN PCWSTR TargetKeyPath OPTIONAL,
     IN HKEY TargetKeyHandle)
 {
+    LONG rc;
     PMEMKEY LinkKey, TargetKey;
     PREPARSE_POINT ReparsePoint;
 
     PMEMKEY LinkKey, TargetKey;
     PREPARSE_POINT ReparsePoint;
 
@@ -863,15 +892,20 @@ CreateSymLink(
     if (LinkKeyPath && !(LinkKeyHandle && *LinkKeyHandle))
     {
         /* Create the link key */
     if (LinkKeyPath && !(LinkKeyHandle && *LinkKeyHandle))
     {
         /* Create the link key */
-        RegCreateKeyExW(NULL,
-                        LinkKeyPath,
-                        0,
-                        NULL,
-                        REG_OPTION_VOLATILE,
-                        0,
-                        NULL,
-                        (HKEY*)&LinkKey,
-                        NULL);
+        rc = RegCreateKeyExW(NULL,
+                             LinkKeyPath,
+                             0,
+                             NULL,
+                             REG_OPTION_VOLATILE,
+                             0,
+                             NULL,
+                             (PHKEY)&LinkKey,
+                             NULL);
+        if (rc != ERROR_SUCCESS)
+        {
+            free(ReparsePoint);
+            return FALSE;
+        }
     }
     else if (LinkKeyHandle)
     {
     }
     else if (LinkKeyHandle)
     {
@@ -942,6 +976,8 @@ RegInitializeRegistry(
     CreateSymLink(L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
                   NULL, ControlSetKey);
 
     CreateSymLink(L"Registry\\Machine\\SYSTEM\\CurrentControlSet",
                   NULL, ControlSetKey);
 
+    RegCloseKey(ControlSetKey);
+
 #if 0
     /* Link SECURITY to SAM */
     CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", L"\\Registry\\Machine\\SAM\\SAM");
 #if 0
     /* Link SECURITY to SAM */
     CmpLinkKeyToHive(L"\\Registry\\Machine\\Security\\SAM", L"\\Registry\\Machine\\SAM\\SAM");