-/* $Id: registry.c,v 1.83 2003/02/10 21:24:45 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
*/
-#ifdef WIN32_REGDBG
-#include "cm_win32.h"
-#else
-#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
-/* ------------------------------------------------- File Statics */
+
+/* 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;
KDPC CmiHiveSyncDpc;
KTIMER CmiHiveSyncTimer;
-static PKEY_OBJECT CmiRootKey = NULL;
-static PKEY_OBJECT CmiMachineKey = NULL;
-static PKEY_OBJECT CmiUserKey = NULL;
-static PKEY_OBJECT CmiHardwareKey = NULL;
-
static GENERIC_MAPPING CmiKeyMapping =
{KEY_READ, KEY_WRITE, KEY_EXECUTE, KEY_ALL_ACCESS};
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;
+#if 0
+ PSECURITY_CELL RootSecurityCell;
+#endif
HANDLE RootKeyHandle;
- PKEY_OBJECT NewKey;
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 = NULL;
- 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 *) &NewKey);
- assert(NT_SUCCESS(Status));
- CmiRootKey = NewKey;
- Status = ObReferenceObjectByHandle(RootKeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- CmiKeyType,
- KernelMode,
- (PVOID *) &CmiRootKey,
- NULL);
- assert(NT_SUCCESS(Status));
- CmiRootKey->RegistryHive = CmiVolatileHive;
- NewKey->BlockOffset = CmiVolatileHive->HiveHeader->RootKeyCell;
- NewKey->KeyCell = CmiGetBlock(CmiVolatileHive, NewKey->BlockOffset, NULL);
- CmiRootKey->Flags = 0;
- CmiRootKey->NumberOfSubKeys = 0;
- CmiRootKey->SubKeys = NULL;
- CmiRootKey->SizeOfSubKeys = 0;
- CmiRootKey->Name = ExAllocatePool(PagedPool, strlen("Registry"));
- CmiRootKey->NameSize = strlen("Registry");
- memcpy(CmiRootKey->Name, "Registry", strlen("Registry"));
-
- KeInitializeSpinLock(&CmiKeyListLock);
-
- /* Create initial predefined symbolic links */
+ 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->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;
+ 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
+
/* Create '\Registry\Machine' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*) &NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiRootKey,
- NewKey,
- L"Machine",
- wcslen(L"Machine") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("Machine"));
- NewKey->NameSize = strlen("Machine");
- memcpy(NewKey->Name, "Machine", strlen("Machine"));
- CmiAddKeyToList(CmiRootKey, NewKey);
- CmiMachineKey = NewKey;
+ 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*) &NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiRootKey,
- NewKey,
- L"User",
- wcslen(L"User") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("User"));
- NewKey->NameSize = strlen("User");
- memcpy(NewKey->Name, "User", strlen("User"));
- CmiAddKeyToList(CmiRootKey, NewKey);
- CmiUserKey = NewKey;
-
- /* Create '\Registry\Machine\HARDWARE' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*)&NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiMachineKey,
- NewKey,
- L"HARDWARE",
- wcslen(L"HARDWARE") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("HARDWARE"));
- NewKey->NameSize = strlen("HARDWARE");
- memcpy(NewKey->Name, "HARDWARE", strlen("HARDWARE"));
- CmiAddKeyToList(CmiMachineKey, NewKey);
- CmiHardwareKey = NewKey;
-
- /* Create '\Registry\Machine\HARDWARE\DESCRIPTION' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*) &NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiHardwareKey,
- NewKey,
- L"DESCRIPTION",
- wcslen(L"DESCRIPTION") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("DESCRIPTION"));
- NewKey->NameSize = strlen("DESCRIPTION");
- memcpy(NewKey->Name, "DESCRIPTION", strlen("DESCRIPTION"));
- CmiAddKeyToList(CmiHardwareKey, NewKey);
-
- /* Create '\Registry\Machine\HARDWARE\DEVICEMAP' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*) &NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiHardwareKey,
- NewKey,
- L"DEVICEMAP",
- wcslen(L"DEVICEMAP") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("DEVICEMAP"));
- NewKey->NameSize = strlen("DEVICEMAP");
- memcpy(NewKey->Name, "DEVICEMAP", strlen("DEVICEMAP"));
- CmiAddKeyToList(CmiHardwareKey,NewKey);
-
- /* Create '\Registry\Machine\HARDWARE\RESOURCEMAP' key. */
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- NULL,
- CmiKeyType,
- (PVOID*) &NewKey);
- assert(NT_SUCCESS(Status));
- Status = CmiAddSubKey(CmiVolatileHive,
- CmiHardwareKey,
- NewKey,
- L"RESOURCEMAP",
- wcslen(L"RESOURCEMAP") * sizeof(WCHAR),
- 0,
- NULL,
- 0);
- assert(NT_SUCCESS(Status));
- NewKey->RegistryHive = CmiVolatileHive;
- NewKey->Flags = 0;
- NewKey->NumberOfSubKeys = 0;
- NewKey->SubKeys = NULL;
- NewKey->SizeOfSubKeys = NewKey->KeyCell->NumberOfSubKeys;
- NewKey->Name = ExAllocatePool(PagedPool, strlen("RESOURCEMAP"));
- NewKey->NameSize = strlen("RESOURCEMAP");
- memcpy(NewKey->Name, "RESOURCEMAP", strlen("RESOURCEMAP"));
- CmiAddKeyToList(CmiHardwareKey, NewKey);
-
- /* FIXME: create remaining structure needed for default handles */
- /* FIXME: load volatile registry data from ROSDTECT */
+ 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();
-#ifndef WIN32_REGDBG
if (!NT_SUCCESS(Status))
- {
- KeBugCheck(CONFIG_INITIALIZATION_FAILED);
- }
-#endif
+ 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);
+ }
- /* Set PICE 'Start' value to 1, if PICE debugging is enabled */
- PiceStart = 4;
- p1 = (PCHAR)CommandLine;
- while (p1 && (p2 = strchr(p1, '/')))
+ 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)
{
- p2++;
- if (_strnicmp(p2, "DEBUGPORT", 9) == 0)
- {
- p2 += 9;
- if (*p2 == '=')
- {
- p2++;
- if (_strnicmp(p2, "PICE", 4) == 0)
- {
- p2 += 4;
- PiceStart = 1;
- }
- }
- }
- p1 = p2;
+ /* 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++);
}
-#ifndef WIN32_REGDBG
- Status = RtlWriteRegistryValue(RTL_REGISTRY_SERVICES,
- L"\\Pice",
- L"Start",
- REG_DWORD,
- &PiceStart,
- sizeof(ULONG));
+ 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)
{
- KeBugCheck(CONFIG_INITIALIZATION_FAILED);
+ Status = RtlCreateRegistryKey(RTL_REGISTRY_CONTROL, L"MiniNT");
+ if (!NT_SUCCESS(Status))
+ KEBUGCHECK(CONFIG_INITIALIZATION_FAILED);
}
-#endif
+
+ /* 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);
+
+ 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(PWSTR FileName,
- PWSTR FullName,
- PCHAR KeyName,
- PKEY_OBJECT Parent,
- BOOLEAN CreateNew)
+CmiConnectHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN PREGISTRY_HIVE RegistryHive)
{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PREGISTRY_HIVE RegistryHive = NULL;
- UNICODE_STRING uKeyName;
+ 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(%S, %S, %s, %p, %d) - Called.\n", FileName, FullName, KeyName, Parent, CreateNew);
+ DPRINT ("RemainingPath %wZ\n", &RemainingPath);
- Status = CmiCreateRegistryHive(FileName, &RegistryHive, CreateNew);
- if (!NT_SUCCESS(Status))
+ if ((RemainingPath.Buffer == NULL) || (RemainingPath.Buffer[0] == 0))
{
- DPRINT1("CmiCreateRegistryHive() failed (Status %lx)\n", Status);
- KeBugCheck(0);
- return(Status);
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_OBJECT_NAME_COLLISION;
}
- RtlInitUnicodeString(&uKeyName, FullName);
+ /* Ignore leading backslash */
+ SubName = RemainingPath.Buffer;
+ if (*SubName == L'\\')
+ SubName++;
- InitializeObjectAttributes(&ObjectAttributes,
- &uKeyName,
- 0,
- NULL,
- NULL);
+ /* If RemainingPath contains \ we must return error
+ because CmiConnectHive() can not create trees */
+ if (wcschr (SubName, L'\\') != NULL)
+ {
+ ObDereferenceObject (ParentKey);
+ RtlFreeUnicodeString(&RemainingPath);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
- Status = ObCreateObject(&KeyHandle,
- STANDARD_RIGHTS_REQUIRED,
- &ObjectAttributes,
+ DPRINT("RemainingPath %wZ ParentKey %p\n",
+ &RemainingPath, ParentKey);
+
+ 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);
- KeBugCheck(0);
- CmiRemoveRegistryHive(RegistryHive);
- return(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(DWORD));
-
- if ((NewKey->SubKeys == NULL) && (NewKey->KeyCell->NumberOfSubKeys != 0))
+ InsertTailList(&CmiKeyObjectListHead, &NewKey->ListEntry);
+ if (NewKey->KeyCell->NumberOfSubKeys != 0)
{
- DPRINT("NumberOfSubKeys %d\n", NewKey->KeyCell->NumberOfSubKeys);
- ZwClose(NewKey);
- CmiRemoveRegistryHive(RegistryHive);
- 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->Name = ExAllocatePool(PagedPool, strlen(KeyName));
+ DPRINT ("SubName %S\n", SubName);
- if ((NewKey->Name == NULL) && (strlen(KeyName) != 0))
+ Status = RtlpCreateUnicodeString(&NewKey->Name,
+ SubName, NonPagedPool);
+ RtlFreeUnicodeString(&RemainingPath);
+ if (!NT_SUCCESS(Status))
{
- DPRINT("strlen(KeyName) %d\n", strlen(KeyName));
+ DPRINT1("RtlpCreateUnicodeString() failed (Status %lx)\n", Status);
if (NewKey->SubKeys != NULL)
- ExFreePool(NewKey->SubKeys);
- ZwClose(NewKey);
- CmiRemoveRegistryHive(RegistryHive);
- return(STATUS_INSUFFICIENT_RESOURCES);
+ {
+ ExFreePool (NewKey->SubKeys);
+ }
+ ObDereferenceObject (NewKey);
+ ObDereferenceObject (ParentKey);
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- NewKey->NameSize = strlen(KeyName);
- memcpy(NewKey->Name, KeyName, strlen(KeyName));
- CmiAddKeyToList(Parent, NewKey);
+ CmiAddKeyToList (ParentKey, NewKey);
+ ObDereferenceObject (ParentKey);
VERIFY_KEY_OBJECT(NewKey);
- return(STATUS_SUCCESS);
+ /* Note: Do not dereference NewKey here! */
+
+ return STATUS_SUCCESS;
}
NTSTATUS
-CmiInitializeHive(PWSTR FileName,
- PWSTR FullName,
- PCHAR KeyName,
- PKEY_OBJECT Parent,
- BOOLEAN CreateNew)
+CmiDisconnectHive (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ OUT PREGISTRY_HIVE *RegistryHive)
{
+ PKEY_OBJECT KeyObject;
+ PREGISTRY_HIVE Hive;
+ HANDLE KeyHandle;
NTSTATUS Status;
+ PLIST_ENTRY CurrentEntry;
+ PKEY_OBJECT CurrentKey;
- DPRINT("CmiInitializeHive(%s) called\n", KeyName);
+ DPRINT("CmiDisconnectHive() called\n");
- /* Try to connect the hive */
- //Status = CmiConnectHive(FileName, FullName, KeyName, Parent, FALSE);
- Status = CmiConnectHive(FileName, FullName, KeyName, Parent, CreateNew);
+ *RegistryHive = NULL;
+ Status = ObOpenObjectByName (KeyObjectAttributes,
+ CmiKeyType,
+ NULL,
+ KernelMode,
+ STANDARD_RIGHTS_REQUIRED,
+ NULL,
+ &KeyHandle);
if (!NT_SUCCESS(Status))
{
-#if 0
-#ifdef WIN32_REGDBG
- WCHAR AltFileName[MAX_PATH];
+ DPRINT1 ("ObOpenObjectByName() failed (Status %lx)\n", Status);
+ return Status;
+ }
- CPRINT("WARNING! Registry file %S not found\n", FileName);
- //DPRINT("Status %.08x\n", Status);
+ Status = ObReferenceObjectByHandle (KeyHandle,
+ STANDARD_RIGHTS_REQUIRED,
+ CmiKeyType,
+ KernelMode,
+ (PVOID*)&KeyObject,
+ NULL);
+ ZwClose (KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ObReferenceObjectByName() failed (Status %lx)\n", Status);
+ return Status;
+ }
+ DPRINT ("KeyObject %p Hive %p\n", KeyObject, KeyObject->RegistryHive);
- wcscpy(AltFileName, FileName);
- wcscat(AltFileName, L".alt");
+ if (!(KeyObject->KeyCell->Flags & REG_KEY_ROOT_CELL))
+ {
+ DPRINT1 ("Key is not the Hive-Root-Key\n");
+ ObDereferenceObject (KeyObject);
+ return STATUS_INVALID_PARAMETER;
+ }
- DPRINT("Attempting to connect the alternative hive %S\n", AltFileName);
- /* Try to connect the alternative hive */
- Status = CmiConnectHive(AltFileName, FullName, KeyName, Parent, TRUE);
+ /* Acquire registry lock exclusively */
+ KeEnterCriticalRegion();
+ ExAcquireResourceExclusiveLite(&CmiRegistryLock, TRUE);
- if (!NT_SUCCESS(Status)) {
- CPRINT("WARNING! Alternative registry file %S not found\n", AltFileName);
- //DPRINT("Status %.08x\n", Status);
- }
-#endif
-#endif
+ 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;
}
- DPRINT("CmiInitializeHive() done\n");
+ Hive = KeyObject->RegistryHive;
+
+ /* Dereference KeyObject twice to delete it */
+ ObDereferenceObject (KeyObject);
+ ObDereferenceObject (KeyObject);
- return(Status);
+ *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 */
+ InitializeObjectAttributes (&ObjectAttributes,
+ &ControlSetKeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwCreateKey (&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ZwCreateKey() failed (Status %lx)\n", Status);
+ return Status;
+ }
+ ZwClose (KeyHandle);
+
+ /* Link 'CurrentControlSet' to 'ControlSet001' key */
+ InitializeObjectAttributes (&ObjectAttributes,
+ &ControlSetLinkName,
+ OBJ_CASE_INSENSITIVE | OBJ_OPENIF | OBJ_OPENLINK,
+ NULL,
+ NULL);
+ Status = ZwCreateKey (&KeyHandle,
+ KEY_ALL_ACCESS | KEY_CREATE_LINK,
+ &ObjectAttributes,
+ 0,
+ NULL,
+ REG_OPTION_VOLATILE | REG_OPTION_CREATE_LINK,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ZwCreateKey() failed (Status %lx)\n", Status);
+ return Status;
+ }
+
+ Status = ZwSetValueKey (KeyHandle,
+ &ControlSetValueName,
+ 0,
+ REG_LINK,
+ (PVOID)ControlSetKeyName.Buffer,
+ ControlSetKeyName.Length);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("ZwSetValueKey() failed (Status %lx)\n", Status);
+ }
+ ZwClose (KeyHandle);
+
+ return STATUS_SUCCESS;
}
NTSTATUS
-CmiInitHives(BOOLEAN SetUpBoot)
+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;
DPRINT("CmiInitHives() called\n");
- if (SetUpBoot == TRUE)
- {
- RtlInitUnicodeStringFromLiteral(&KeyName,
- L"\\Registry\\Machine\\HARDWARE");
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
- Status = NtOpenKey(&KeyHandle,
- KEY_ALL_ACCESS,
- &ObjectAttributes);
- if (!NT_SUCCESS(Status))
+ if (SetupBoot == TRUE)
{
- DPRINT1("NtOpenKey() failed (Status %lx)\n", Status);
- return(Status);
- }
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = ZwOpenKey(&KeyHandle,
+ KEY_ALL_ACCESS,
+ &ObjectAttributes);
+ if (!NT_SUCCESS(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)
+ {
+ ZwClose(KeyHandle);
+ return(STATUS_INSUFFICIENT_RESOURCES);
+ }
- BufferSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 4096;
- ValueInfo = ExAllocatePool(PagedPool,
- BufferSize);
- if (ValueInfo == NULL)
- {
- NtClose(KeyHandle);
- return(STATUS_INSUFFICIENT_RESOURCES);
- }
+ Status = ZwQueryValueKey(KeyHandle,
+ &ValueName,
+ KeyValuePartialInformation,
+ ValueInfo,
+ BufferSize,
+ &ResultSize);
+ ZwClose(KeyHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(ValueInfo);
+ return(Status);
+ }
- Status = NtQueryValueKey(KeyHandle,
- &ValueName,
- KeyValuePartialInformation,
- ValueInfo,
- BufferSize,
- &ResultSize);
- NtClose(KeyHandle);
- if (ValueInfo == NULL)
- {
+ RtlCopyMemory(ConfigPath,
+ ValueInfo->Data,
+ ValueInfo->DataLength);
+ ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0;
ExFreePool(ValueInfo);
- return(Status);
}
-
- RtlCopyMemory(ConfigPath,
- ValueInfo->Data,
- ValueInfo->DataLength);
- ConfigPath[ValueInfo->DataLength / sizeof(WCHAR)] = (WCHAR)0;
- ExFreePool(ValueInfo);
- }
else
- {
- wcscpy(ConfigPath, L"\\SystemRoot");
- }
+ {
+ wcscpy(ConfigPath, L"\\SystemRoot");
+ }
wcscat(ConfigPath, L"\\system32\\config");
DPRINT("ConfigPath: %S\n", ConfigPath);
/* FIXME: Save boot log */
- /* FIXME: Rename \Registry\Machine\System */
+ /* Connect the SYSTEM hive only if it has been created */
+ if (SetupBoot == TRUE)
+ {
+ wcscpy(EndPtr, REG_SYSTEM_FILE_NAME);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
- /* Connect the SYSTEM hive */
-// Status = CmiInitializeHive(SYSTEM_REG_FILE, REG_SYSTEM_KEY_NAME, "System", CmiMachineKey, SetUpBoot);
-// assert(NT_SUCCESS(Status));
+ RtlInitUnicodeString (&KeyName,
+ REG_SYSTEM_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- /* FIXME: Synchronize old and new system hive (??) */
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
+ return Status;
+ }
- /* FIXME: Delete old system hive */
+ 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);
- DPRINT1("ConfigPath: %S\n", ConfigPath);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
+
+ RtlInitUnicodeString (&KeyName,
+ REG_SOFTWARE_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
- Status = CmiInitializeHive(ConfigPath,
- REG_SOFTWARE_KEY_NAME,
- "Software",
- CmiMachineKey,
- SetUpBoot);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
- return(Status);
- }
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ return(Status);
+ }
/* Connect the SAM hive */
wcscpy(EndPtr, REG_SAM_FILE_NAME);
- DPRINT1("ConfigPath: %S\n", ConfigPath);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
- Status = CmiInitializeHive(ConfigPath,
- REG_SAM_KEY_NAME,
- "Sam",
- CmiMachineKey,
- SetUpBoot);
+ RtlInitUnicodeString (&KeyName,
+ REG_SAM_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
- return(Status);
- }
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ return(Status);
+ }
/* Connect the SECURITY hive */
wcscpy(EndPtr, REG_SEC_FILE_NAME);
- DPRINT1("ConfigPath: %S\n", ConfigPath);
- Status = CmiInitializeHive(ConfigPath,
- REG_SEC_KEY_NAME,
- "Security",
- CmiMachineKey,
- SetUpBoot);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
+
+ RtlInitUnicodeString (&KeyName,
+ REG_SEC_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
- return(Status);
- }
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ return(Status);
+ }
/* Connect the DEFAULT hive */
- wcscpy(EndPtr, REG_USER_FILE_NAME);
- DPRINT1("ConfigPath: %S\n", ConfigPath);
-
- Status = CmiInitializeHive(ConfigPath,
- REG_USER_KEY_NAME,
- ".Default",
- CmiUserKey,
- SetUpBoot);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
- return(Status);
- }
+ wcscpy(EndPtr, REG_DEFAULT_USER_FILE_NAME);
+ RtlInitUnicodeString (&FileName,
+ ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
- /* FIXME : initialize standards symbolic links */
+ RtlInitUnicodeString (&KeyName,
+ REG_DEFAULT_USER_KEY_NAME);
+ InitializeObjectAttributes(&ObjectAttributes,
+ &KeyName,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+ Status = CmiLoadHive (&ObjectAttributes,
+ &FileName,
+ 0);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("CmiInitializeHive() failed (Status %lx)\n", Status);
+ return(Status);
+ }
// CmiCheckRegistry(TRUE);
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 (IsPermanentHive(Hive))
+ if (!(IsNoFileHive(Hive) || IsNoSynchHive(Hive)))
{
- /* Acquire hive resource exclusively */
- ExAcquireResourceExclusiveLite(&Hive->HiveResource,
- TRUE);
-
/* Flush non-volatile hive */
CmiFlushRegistryHive(Hive);
-
- /* Dereference file */
- ObDereferenceObject(Hive->FileObject);
- Hive->FileObject = NULL;
-
- /* 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");
}
PREGISTRY_HIVE Hive;
PLIST_ENTRY Entry;
- DPRINT1("CmiHiveSyncRoutine() called\n");
+ DPRINT("CmiHiveSyncRoutine() called\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 (IsPermanentHive(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);