forget update de.rc
[reactos.git] / reactos / ntoskrnl / cm / registry.c
index 26b3a80..c2cc4a2 100644 (file)
@@ -1,14 +1,13 @@
-/* $Id: registry.c,v 1.127 2004/10/22 20:14:04 ekohl Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/cm/registry.c
  * PURPOSE:         Registry functions
+ *
  * PROGRAMMERS:     Rex Jolliff
  *                  Matt Pyne
  *                  Jean Michault
- * UPDATE HISTORY:
- *                  Created 22/05/98
  */
 
 #include <ntoskrnl.h>
 
 #include "cm.h"
 
+#if defined (ALLOC_PRAGMA)
+#pragma alloc_text(INIT, CmInitHives)
+#pragma alloc_text(INIT, CmInitializeRegistry)
+#pragma alloc_text(INIT, CmInit2)
+#endif
+
+
 /* GLOBALS ******************************************************************/
 
 POBJECT_TYPE  CmiKeyType = NULL;
 PREGISTRY_HIVE  CmiVolatileHive = NULL;
-KSPIN_LOCK  CmiKeyListLock;
 
 LIST_ENTRY CmiHiveListHead;
-ERESOURCE CmiHiveListLock;
+
+ERESOURCE CmiRegistryLock;
+
+KTIMER CmiWorkerTimer;
+LIST_ENTRY CmiKeyObjectListHead;
+ULONG CmiTimer = 0;
 
 volatile BOOLEAN CmiHiveSyncEnabled = FALSE;
 volatile BOOLEAN CmiHiveSyncPending = FALSE;
@@ -49,6 +59,9 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
                      PVOID SystemArgument1,
                      PVOID SystemArgument2);
 
+extern LIST_ENTRY CmiCallbackHead;
+extern FAST_MUTEX CmiCallbackLock;
+
 /* FUNCTIONS ****************************************************************/
 
 VOID
