-/* $Id: registry.c,v 1.95 2003/05/13 21:28:26 chorns 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 <ddk/ntddk.h>
-#include <roscfg.h>
-#include <limits.h>
-#include <string.h>
-#include <internal/pool.h>
-#include <internal/registry.h>
-#include <reactos/bugcodes.h>
-
+#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.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;
PVOID SystemArgument1,
PVOID SystemArgument2);
+extern LIST_ENTRY CmiCallbackHead;
+extern FAST_MUTEX CmiCallbackLock;
+
/* FUNCTIONS ****************************************************************/
VOID
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
KeyInfo = ExAllocatePool(PagedPool, BufferSize);
- Status = NtEnumerateKey(Key,
+ Status = ZwEnumerateKey(Key,
Index,
KeyNodeInformation,
KeyInfo,
NULL,
NULL);
- Status = NtOpenKey(&SubKey,
+ Status = ZwOpenKey(&SubKey,
KEY_ALL_ACCESS,
&ObjectAttributes);
- assert(NT_SUCCESS(Status));
+ ASSERT(NT_SUCCESS(Status));
CmiCheckKey(Verbose, SubKey);
- NtClose(SubKey);
+ ZwClose(SubKey);
Index++;
}
- assert(NT_SUCCESS(Status));
+ ASSERT(NT_SUCCESS(Status));
}
BufferSize = sizeof(KEY_NODE_INFORMATION) + 4096;
ValueInfo = ExAllocatePool(PagedPool, BufferSize);
- Status = NtEnumerateValueKey(Key,
+ Status = ZwEnumerateValueKey(Key,
Index,
KeyNodeInformation,
ValueInfo,
Index++;
}
- assert(NT_SUCCESS(Status));
+ ASSERT(NT_SUCCESS(Status));
}
NULL,
NULL);
- Status = NtOpenKey(&Key,
+ Status = ZwOpenKey(&Key,
KEY_ALL_ACCESS,
&ObjectAttributes);
{
DbgPrint("KeyPath %wZ Status: %.08x", KeyPath, Status);
DbgPrint("KeyPath %S Status: %.08x", KeyPath.Buffer, Status);
- assert(NT_SUCCESS(Status));
+ ASSERT(NT_SUCCESS(Status));
}
}
CmiCheckKey(Verbose, Key);
- NtClose(Key);
+ ZwClose(Key);
}
CmiCheckByName(Verbose, L"User");
}
+VOID STDCALL
+CmiWorkerThread(PVOID Param)
+{
+ NTSTATUS Status;
+ PLIST_ENTRY CurrentEntry;
+ PKEY_OBJECT CurrentKey;
+ ULONG Count;
+
+
+ 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;
- UNICODE_STRING RootKeyName;
+ UNICODE_STRING KeyName;
PKEY_OBJECT RootKey;
- PKEY_OBJECT MachineKey;
- PKEY_OBJECT UserKey;
+#if 0
+ PSECURITY_CELL RootSecurityCell;
+#endif
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->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 = NULL;
- CmiKeyType->OkayToClose = NULL;
- CmiKeyType->Create = CmiObjectCreate;
- CmiKeyType->DuplicationNotify = NULL;
- RtlInitUnicodeString(&CmiKeyType->TypeName, L"Key");
+ 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 = CmiCreateRegistryHive(NULL, &CmiVolatileHive, FALSE);
- assert(NT_SUCCESS(Status));
+ Status = CmiCreateVolatileHive (&CmiVolatileHive);
+ ASSERT(NT_SUCCESS(Status));
+
+ InitializeListHead(&CmiCallbackHead);
+ ExInitializeFastMutex(&CmiCallbackLock);
/* Create '\Registry' key. */
- RtlInitUnicodeString(&RootKeyName, REG_ROOT_KEY_NAME);
- InitializeObjectAttributes(&ObjectAttributes, &RootKeyName, 0, NULL, NULL);
- Status = ObCreateObject(&RootKeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- &ObjectAttributes,
- CmiKeyType,
- (PVOID *) &RootKey);
- assert(NT_SUCCESS(Status));
- Status = ObReferenceObjectByHandle(RootKeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- CmiKeyType,
- KernelMode,
- (PVOID *)&RootKey,
- NULL);
- assert(NT_SUCCESS(Status));
+ RtlInitUnicodeString(&KeyName, REG_ROOT_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName, 0, NULL, NULL);
+ Status = ObCreateObject(KernelMode,
+ CmiKeyType,
+ &ObjectAttributes,
+ KernelMode,
+ NULL,
+ sizeof(KEY_OBJECT),
+ 0,
+ 0,
+ (PVOID *) &RootKey);
+ ASSERT(NT_SUCCESS(Status));
+ Status = ObInsertObject(RootKey,
+ NULL,
+ KEY_ALL_ACCESS,
+ 0,
+ NULL,
+ &RootKeyHandle);
+ ASSERT(NT_SUCCESS(Status));
RootKey->RegistryHive = CmiVolatileHive;
- RootKey->BlockOffset = CmiVolatileHive->HiveHeader->RootKeyCell;
- RootKey->KeyCell = CmiGetBlock(CmiVolatileHive, RootKey->BlockOffset, NULL);
+ RootKey->KeyCellOffset = CmiVolatileHive->HiveHeader->RootKeyOffset;
+ RootKey->KeyCell = CmiGetCell (CmiVolatileHive, RootKey->KeyCellOffset, NULL);
+ RootKey->ParentKey = RootKey;
RootKey->Flags = 0;
RootKey->NumberOfSubKeys = 0;
RootKey->SubKeys = NULL;
RootKey->SizeOfSubKeys = 0;
- RootKey->NameSize = strlen("Registry");
- RootKey->Name = ExAllocatePool(PagedPool, RootKey->NameSize);
- RtlCopyMemory(RootKey->Name, "Registry", RootKey->NameSize);
+ InsertTailList(&CmiKeyObjectListHead, &RootKey->ListEntry);
+ Status = RtlpCreateUnicodeString(&RootKey->Name, L"Registry", NonPagedPool);
+ ASSERT(NT_SUCCESS(Status));
+
+#if 0
+ Status = CmiAllocateCell(CmiVolatileHive,
+ 0x10, //LONG CellSize,
+ (PVOID *)&RootSecurityCell,
+ &RootKey->KeyCell->SecurityKeyOffset);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Copy the security descriptor */
+
+ CmiVolatileHive->RootSecurityCell = RootSecurityCell;
+#endif
- KeInitializeSpinLock(&CmiKeyListLock);
/* Create '\Registry\Machine' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*)&MachineKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- RootKey,
- MachineKey,
- L"Machine",
- wcslen(L"Machine") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- MachineKey->RegistryHive = CmiVolatileHive;
- MachineKey->Flags = 0;
- MachineKey->NumberOfSubKeys = 0;
- MachineKey->SubKeys = NULL;
- MachineKey->SizeOfSubKeys = MachineKey->KeyCell->NumberOfSubKeys;
- MachineKey->NameSize = strlen("Machine");
- MachineKey->Name = ExAllocatePool(PagedPool, MachineKey->NameSize);
- RtlCopyMemory(MachineKey->Name, "Machine", MachineKey->NameSize);
- CmiAddKeyToList(RootKey, MachineKey);
+ RtlInitUnicodeString(&KeyName,
+ L"Machine");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ 0,
+ RootKeyHandle,
+ NULL);
+ Status = ZwCreateKey(&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ ASSERT(NT_SUCCESS(Status));
/* Create '\Registry\User' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*)&UserKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- RootKey,
- UserKey,
- L"User",
- wcslen(L"User") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- UserKey->RegistryHive = CmiVolatileHive;
- UserKey->Flags = 0;
- UserKey->NumberOfSubKeys = 0;
- UserKey->SubKeys = NULL;
- UserKey->SizeOfSubKeys = UserKey->KeyCell->NumberOfSubKeys;
- UserKey->NameSize = strlen("User");
- UserKey->Name = ExAllocatePool(PagedPool, UserKey->NameSize);
- RtlCopyMemory(UserKey->Name, "User", UserKey->NameSize);
- CmiAddKeyToList(RootKey, UserKey);
+ RtlInitUnicodeString(&KeyName,
+ L"User");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ 0,
+ RootKeyHandle,
+ NULL);
+ Status = ZwCreateKey(&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE,
+ NULL);
+ ASSERT(NT_SUCCESS(Status));
}
-VOID
+VOID INIT_FUNCTION
CmInit2(PCHAR CommandLine)
{
- PCHAR p1, p2;
- ULONG PiceStart;
+ ULONG PiceStart = 4;
+ BOOLEAN MiniNT = FALSE;
+ PWCHAR SystemBootDevice;
+ PWCHAR SystemStartOptions;
+ ULONG Position;
NTSTATUS Status;
- /* FIXME: Store system start options */
-
-
-
/* Create the 'CurrentControlSet' link. */
Status = CmiCreateCurrentControlSetLink();
if (!NT_SUCCESS(Status))
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
+
+ /*
+ * Parse the system boot device.
+ */
+ Position = 0;
+ SystemBootDevice = ExAllocatePool(PagedPool,
+ (strlen(CommandLine) + 1) * sizeof(WCHAR));
+ if (SystemBootDevice == NULL)
+ {
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
+ }
+
+ while (*CommandLine != 0 && *CommandLine != ' ')
+ SystemBootDevice[Position++] = *(CommandLine++);
+ SystemBootDevice[Position++] = 0;
+
+ /*
+ * Write the system boot device to registry.
+ */
+ Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
+ L"SystemBootDevice",
+ REG_SZ,
+ SystemBootDevice,
+ Position * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
+ }
+
+ /*
+ * Parse the system start options.
+ */
+ Position = 0;
+ SystemStartOptions = SystemBootDevice;
+ while ((CommandLine = strchr(CommandLine, '/')) != NULL)
{
- KeBugCheck(CONFIG_INITIALIZATION_FAILED);
+ /* Skip over the slash */
+ CommandLine++;
+
+ /* Special options */
+ if (!_strnicmp(CommandLine, "MININT", 6))
+ MiniNT = TRUE;
+ else if (!_strnicmp(CommandLine, "DEBUGPORT=PICE", 14))
+ PiceStart = 1;
+
+ /* Add a space between the options */
+ if (Position != 0)
+ SystemStartOptions[Position++] = L' ';
+
+ /* Copy the command */
+ while (*CommandLine != 0 && *CommandLine != ' ')
+ SystemStartOptions[Position++] = *(CommandLine++);
}
-
- /* Set PICE 'Start' value to 1, if PICE debugging is enabled */
- PiceStart = 4;
- p1 = (PCHAR)CommandLine;
- while (p1 && (p2 = strchr(p1, '/')))
+ SystemStartOptions[Position++] = 0;
+
+ /*
+ * Write the system start options to registry.
+ */
+ Status = RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
+ L"\\Registry\\Machine\\System\\CurrentControlSet\\Control",
+ L"SystemStartOptions",
+ REG_SZ,
+ SystemStartOptions,
+ Position * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
+ }
+
+ /*
+ * Create a CurrentControlSet\Control\MiniNT key that is used
+ * to detect WinPE/MiniNT systems.
+ */
+ if (MiniNT)
{
- p2++;
- if (_strnicmp(p2, "DEBUGPORT", 9) == 0)
- {
- p2 += 9;
- if (*p2 == '=')
- {
- p2++;
- if (_strnicmp(p2, "PICE", 4) == 0)
- {
- p2 += 4;
- PiceStart = 1;
- }
- }
- }
- p1 = p2;
+ Status = RtlCreateRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT");
+ if (!NT_SUCCESS(Status))
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
}
- Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
- L"\\Pice",
- L"Start",
- REG_DWORD,
- &PiceStart,
- sizeof(ULONG));
+ /* Set PICE 'Start' value to 1, if PICE debugging is enabled */
+ Status = RtlWriteRegistryValue(
+ RTL_REGISTRY_SERVICES,
+ L"\\Pice",
+ L"Start",
+ REG_DWORD,
+ &PiceStart,
+ sizeof(ULONG));
if (!NT_SUCCESS(Status))
- {
- KeBugCheck(CONFIG_INITIALIZATION_FAILED);
- }
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
+
+ ExFreePool(SystemBootDevice);
}
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;
DPRINT("Link target '%S'\n", TargetNameBuffer);
- RtlInitUnicodeStringFromLiteral(&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,
NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("NtCreateKey() failed (Status %lx)\n", Status);
+ DPRINT1("ZwCreateKey() failed (Status %lx)\n", Status);
return(Status);
}
- RtlInitUnicodeStringFromLiteral(&LinkValue,
- L"SymbolicLinkValue");
- Status = NtSetValueKey(KeyHandle,
+ Status = ZwSetValueKey(KeyHandle,
&LinkValue,
0,
REG_LINK,
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);
+ return Status;
}
NTSTATUS
-CmiConnectHive(PREGISTRY_HIVE RegistryHive,
- PUNICODE_STRING KeyName)
+CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN PREGISTRY_HIVE RegistryHive)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING ParentKeyName;
+ UNICODE_STRING RemainingPath;
PKEY_OBJECT ParentKey;
PKEY_OBJECT NewKey;
- HANDLE KeyHandle;
NTSTATUS Status;
PWSTR SubName;
+ UNICODE_STRING ObjectName;
+ OBJECT_CREATE_INFORMATION ObjectCreateInfo;
+
+ DPRINT("CmiConnectHive(%p, %p) called.\n",
+ KeyObjectAttributes, RegistryHive);
+
+ /* 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;
+ }
- DPRINT("CmiConnectHive(%p, %wZ) called.\n",
- RegistryHive, KeyName);
+ DPRINT ("RemainingPath %wZ\n", &RemainingPath);
- SubName = wcsrchr (KeyName->Buffer, L'\\');
- if (SubName == NULL)
+ if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0))
{
- return STATUS_UNSUCCESSFUL;
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_OBJECT_NAME_COLLISION;
}
- ParentKeyName.Length = (USHORT)(SubName - KeyName->Buffer) * sizeof(WCHAR);
- ParentKeyName.MaximumLength = ParentKeyName.Length + sizeof(WCHAR);
- ParentKeyName.Buffer = ExAllocatePool (NonPagedPool,
- ParentKeyName.MaximumLength);
- RtlCopyMemory (ParentKeyName.Buffer,
- KeyName->Buffer,
- ParentKeyName.Length);
- ParentKeyName.Buffer[ParentKeyName.Length / sizeof(WCHAR)] = 0;
- SubName++;
-
- Status = ObReferenceObjectByName (&ParentKeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- STANDARD_RIGHTS_REQUIRED,
- CmiKeyType,
- KernelMode,
- NULL,
- (PVOID*)&ParentKey);
- RtlFreeUnicodeString (&ParentKeyName);
- if (!NT_SUCCESS(Status))
+ /* Ignore leading backslash */
+ SubName = RemainingPath.Buffer;
+ if (*SubName == L'\\')
+ SubName++;
+
+ /* If RemainingPath contains \ we must return error
+ because CmiConnectHive() can not create trees */
+ if (wcschr (SubName, L'\\') != NULL)
{
- DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
- return Status;
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
}
- InitializeObjectAttributes(&ObjectAttributes,
- KeyName,
- 0,
- NULL,
- NULL);
+ DPRINT("RemainingPath %wZ ParentKey %p\n",
+ &RemainingPath, ParentKey);
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- &ObjectAttributes,
+ Status = ObCreateObject(KernelMode,
CmiKeyType,
+ NULL,
+ KernelMode,
+ NULL,
+ sizeof(KEY_OBJECT),
+ 0,
+ 0,
(PVOID*)&NewKey);
+
if (!NT_SUCCESS(Status))
{
DPRINT1 ("ObCreateObject() failed (Status %lx)\n", Status);
ObDereferenceObject (ParentKey);
+ 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->BlockOffset = RegistryHive->HiveHeader->RootKeyCell;
- NewKey->KeyCell = CmiGetBlock(RegistryHive, NewKey->BlockOffset, NULL);
+ NewKey->KeyCellOffset = RegistryHive->HiveHeader->RootKeyOffset;
+ NewKey->KeyCell = CmiGetCell (RegistryHive, NewKey->KeyCellOffset, NULL);
NewKey->Flags = 0;
NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = ExAllocatePool(PagedPool,
- NewKey->KeyCell->NumberOfSubKeys * sizeof(ULONG));
-
- if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
+ InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
+ if (NewKey->KeyCell->NumberOfSubKeys != 0)
{
- DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
- NtClose(NewKey);
- ObDereferenceObject (ParentKey);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ NewKey->SubKeys = ExAllocatePool(NonPagedPool,
+ NewKey->KeyCell->NumberOfSubKeys * sizeof(ULONG));
+ if (NewKey->SubKeys == NULL)
+ {
+ DPRINT("ExAllocatePool() failed\n");
+ ObDereferenceObject (NewKey);
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ }
+ else
+ {
+ NewKey->SubKeys = NULL;
}
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->NameSize = wcslen (SubName);
- NewKey->Name = ExAllocatePool(PagedPool, NewKey->NameSize);
+ DPRINT ("SubName %S\n", SubName);
- if ((NewKey->Name == NULL) && (NewKey->NameSize != 0))
+ Status = RtlpCreateUnicodeString(&NewKey->Name,
+ SubName, NonPagedPool);
+ RtlFreeUnicodeString(&RemainingPath);
+ if (!NT_SUCCESS(Status))
{
- DPRINT("NewKey->NameSize %d\n", NewKey->NameSize);
+ DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
if (NewKey->SubKeys != NULL)
- ExFreePool(NewKey->SubKeys);
- NtClose(KeyHandle);
+ {
+ ExFreePool (NewKey->SubKeys);
+ }
+ ObDereferenceObject (NewKey);
ObDereferenceObject (ParentKey);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- wcstombs (NewKey->Name,
- SubName,
- NewKey->NameSize);
-
CmiAddKeyToList (ParentKey, NewKey);
ObDereferenceObject (ParentKey);
VERIFY_KEY_OBJECT(NewKey);
- return(STATUS_SUCCESS);
+ /* Note: Do not dereference NewKey here! */
+
+ return STATUS_SUCCESS;
}
-static NTSTATUS
-CmiInitializeSystemHive (PWSTR FileName,
- PUNICODE_STRING KeyName)
+NTSTATUS
+CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ OUT PREGISTRY_HIVE *RegistryHive)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING ControlSetKeyName;
- UNICODE_STRING ControlSetLinkName;
- UNICODE_STRING ControlSetValueName;
+ PKEY_OBJECT KeyObject;
+ PREGISTRY_HIVE Hive;
HANDLE KeyHandle;
NTSTATUS Status;
- PREGISTRY_HIVE RegistryHive;
+ PLIST_ENTRY CurrentEntry;
+ PKEY_OBJECT CurrentKey;
- Status = CmiCreateRegistryHive (FileName,
- &RegistryHive,
- TRUE);
+ DPRINT("CmiDisconnectHive() called\n");
+
+ *RegistryHive = NULL;
+
+ Status = ObOpenObjectByName (KeyObjectAttributes,
+ CmiKeyType,
+ NULL,
+ KernelMode,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ &KeyHandle);
if (!NT_SUCCESS(Status))
{
- DPRINT1 ("CmiCreateRegistryHive() failed (Status %lx)\n", Status);
+ DPRINT1 ("ObOpenObjectByName() failed (Status %lx)\n", Status);
return Status;
}
- Status = CmiConnectHive (RegistryHive,
- KeyName);
+ Status = ObReferenceObjectByHandle (KeyHandle,
+ STANDARD_RIGHTS_REQUIRED,
+ CmiKeyType,
+ KernelMode,
+ (PVOID*)&KeyObject,
+ NULL);
+ ZwClose (KeyHandle);
if (!NT_SUCCESS(Status))
{
- DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
- CmiRemoveRegistryHive (RegistryHive);
+ DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
return Status;
}
+ DPRINT ("KeyObject %p Hive %p\n", KeyObject, KeyObject->RegistryHive);
+
+ if (!(KeyObject->KeyCell->Flags & REG_KEY_ROOT_CELL))
+ {
+ DPRINT1 ("Key is not the Hive-Root-Key\n");
+ ObDereferenceObject (KeyObject);
+ 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 (hc %d, rc %d)\n", ObGetObjectHandleCount (KeyObject), ObGetObjectPointerCount (KeyObject));
+ ObDereferenceObject (KeyObject);
+
+ /* Release registry lock */
+ ExReleaseResourceLite (&CmiRegistryLock);
+ KeLeaveCriticalRegion();
+
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ Hive = KeyObject->RegistryHive;
+
+ /* Dereference KeyObject twice to delete it */
+ ObDereferenceObject (KeyObject);
+ ObDereferenceObject (KeyObject);
+
+ *RegistryHive = Hive;
+
+ /* Release registry lock */
+ ExReleaseResourceLite (&CmiRegistryLock);
+ KeLeaveCriticalRegion();
+
+ DPRINT ("CmiDisconnectHive() done\n");
+
+ return STATUS_SUCCESS;
+}
+
+
+static NTSTATUS
+CmiInitControlSetLink (VOID)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ 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 */
- RtlInitUnicodeStringFromLiteral (&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,
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 */
- RtlInitUnicodeStringFromLiteral (&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,
NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1 ("NtCreateKey() failed (Status %lx)\n", Status);
+ DPRINT1 ("ZwCreateKey() failed (Status %lx)\n", Status);
return Status;
}
- RtlInitUnicodeStringFromLiteral (&ControlSetValueName,
- L"SymbolicLinkValue");
- Status = NtSetValueKey (KeyHandle,
+ Status = ZwSetValueKey (KeyHandle,
&ControlSetValueName,
0,
REG_LINK,
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;
}
-NTSTATUS
-CmiInitializeHive(PWSTR FileName,
- PUNICODE_STRING KeyName,
- BOOLEAN CreateNew)
-{
- PREGISTRY_HIVE RegistryHive;
- NTSTATUS Status;
-
- DPRINT("CmiInitializeHive(%s) called\n", KeyName);
-
- Status = CmiCreateRegistryHive(FileName,
- &RegistryHive,
- CreateNew);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status);
-
- /* FIXME: Try to load the backup hive */
-
- KeBugCheck(0);
- return(Status);
- }
-
- /* Connect the hive */
- Status = CmiConnectHive(RegistryHive,
- KeyName);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiConnectHive() failed (Status %lx)\n", Status);
- CmiRemoveRegistryHive(RegistryHive);
- return(Status);
- }
-
- DPRINT("CmiInitializeHive() done\n");
-
- return(STATUS_SUCCESS);
-}
-
-
NTSTATUS
CmiInitHives(BOOLEAN SetupBoot)
{
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING KeyName;
- UNICODE_STRING ValueName;
+ UNICODE_STRING FileName;
+ UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE");
+ UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath");
HANDLE KeyHandle;
NTSTATUS Status;
if (SetupBoot == TRUE)
{
- RtlInitUnicodeStringFromLiteral(&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);
}
- RtlInitUnicodeStringFromLiteral(&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);
RtlInitUnicodeString (&KeyName,
REG_SYSTEM_KEY_NAME);
- Status = CmiInitializeSystemHive (ConfigPath,
- &KeyName);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
{
- DPRINT1("CmiInitializeSystemHive() failed (Status %lx)\n", Status);
+ DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ Status = CmiInitControlSetLink ();
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitControlSetLink() failed (Status %lx)\n", Status);
return(Status);
}
}
/* Connect the SOFTWARE hive */
wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
RtlInitUnicodeString (&KeyName,
REG_SOFTWARE_KEY_NAME);
- Status = CmiInitializeHive(ConfigPath,
+ InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- SetupBoot);
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
/* Connect the SAM hive */
wcscpy(EndPtr, REG_SAM_FILE_NAME);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
RtlInitUnicodeString (&KeyName,
REG_SAM_KEY_NAME);
- Status = CmiInitializeHive(ConfigPath,
+ InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- SetupBoot);
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
/* Connect the SECURITY hive */
wcscpy(EndPtr, REG_SEC_FILE_NAME);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
RtlInitUnicodeString (&KeyName,
REG_SEC_KEY_NAME);
- Status = CmiInitializeHive(ConfigPath,
+ InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- SetupBoot);
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
}
/* Connect the DEFAULT hive */
- wcscpy(EndPtr, REG_USER_FILE_NAME);
+ wcscpy(EndPtr, REG_DEFAULT_USER_FILE_NAME);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
RtlInitUnicodeString (&KeyName,
- REG_USER_KEY_NAME);
- Status = CmiInitializeHive(ConfigPath,
+ REG_DEFAULT_USER_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
&KeyName,
- SetupBoot);
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
PREGISTRY_HIVE Hive;
PLIST_ENTRY Entry;
- DPRINT1("CmShutdownRegistry() called\n");
+ DPRINT("CmShutdownRegistry() called\n");
/* Stop automatic hive synchronization */
CmiHiveSyncEnabled = FALSE;
+ /* Cancel pending hive synchronization */
+ if (CmiHiveSyncPending == TRUE)
+ {
+ KeCancelTimer(&CmiHiveSyncTimer);
+ CmiHiveSyncPending = FALSE;
+ }
+
/* Acquire hive list lock exclusively */
- ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
Entry = CmiHiveListHead.Flink;
while (Entry != &CmiHiveListHead)
{
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
- if (!IsVolatileHive(Hive))
+ 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();
- DPRINT1("CmShutdownRegistry() done\n");
+ DPRINT("CmShutdownRegistry() done\n");
}
CmiHiveSyncPending = FALSE;
/* Acquire hive list lock exclusively */
- ExAcquireResourceExclusiveLite(&CmiHiveListLock, TRUE);
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
Entry = CmiHiveListHead.Flink;
while (Entry != &CmiHiveListHead)
{
Hive = CONTAINING_RECORD(Entry, REGISTRY_HIVE, HiveList);
- if (!IsVolatileHive(Hive))
+ 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");
CmiHiveSyncRoutine,
WorkQueueItem);
- DPRINT("DeferredContext %x\n", WorkQueueItem);
+ DPRINT("DeferredContext 0x%p\n", WorkQueueItem);
ExQueueWorkItem(WorkQueueItem,
CriticalWorkQueue);
}
CmiHiveSyncPending = TRUE;
-
- Timeout.QuadPart = -50000000LL;
+ Timeout.QuadPart = (LONGLONG)-50000000;
KeSetTimer(&CmiHiveSyncTimer,
Timeout,
&CmiHiveSyncDpc);