@@ -72,7 +85,7 @@ CmiCheckSubKeys(BOOLEAN Verbose,
       BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
       KeyInfo = ExAllocatePool(PagedPool, BufferSize);
 
-      Status = NtEnumerateKey(Key,
+      Status = ZwEnumerateKey(Key,
                              Index,
                              KeyNodeInformation,
                              KeyInfo,
@@ -110,7 +123,7 @@ CmiCheckSubKeys(BOOLEAN Verbose,
                                 NULL,
                                 NULL);
 
-      Status = NtOpenKey(&SubKey,
+      Status = ZwOpenKey(&SubKey,
                         KEY_ALL_ACCESS,
                         &ObjectAttributes);
 
@@ -118,7 +131,7 @@ CmiCheckSubKeys(BOOLEAN Verbose,
 
       CmiCheckKey(Verbose, SubKey);
 
-      NtClose(SubKey);
+      ZwClose(SubKey);
 
       Index++;
     }
@@ -144,7 +157,7 @@ CmiCheckValues(BOOLEAN Verbose,
       BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
       ValueInfo = ExAllocatePool(PagedPool, BufferSize);
 
-      Status = NtEnumerateValueKey(Key,
+      Status = ZwEnumerateValueKey(Key,
                                   Index,
                                   KeyNodeInformation,
                                   ValueInfo,
@@ -208,7 +221,7 @@ CmiCheckByName(BOOLEAN Verbose,
                NULL,
                NULL);
 
-  Status = NtOpenKey(&Key,
+  Status = ZwOpenKey(&Key,
                KEY_ALL_ACCESS,
                &ObjectAttributes);
 
@@ -224,7 +237,7 @@ CmiCheckByName(BOOLEAN Verbose,
 
   CmiCheckKey(Verbose, Key);
 
-  NtClose(Key);
+  ZwClose(Key);
 }
 
 
@@ -238,8 +251,95 @@ CmiCheckRegistry(BOOLEAN Verbose)
   CmiCheckByName(Verbose, L"User");
 }
 
+VOID STDCALL
+CmiWorkerThread(PVOID Param)
+{
+  NTSTATUS Status;
+  PLIST_ENTRY CurrentEntry;
+  PKEY_OBJECT CurrentKey;
+  ULONG Count;
 
-VOID INIT_FUNCTION
+
+  while (1)
+  {
+    Status = KeWaitForSingleObject(&CmiWorkerTimer,
+                                  Executive,
+                                  KernelMode,
+                                  FALSE,
+                                  NULL);
+    if (Status == STATUS_SUCCESS)
+    {
+      DPRINT("CmiWorkerThread\n");
+
+      /* Acquire hive lock */
+      KeEnterCriticalRegion();
+      ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
+      CmiTimer++;
+
+      Count = 0;
+      CurrentEntry = CmiKeyObjectListHead.Blink;
+      while (CurrentEntry != &CmiKeyObjectListHead)
+      {
+         CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
+        if (CurrentKey->TimeStamp + 120 > CmiTimer)
+        {
+           /* The object was accessed in the last 10min */
+           break;
+        }
+        if (1 == ObGetObjectPointerCount(CurrentKey) &&
+            !(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
+        {
+           ObDereferenceObject(CurrentKey);
+            CurrentEntry = CmiKeyObjectListHead.Blink;
+           Count++;
+        }
+        else
+        {
+           CurrentEntry = CurrentEntry->Blink;
+        }
+      }
+      ExReleaseResourceLite(&CmiRegistryLock);
+      KeLeaveCriticalRegion();
+
+      DPRINT("Removed %d key objects\n", Count);
+
+    }
+    else
+    {
+      KEBUGCHECK(0);
+    }
+  }
+}
+
+VOID
+INIT_FUNCTION
+STDCALL
+CmInitHives(BOOLEAN SetupBoot)
+{
+    PCHAR BaseAddress;
+
+    /* Load Registry Hives. This one can be missing. */
+    if (CachedModules[SystemRegistry]) {
+        BaseAddress = (PCHAR)CachedModules[SystemRegistry]->ModStart;
+        CmImportSystemHive(BaseAddress,
+                           CachedModules[SystemRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+    }
+
+    BaseAddress = (PCHAR)CachedModules[HardwareRegistry]->ModStart;
+    CmImportHardwareHive(BaseAddress,
+                         CachedModules[HardwareRegistry]->ModEnd - (ULONG_PTR)BaseAddress);
+
+
+    /* Create dummy keys if no hardware hive was found */
+    CmImportHardwareHive (NULL, 0);
+
+    /* Initialize volatile registry settings */
+    if (SetupBoot == FALSE) CmInit2((PCHAR)KeLoaderBlock.CommandLine);
+}
+
+VOID 
+INIT_FUNCTION
 CmInitializeRegistry(VOID)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
@@ -251,40 +351,66 @@ CmInitializeRegistry(VOID)
   HANDLE RootKeyHandle;
   HANDLE KeyHandle;
   NTSTATUS Status;
-
+  LARGE_INTEGER DueTime;
+  HANDLE ThreadHandle;
+  CLIENT_ID ThreadId;
+  OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
+  UNICODE_STRING Name;
+
+  DPRINT("Creating Registry Object Type\n");
+  
   /*  Initialize the Key object type  */
-  CmiKeyType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE));
-  ASSERT(CmiKeyType);
-  CmiKeyType->Tag = TAG('R', 'e', 'g', 'K');
-  CmiKeyType->TotalObjects = 0;
-  CmiKeyType->TotalHandles = 0;
-  CmiKeyType->MaxObjects = LONG_MAX;
-  CmiKeyType->MaxHandles = LONG_MAX;
-  CmiKeyType->PagedPoolCharge = 0;
-  CmiKeyType->NonpagedPoolCharge = sizeof(KEY_OBJECT);
-  CmiKeyType->Mapping = &CmiKeyMapping;
-  CmiKeyType->Dump = NULL;
-  CmiKeyType->Open = NULL;
-  CmiKeyType->Close = NULL;
-  CmiKeyType->Delete = CmiObjectDelete;
-  CmiKeyType->Parse = CmiObjectParse;
-  CmiKeyType->Security = CmiObjectSecurity;
-  CmiKeyType->QueryName = CmiObjectQueryName;
-  CmiKeyType->OkayToClose = NULL;
-  CmiKeyType->Create = CmiObjectCreate;
-  CmiKeyType->DuplicationNotify = NULL;
-  RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
-
-  ObpCreateTypeObject (CmiKeyType);
+  RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
+  RtlInitUnicodeString(&Name, L"Key");
+  ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
+  ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(KEY_OBJECT);
+  ObjectTypeInitializer.GenericMapping = CmiKeyMapping;
+  ObjectTypeInitializer.PoolType = PagedPool;
+  ObjectTypeInitializer.ValidAccessMask = KEY_ALL_ACCESS;
+  ObjectTypeInitializer.UseDefaultObject = TRUE;
+  ObjectTypeInitializer.DeleteProcedure = CmiObjectDelete;
+  ObjectTypeInitializer.ParseProcedure = CmiObjectParse;
+  ObjectTypeInitializer.SecurityProcedure = CmiObjectSecurity;
+  ObjectTypeInitializer.QueryNameProcedure = CmiObjectQueryName;
+
+  ObpCreateTypeObject(&ObjectTypeInitializer, &Name, &CmiKeyType);
 
   /* Initialize the hive list */
   InitializeListHead(&CmiHiveListHead);
-  ExInitializeResourceLite(&CmiHiveListLock);
+
+  /* Initialize registry lock */
+  ExInitializeResourceLite(&CmiRegistryLock);
+
+  /* Initialize the key object list */
+  InitializeListHead(&CmiKeyObjectListHead);
+
+  /* Initialize the worker timer */
+  KeInitializeTimerEx(&CmiWorkerTimer, SynchronizationTimer);
+
+  /* Initialize the worker thread */
+  Status = PsCreateSystemThread(&ThreadHandle,
+                               THREAD_ALL_ACCESS,
+                               NULL,
+                               NULL,
+                               &ThreadId,
+                               CmiWorkerThread,
+                               NULL);
+  if (!NT_SUCCESS(Status))
+  {
+    KEBUGCHECK(0);
+  }
+
+  /* Start the timer */
+  DueTime.QuadPart = -1;
+  KeSetTimerEx(&CmiWorkerTimer, DueTime, 5000, NULL); /* 5sec */
 
   /*  Build volatile registry store  */
   Status = CmiCreateVolatileHive (&CmiVolatileHive);
   ASSERT(NT_SUCCESS(Status));
 
+  InitializeListHead(&CmiCallbackHead);
+  ExInitializeFastMutex(&CmiCallbackLock);
+
   /* Create '\Registry' key. */
   RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
   InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
@@ -300,7 +426,7 @@ CmInitializeRegistry(VOID)
   ASSERT(NT_SUCCESS(Status));
   Status = ObInsertObject(RootKey,
                          NULL,
-                         STANDARD_RIGHTS_REQUIRED,
+                         KEY_ALL_ACCESS,
                          0,
                          NULL,
                          &RootKeyHandle);
@@ -313,7 +439,8 @@ CmInitializeRegistry(VOID)
   RootKey->NumberOfSubKeys = 0;
   RootKey->SubKeys = NULL;
   RootKey->SizeOfSubKeys = 0;
-  Status = RtlCreateUnicodeString(&RootKey->Name, L"Registry");
+  InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry);
+  Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
   ASSERT(NT_SUCCESS(Status));
 
 #if 0
@@ -328,7 +455,6 @@ CmInitializeRegistry(VOID)
   CmiVolatileHive->RootSecurityCell = RootSecurityCell;
 #endif
 
-  KeInitializeSpinLock(&CmiKeyListLock);
 
   /* Create '\Registry\Machine' key. */
   RtlInitUnicodeString(&KeyName,
@@ -338,8 +464,8 @@ CmInitializeRegistry(VOID)
                             0,
                             RootKeyHandle,
                             NULL);
-  Status = NtCreateKey(&KeyHandle,
-                      STANDARD_RIGHTS_REQUIRED,
+  Status = ZwCreateKey(&KeyHandle,
+                      KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
@@ -355,8 +481,8 @@ CmInitializeRegistry(VOID)
                             0,
                             RootKeyHandle,
                             NULL);
-  Status = NtCreateKey(&KeyHandle,
-                      STANDARD_RIGHTS_REQUIRED,
+  Status = ZwCreateKey(&KeyHandle,
+                      KEY_ALL_ACCESS,
                       &ObjectAttributes,
                       0,
                       NULL,
@@ -425,7 +551,7 @@ CmInit2(PCHAR CommandLine)
         MiniNT = TRUE;
       else if (!_strnicmp(CommandLine, "DEBUGPORT=PICE", 14))
         PiceStart = 1;
-      
+
       /* Add a space between the options */
       if (Position != 0)
         SystemStartOptions[Position++] = L' ';
@@ -482,8 +608,9 @@ CmiCreateCurrentControlSetLink(VOID)
   RTL_QUERY_REGISTRY_TABLE QueryTable[5];
   WCHAR TargetNameBuffer[80];
   ULONG TargetNameLength;
-  UNICODE_STRING LinkName;
-  UNICODE_STRING LinkValue;
+  UNICODE_STRING LinkName = RTL_CONSTANT_STRING(
+                            L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet");
+  UNICODE_STRING LinkValue = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
   ULONG CurrentSet;
   ULONG DefaultSet;
   ULONG Failed;
@@ -531,14 +658,12 @@ CmiCreateCurrentControlSetLink(VOID)
 
   DPRINT("Link target '%S'\n", TargetNameBuffer);
 
-  RtlRosInitUnicodeStringFromLiteral(&LinkName,
-                                 L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet");
   InitializeObjectAttributes(&ObjectAttributes,
                             &LinkName,
                             OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK,
                             NULL,
                             NULL);
-  Status = NtCreateKey(&KeyHandle,
+  Status = ZwCreateKey(&KeyHandle,
                       KEY_ALL_ACCESS | KEY_CREATE_LINK,
                       &ObjectAttributes,
                       0,
@@ -547,13 +672,11 @@ CmiCreateCurrentControlSetLink(VOID)
                       NULL);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
+      DPRINT1("ZwCreateKey() failed (Status %lx)\n", Status);
       return(Status);
     }
 
-  RtlRosInitUnicodeStringFromLiteral(&LinkValue,
-                                 L"SymbolicLinkValue");
-  Status = NtSetValueKey(KeyHandle,
+  Status = ZwSetValueKey(KeyHandle,
                         &LinkValue,
                         0,
                         REG_LINK,
@@ -561,10 +684,10 @@ CmiCreateCurrentControlSetLink(VOID)
                         TargetNameLength);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("NtSetValueKey() failed (Status %lx)\n", Status);
+      DPRINT1("ZwSetValueKey() failed (Status %lx)\n", Status);
     }
 
-  NtClose(KeyHandle);
+  ZwClose(KeyHandle);
 
   return Status;
 }
@@ -579,14 +702,32 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
   PKEY_OBJECT NewKey;
   NTSTATUS Status;
   PWSTR SubName;
+  UNICODE_STRING ObjectName;
+  OBJECT_CREATE_INFORMATION ObjectCreateInfo;
 
   DPRINT("CmiConnectHive(%p, %p) called.\n",
         KeyObjectAttributes, RegistryHive);
-
-  Status = ObFindObject(KeyObjectAttributes,
-                       (PVOID*)&ParentKey,
-                       &RemainingPath,
-                       CmiKeyType);
+     
+   /* Capture all the info */
+   DPRINT("Capturing Create Info\n");
+   Status = ObpCaptureObjectAttributes(KeyObjectAttributes,
+                                       KernelMode,
+                                       CmiKeyType,
+                                       &ObjectCreateInfo,
+                                       &ObjectName);
+   if (!NT_SUCCESS(Status))
+     {
+       DPRINT("ObpCaptureObjectAttributes() failed (Status %lx)\n", Status);
+       return Status;
+     }
+
+  Status = ObFindObject(&ObjectCreateInfo,
+                        &ObjectName,
+                                   (PVOID*)&ParentKey,
+                        &RemainingPath,
+                        CmiKeyType);
+     ObpReleaseCapturedAttributes(&ObjectCreateInfo);
+   if (ObjectName.Buffer) ExFreePool(ObjectName.Buffer);
   if (!NT_SUCCESS(Status))
     {
       return Status;
@@ -627,6 +768,7 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
                          0,
                          0,
                          (PVOID*)&NewKey);
+                            
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
@@ -634,15 +776,23 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
       RtlFreeUnicodeString(&RemainingPath);
       return Status;
     }
-
+    DPRINT("Inserting Key into Object Tree\n");
+    Status =  ObInsertObject((PVOID)NewKey,
+                             NULL,
+                             KEY_ALL_ACCESS,
+                             0,
+                             NULL,
+                             NULL);
+DPRINT("Status %x\n", Status);
   NewKey->RegistryHive = RegistryHive;
   NewKey->KeyCellOffset = RegistryHive->HiveHeader->RootKeyOffset;
   NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset, NULL);
   NewKey->Flags = 0;
   NewKey->NumberOfSubKeys = 0;
+  InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
   if (NewKey->KeyCell->NumberOfSubKeys != 0)
     {
-      NewKey->SubKeys = ExAllocatePool(PagedPool,
+      NewKey->SubKeys = ExAllocatePool(NonPagedPool,
                                       NewKey->KeyCell->NumberOfSubKeys * sizeof(ULONG));
       if (NewKey->SubKeys == NULL)
        {
@@ -660,12 +810,12 @@ CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
 
   DPRINT ("SubName %S\n", SubName);
 
-  Status = RtlCreateUnicodeString(&NewKey->Name,
-                                 SubName);
+  Status = RtlpCreateUnicodeString(&NewKey->Name,
+              SubName, NonPagedPool);
   RtlFreeUnicodeString(&RemainingPath);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1("RtlCreateUnicodeString() failed (Status %lx)\n", Status);
+      DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
       if (NewKey->SubKeys != NULL)
        {
          ExFreePool (NewKey->SubKeys);
@@ -694,6 +844,8 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
   PREGISTRY_HIVE Hive;
   HANDLE KeyHandle;
   NTSTATUS Status;
+  PLIST_ENTRY CurrentEntry;
+  PKEY_OBJECT CurrentKey;
 
   DPRINT("CmiDisconnectHive() called\n");
 
@@ -718,7 +870,7 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
                                      KernelMode,
                                      (PVOID*)&KeyObject,
                                      NULL);
-  NtClose (KeyHandle);
+  ZwClose (KeyHandle);
   if (!NT_SUCCESS(Status))
     {
       DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
@@ -733,11 +885,36 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
       return STATUS_INVALID_PARAMETER;
     }
 
+  /* Acquire registry lock exclusively */
+  KeEnterCriticalRegion();
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
+
+  CurrentEntry = CmiKeyObjectListHead.Flink;
+  while (CurrentEntry != &CmiKeyObjectListHead)
+  {
+     CurrentKey = CONTAINING_RECORD(CurrentEntry, KEY_OBJECT, ListEntry);
+     if (1 == ObGetObjectPointerCount(CurrentKey) &&
+        !(CurrentKey->Flags & KO_MARKED_FOR_DELETE))
+     {
+        ObDereferenceObject(CurrentKey);
+        CurrentEntry = CmiKeyObjectListHead.Flink;
+     }
+     else
+     {
+        CurrentEntry = CurrentEntry->Flink;
+     }
+  }
+
   if (ObGetObjectHandleCount (KeyObject) != 0 ||
       ObGetObjectPointerCount (KeyObject) != 2)
     {
-      DPRINT1 ("Hive is still in use\n");
+      DPRINT1 ("Hive is still in use (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject));
       ObDereferenceObject (KeyObject);
+
+      /* Release registry lock */
+      ExReleaseResourceLite (&CmiRegistryLock);
+      KeLeaveCriticalRegion();
+
       return STATUS_UNSUCCESSFUL;
     }
 
@@ -749,6 +926,10 @@ CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
 
   *RegistryHive = Hive;
 
+  /* Release registry lock */
+  ExReleaseResourceLite (&CmiRegistryLock);
+  KeLeaveCriticalRegion();
+
   DPRINT ("CmiDisconnectHive() done\n");
 
   return STATUS_SUCCESS;
@@ -759,21 +940,21 @@ static NTSTATUS
 CmiInitControlSetLink (VOID)
 {
   OBJECT_ATTRIBUTES ObjectAttributes;
-  UNICODE_STRING ControlSetKeyName;
-  UNICODE_STRING ControlSetLinkName;
-  UNICODE_STRING ControlSetValueName;
+  UNICODE_STRING ControlSetKeyName = RTL_CONSTANT_STRING(
+                                L"\\Registry\\Machine\\SYSTEM\\ControlSet001");
+  UNICODE_STRING ControlSetLinkName =  RTL_CONSTANT_STRING(
+                            L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet");
+  UNICODE_STRING ControlSetValueName = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
   HANDLE KeyHandle;
   NTSTATUS Status;
 
   /* Create 'ControlSet001' key */
-  RtlRosInitUnicodeStringFromLiteral (&ControlSetKeyName,
-                                  L"\\Registry\\Machine\\SYSTEM\\ControlSet001");
   InitializeObjectAttributes (&ObjectAttributes,
                              &ControlSetKeyName,
                              OBJ_CASE_INSENSITIVE,
                              NULL,
                              NULL);
-  Status = NtCreateKey (&KeyHandle,
+  Status = ZwCreateKey (&KeyHandle,
                        KEY_ALL_ACCESS,
                        &ObjectAttributes,
                        0,
@@ -782,20 +963,18 @@ CmiInitControlSetLink (VOID)
                        NULL);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1 ("NtCreateKey() failed (Status %lx)\n", Status);
+      DPRINT1 ("ZwCreateKey() failed (Status %lx)\n", Status);
       return Status;
     }
-  NtClose (KeyHandle);
+  ZwClose (KeyHandle);
 
   /* Link 'CurrentControlSet' to 'ControlSet001' key */
-  RtlRosInitUnicodeStringFromLiteral (&ControlSetLinkName,
-                                  L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet");
   InitializeObjectAttributes (&ObjectAttributes,
                              &ControlSetLinkName,
                              OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK,
                              NULL,
                              NULL);
-  Status = NtCreateKey (&KeyHandle,
+  Status = ZwCreateKey (&KeyHandle,
                        KEY_ALL_ACCESS | KEY_CREATE_LINK,
                        &ObjectAttributes,
                        0,
@@ -804,13 +983,11 @@ CmiInitControlSetLink (VOID)
                        NULL);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1 ("NtCreateKey() failed (Status %lx)\n", Status);
+      DPRINT1 ("ZwCreateKey() failed (Status %lx)\n", Status);
       return Status;
     }
 
-  RtlRosInitUnicodeStringFromLiteral (&ControlSetValueName,
-                                  L"SymbolicLinkValue");
-  Status = NtSetValueKey (KeyHandle,
+  Status = ZwSetValueKey (KeyHandle,
                          &ControlSetValueName,
                          0,
                          REG_LINK,
@@ -818,9 +995,9 @@ CmiInitControlSetLink (VOID)
                          ControlSetKeyName.Length);
   if (!NT_SUCCESS(Status))
     {
-      DPRINT1 ("NtSetValueKey() failed (Status %lx)\n", Status);
+      DPRINT1 ("ZwSetValueKey() failed (Status %lx)\n", Status);
     }
-  NtClose (KeyHandle);
+  ZwClose (KeyHandle);
 
   return STATUS_SUCCESS;
 }
@@ -832,8 +1009,8 @@ CmiInitHives(BOOLEAN SetupBoot)
   PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
   OBJECT_ATTRIBUTES ObjectAttributes;
   UNICODE_STRING FileName;
-  UNICODE_STRING KeyName;
-  UNICODE_STRING ValueName;
+  UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE");
+  UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath");
   HANDLE KeyHandle;
 
   NTSTATUS Status;
@@ -849,41 +1026,36 @@ CmiInitHives(BOOLEAN SetupBoot)
 
   if (SetupBoot == TRUE)
     {
-      RtlRosInitUnicodeStringFromLiteral(&KeyName,
-                                     L"\\Registry\\Machine\\HARDWARE");
       InitializeObjectAttributes(&ObjectAttributes,
                                 &KeyName,
                                 OBJ_CASE_INSENSITIVE,
                                 NULL,
                                 NULL);
-      Status =  NtOpenKey(&KeyHandle,
+      Status =  ZwOpenKey(&KeyHandle,
                          KEY_ALL_ACCESS,
                          &ObjectAttributes);
       if (!NT_SUCCESS(Status))
        {
-         DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
+         DPRINT1("ZwOpenKey() failed (Status %lx)\n", Status);
          return(Status);
        }
 
-      RtlRosInitUnicodeStringFromLiteral(&ValueName,
-                                     L"InstallPath");
-
       BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
       ValueInfo = ExAllocatePool(PagedPool,
                                 BufferSize);
       if (ValueInfo == NULL)
        {
-         NtClose(KeyHandle);
+         ZwClose(KeyHandle);
          return(STATUS_INSUFFICIENT_RESOURCES);
        }
 
-      Status = NtQueryValueKey(KeyHandle,
+      Status = ZwQueryValueKey(KeyHandle,
                               &ValueName,
                               KeyValuePartialInformation,
                               ValueInfo,
                               BufferSize,
                               &ResultSize);
-      NtClose(KeyHandle);
+      ZwClose(KeyHandle);
       if (!NT_SUCCESS(Status))
        {
          ExFreePool(ValueInfo);
@@ -1067,7 +1239,7 @@ CmShutdownRegistry(VOID)
 
   /* Acquire hive list lock exclusively */
   KeEnterCriticalRegion();
-  ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
   Entry = CmiHiveListHead.Flink;
   while (Entry != &CmiHiveListHead)
@@ -1076,22 +1248,15 @@ CmShutdownRegistry(VOID)
 
       if (!(IsNoFileHive(Hive) || IsNoSynchHive(Hive)))
        {
-         /* Acquire hive resource exclusively */
-         ExAcquireResourceExclusiveLite(&Hive->HiveResource,
-                                        TRUE);
-
          /* Flush non-volatile hive */
          CmiFlushRegistryHive(Hive);
-
-         /* Release hive resource */
-         ExReleaseResourceLite(&Hive->HiveResource);
        }
 
       Entry = Entry->Flink;
     }
 
   /* Release hive list lock */
-  ExReleaseResourceLite(&CmiHiveListLock);
+  ExReleaseResourceLite(&CmiRegistryLock);
   KeLeaveCriticalRegion();
 
   DPRINT("CmShutdownRegistry() done\n");
@@ -1110,7 +1275,7 @@ CmiHiveSyncRoutine(PVOID DeferredContext)
 
   /* Acquire hive list lock exclusively */
   KeEnterCriticalRegion();
-  ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
+  ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
 
   Entry = CmiHiveListHead.Flink;
   while (Entry != &CmiHiveListHead)
@@ -1119,25 +1284,18 @@ CmiHiveSyncRoutine(PVOID DeferredContext)
 
       if (!(IsNoFileHive(Hive) || IsNoSynchHive(Hive)))
        {
-         /* Acquire hive resource exclusively */
-         ExAcquireResourceExclusiveLite(&Hive->HiveResource,
-                                        TRUE);
-
          /* Flush non-volatile hive */
          CmiFlushRegistryHive(Hive);
-
-         /* Release hive resource */
-         ExReleaseResourceLite(&Hive->HiveResource);
        }
 
       Entry = Entry->Flink;
     }
 
   /* Release hive list lock */
-  ExReleaseResourceLite(&CmiHiveListLock);
+  ExReleaseResourceLite(&CmiRegistryLock);
   KeLeaveCriticalRegion();
 
-  DPRINT("DeferredContext %x\n", DeferredContext);
+  DPRINT("DeferredContext 0x%p\n", DeferredContext);
   ExFreePool(DeferredContext);
 
   DPRINT("CmiHiveSyncRoutine() done\n");
@@ -1164,7 +1322,7 @@ CmiHiveSyncDpcRoutine(PKDPC Dpc,
                       CmiHiveSyncRoutine,
                       WorkQueueItem);
 
-  DPRINT("DeferredContext %x\n", WorkQueueItem);
+  DPRINT("DeferredContext 0x%p\n", WorkQueueItem);
   ExQueueWorkItem(WorkQueueItem,
                  CriticalWorkQueue);
 }