Author: fireball
Date: Thu Nov 22 21:38:32 2007
New Revision: 30680
URL:
http://svn.reactos.org/svn/reactos?rev=30680&view=rev
Log:
- Fix prototype of NtLoadKeyEx.
- Refactor CmiLoadHives using new config routines instead of deprecated cm routines.
- Stop using deprecated CmiScanKeyForValue (delete regfile.c as a result).
- Add code for parallel hive loading to speed up boot process, but don't yet fully use
it due to changes required in linking hives.
- Add code for new hive linking process (CmpCreateLinkNode/CmpDoOpen). Not yet used to
avoid too many changes in one patch.
- Add new code in CmiLoadHives to deal with updated linking process when it becomes used.
- Implement NtLoadKey2 to cal NtLoadKeyEx.
- Implement NtLoadKeyEx as a new config routine, using CmLoadKey, move out of Cm.
- Add some more code in CmpInitializeSystemHive to deal with SYSTEM hive creation during
setup, once hive linking is refactored.
- Implement a new command except for flushing -- open: CmpCmdHiveOpen. Used by CmLoadKey.
- Add support for impersonating the SYSTEM account if the hive can't be open in the
current client security context.
- Fill out CmpMachineHiveList, to be used in parallel hive loading.
Removed:
trunk/reactos/ntoskrnl/cm/regfile.c
Modified:
trunk/reactos/include/ndk/cmfuncs.h
trunk/reactos/ntoskrnl/cm/ntfunc.c
trunk/reactos/ntoskrnl/cm/registry.c
trunk/reactos/ntoskrnl/cm/regobj.c
trunk/reactos/ntoskrnl/config/cm.h
trunk/reactos/ntoskrnl/config/cmapi.c
trunk/reactos/ntoskrnl/config/cmdata.c
trunk/reactos/ntoskrnl/config/cmlazy.c
trunk/reactos/ntoskrnl/config/cmparse.c
trunk/reactos/ntoskrnl/config/cmsysini.c
trunk/reactos/ntoskrnl/config/ntapi.c
trunk/reactos/ntoskrnl/ntoskrnl.rbuild
trunk/reactos/ntoskrnl/sysfuncs.lst
Modified: trunk/reactos/include/ndk/cmfuncs.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/cmfuncs.h?rev=…
==============================================================================
--- trunk/reactos/include/ndk/cmfuncs.h (original)
+++ trunk/reactos/include/ndk/cmfuncs.h Thu Nov 22 21:38:32 2007
@@ -139,10 +139,7 @@
IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile,
IN ULONG Flags,
- IN HANDLE TrustClassKey,
- IN HANDLE Event,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE RootHandle
+ IN HANDLE TrustClassKey
);
NTSTATUS
Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=3…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/ntfunc.c (original)
+++ trunk/reactos/ntoskrnl/cm/ntfunc.c Thu Nov 22 21:38:32 2007
@@ -578,65 +578,25 @@
return Status;
}
-/*
- * NOTE:
- * KeyObjectAttributes->RootDirectory specifies the handle to the parent key and
- * KeyObjectAttributes->Name specifies the name of the key to load.
- * Flags can be 0 or REG_NO_LAZY_FLUSH.
- */
-NTSTATUS
-NTAPI
-NtLoadKey2 (IN POBJECT_ATTRIBUTES KeyObjectAttributes,
- IN POBJECT_ATTRIBUTES FileObjectAttributes,
- IN ULONG Flags)
-{
- NTSTATUS Status;
- PAGED_CODE();
- DPRINT ("NtLoadKey2() called\n");
-
-#if 0
- if (!SeSinglePrivilegeCheck (SeRestorePrivilege, ExGetPreviousMode ()))
- return STATUS_PRIVILEGE_NOT_HELD;
-#endif
-
- /* Acquire hive lock */
- KeEnterCriticalRegion();
- ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
-
- Status = CmiLoadHive (KeyObjectAttributes,
- FileObjectAttributes->ObjectName,
- Flags);
- if (!NT_SUCCESS (Status))
- {
- DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
- }
-
- /* Release hive lock */
- ExReleaseResourceLite(&CmpRegistryLock);
- KeLeaveCriticalRegion();
-
- return Status;
-}
-
NTSTATUS
NTAPI
NtInitializeRegistry (IN USHORT Flag)
{
NTSTATUS Status;
-
+
PAGED_CODE();
-
+
if (CmiRegistryInitialized == TRUE)
return STATUS_ACCESS_DENIED;
/* Save boot log file */
IopSaveBootLogToFile();
-
+
Status = CmiInitHives (Flag);
-
+
CmpCmdInit(Flag);
CmiRegistryInitialized = TRUE;
-
+
return Status;
}
Removed: trunk/reactos/ntoskrnl/cm/regfile.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regfile.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regfile.c (original)
+++ trunk/reactos/ntoskrnl/cm/regfile.c (removed)
@@ -1,84 +1,0 @@
-/*
- * PROJECT: ReactOS Kernel
- * COPYRIGHT: GPL - See COPYING in the top level directory
- * FILE: ntoskrnl/cm/regfile.c
- * PURPOSE: Registry file manipulation routines
- *
- * PROGRAMMERS: Casper Hornstrup
- * Eric Kohl
- * Filip Navara
- */
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <internal/debug.h>
-#include "cm.h"
-
-/* LOCAL MACROS *************************************************************/
-
-#define ABS_VALUE(V) (((V) < 0) ? -(V) : (V))
-#define REG_DATA_SIZE_MASK 0x7FFFFFFF
-#define REG_DATA_IN_OFFSET 0x80000000
-
-/* FUNCTIONS ****************************************************************/
-
-NTSTATUS
-CmiLoadHive(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
- IN PCUNICODE_STRING FileName,
- IN ULONG Flags)
-{
- PCMHIVE Hive = NULL;
- NTSTATUS Status;
- BOOLEAN Allocate = TRUE;
-
- DPRINT ("CmiLoadHive(Filename %wZ)\n", FileName);
-
- if (Flags & ~REG_NO_LAZY_FLUSH) return STATUS_INVALID_PARAMETER;
-
- Status = CmpInitHiveFromFile(FileName,
- (Flags & REG_NO_LAZY_FLUSH) ? HIVE_NOLAZYFLUSH : 0,
- &Hive,
- &Allocate,
- 0);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmpInitHiveFromFile() failed (Status %lx)\n", Status);
- if (Hive) ExFreePool(Hive);
- return Status;
- }
-
- Status = CmiConnectHive(KeyObjectAttributes, Hive);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1 ("CmiConnectHive() failed (Status %lx)\n", Status);
- // CmiRemoveRegistryHive (Hive);
- }
-
- DPRINT ("CmiLoadHive() done\n");
- return Status;
-}
-
-NTSTATUS
-CmiScanKeyForValue(IN PCMHIVE RegistryHive,
- IN PCM_KEY_NODE KeyCell,
- IN PUNICODE_STRING ValueName,
- OUT PCM_KEY_VALUE *ValueCell,
- OUT HCELL_INDEX *ValueCellOffset)
-{
- HCELL_INDEX CellIndex;
-
- /* Assume failure */
- *ValueCell = NULL;
- if (ValueCellOffset) *ValueCellOffset = HCELL_NIL;
-
- /* Call newer Cm API */
- CellIndex = CmpFindValueByName(&RegistryHive->Hive, KeyCell, ValueName);
- if (CellIndex == HCELL_NIL) return STATUS_OBJECT_NAME_NOT_FOUND;
-
- /* Otherwise, get the cell data back too */
- if (ValueCellOffset) *ValueCellOffset = CellIndex;
- *ValueCell = (PCM_KEY_VALUE)HvGetCell(&RegistryHive->Hive, CellIndex);
- return STATUS_SUCCESS;
-}
-
-/* EOF */
Modified: trunk/reactos/ntoskrnl/cm/registry.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/registry.c?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/registry.c (original)
+++ trunk/reactos/ntoskrnl/cm/registry.c Thu Nov 22 21:38:32 2007
@@ -328,6 +328,8 @@
ULONG BufferSize;
ULONG ResultSize;
PWSTR EndPtr;
+ PCMHIVE CmHive;
+ BOOLEAN Allocate = TRUE;
DPRINT("CmiInitHives() called\n");
@@ -379,138 +381,172 @@
wcscpy(ConfigPath, L"\\SystemRoot");
}
wcscat(ConfigPath, L"\\system32\\config");
-
DPRINT("ConfigPath: %S\n", ConfigPath);
-
EndPtr = ConfigPath + wcslen(ConfigPath);
- /* FIXME: Save boot log */
-
+ /* Setup the file name for the SECURITY hive */
+ wcscpy(EndPtr, REG_SEC_FILE_NAME);
+ RtlInitUnicodeString(&FileName, ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
+
+ /* Load the hive */
+ Status = CmpInitHiveFromFile(&FileName,
+ 0,
+ &CmHive,
+ &Allocate,
+ 0);
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString(&KeyName, REG_SEC_KEY_NAME);
+
+ Status = CmpLinkHiveToMaster(&KeyName,
+ NULL,
+ CmHive,
+ FALSE,
+ NULL);
+
+ /* Connect the SOFTWARE hive */
+ wcscpy(EndPtr, REG_SOFTWARE_FILE_NAME);
+ RtlInitUnicodeString(&FileName, ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
+
+ /* Load the hive */
+ Status = CmpInitHiveFromFile(&FileName,
+ 0,
+ &CmHive,
+ &Allocate,
+ 0);
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString (&KeyName, REG_SOFTWARE_KEY_NAME);
+
+ Status = CmpLinkHiveToMaster(&KeyName,
+ NULL,
+ CmHive,
+ FALSE,
+ NULL);
+
/* Connect the SYSTEM hive only if it has been created */
if (SetupBoot == TRUE)
{
wcscpy(EndPtr, REG_SYSTEM_FILE_NAME);
+ RtlInitUnicodeString(&FileName, ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
-
- RtlInitUnicodeString (&KeyName,
- REG_SYSTEM_KEY_NAME);
- InitializeObjectAttributes(&ObjectAttributes,
- &KeyName,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- RtlInitUnicodeString (&FileName,
- ConfigPath);
- Status = CmiLoadHive (&ObjectAttributes,
- &FileName,
- 0);
- if (!NT_SUCCESS(Status))
+#if 0
+ HANDLE PrimaryHandle, LogHandle;
+ ULONG PrimaryDisposition, SecondaryDisposition;
+ ULONG ClusterSize, Length;
+
+ /* Build the file name */
+ wcscpy(EndPtr, REG_SYSTEM_FILE_NAME);
+ RtlInitUnicodeString(&FileName, ConfigPath);
+ DPRINT ("ConfigPath: %S\n", ConfigPath);
+
+ /* Hive already exists */
+ CmHive = CmpMachineHiveList[3].CmHive;
+
+ /* Open the hive file and log */
+ Status = CmpOpenHiveFiles(&FileName,
+ L".LOG",
+ &PrimaryHandle,
+ &LogHandle,
+ &PrimaryDisposition,
+ &SecondaryDisposition,
+ TRUE,
+ TRUE,
+ FALSE,
+ &ClusterSize);
+ if (!(NT_SUCCESS(Status)) || !(LogHandle))
{
- DPRINT1 ("CmiLoadHive() failed (Status %lx)\n", Status);
- return Status;
+ /* Bugcheck */
+ KeBugCheck(BAD_SYSTEM_CONFIG_INFO);
}
+
+ /* Save the file handles */
+ CmHive->FileHandles[HFILE_TYPE_LOG] = LogHandle;
+ CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
+
+ /* Allow lazy flushing since the handles are there */
+ ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH);
+ CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH;
+
+ /* Get the real size of the hive */
+ Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
+
+ /* Check if the cluster size doesn't match */
+ if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE);
+
+ /* Set the file size */
+ if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
+ {
+ /* This shouldn't fail */
+ ASSERT(FALSE);
+ }
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString (&KeyName, REG_SYSTEM_KEY_NAME);
+#else
+ /* Load the hive */
+ Status = CmpInitHiveFromFile(&FileName,
+ 0,
+ &CmHive,
+ &Allocate,
+ 0);
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString (&KeyName, REG_SYSTEM_KEY_NAME);
+
+ Status = CmpLinkHiveToMaster(&KeyName,
+ NULL,
+ CmHive,
+ FALSE,
+ NULL);
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);
+#endif
+ }
+
+ /* Connect the DEFAULT hive */
+ wcscpy(EndPtr, REG_DEFAULT_USER_FILE_NAME);
+ RtlInitUnicodeString(&FileName, ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
- RtlInitUnicodeString (&KeyName,
- REG_SOFTWARE_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);
- }
+ /* Load the hive */
+ Status = CmpInitHiveFromFile(&FileName,
+ 0,
+ &CmHive,
+ &Allocate,
+ 0);
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString (&KeyName, REG_DEFAULT_USER_KEY_NAME);
+
+ Status = CmpLinkHiveToMaster(&KeyName,
+ NULL,
+ CmHive,
+ FALSE,
+ NULL);
/* Connect the SAM hive */
wcscpy(EndPtr, REG_SAM_FILE_NAME);
- RtlInitUnicodeString (&FileName,
- ConfigPath);
+ RtlInitUnicodeString(&FileName, ConfigPath);
DPRINT ("ConfigPath: %S\n", ConfigPath);
-
- 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);
- }
-
- /* Connect the SECURITY hive */
- wcscpy(EndPtr, REG_SEC_FILE_NAME);
- 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);
- }
-
- /* Connect the DEFAULT hive */
- wcscpy(EndPtr, REG_DEFAULT_USER_FILE_NAME);
- RtlInitUnicodeString (&FileName,
- ConfigPath);
- DPRINT ("ConfigPath: %S\n", ConfigPath);
-
- 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);
- }
-
- DPRINT("CmiInitHives() done\n");
-
- return(STATUS_SUCCESS);
+
+ /* Load the hive */
+ Status = CmpInitHiveFromFile(&FileName,
+ 0,
+ &CmHive,
+ &Allocate,
+ 0);
+
+ /* Setup the key name for the SECURITY hive */
+ RtlInitUnicodeString(&KeyName, REG_SAM_KEY_NAME);
+ Status = CmpLinkHiveToMaster(&KeyName,
+ NULL,
+ CmHive,
+ FALSE,
+ NULL);
+ return Status;
}
VOID
Modified: trunk/reactos/ntoskrnl/cm/regobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/regobj.c?rev=3…
==============================================================================
--- trunk/reactos/ntoskrnl/cm/regobj.c (original)
+++ trunk/reactos/ntoskrnl/cm/regobj.c Thu Nov 22 21:38:32 2007
@@ -838,22 +838,20 @@
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"SymbolicLinkValue");
PCM_KEY_VALUE ValueCell;
PVOID DataCell;
- NTSTATUS Status;
+ HCELL_INDEX Cell;
DPRINT("CmiGetLinkTarget() called\n");
- /* Get Value block of interest */
- Status = CmiScanKeyForValue(RegistryHive,
- KeyCell,
- &LinkName,
- &ValueCell,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT1("CmiScanKeyForValue() failed (Status %lx)\n", Status);
- return(Status);
- }
-
+ /* Find the cell */
+ Cell = CmpFindValueByName(&RegistryHive->Hive, KeyCell, &LinkName);
+ if (Cell == HCELL_NIL)
+ {
+ DPRINT1("CmiScanKeyForValue() failed\n");
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* Get the cell data */
+ ValueCell = (PCM_KEY_VALUE)HvGetCell(&RegistryHive->Hive, Cell);
if (ValueCell->Type != REG_LINK)
{
DPRINT1("Type != REG_LINK\n!");
Modified: trunk/reactos/ntoskrnl/config/cm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cm.h?rev=3…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cm.h (original)
+++ trunk/reactos/ntoskrnl/config/cm.h Thu Nov 22 21:38:32 2007
@@ -86,11 +86,16 @@
#define MAXIMUM_CACHED_DATA 2 * PAGE_SIZE
//
+// Hives to load on startup
+//
+#define CM_NUMBER_OF_MACHINE_HIVES 6
+
+//
// Number of items that can fit inside an Allocation Page
//
#define CM_KCBS_PER_PAGE \
PAGE_SIZE / sizeof(CM_KEY_CONTROL_BLOCK)
-#define CM_DELAYS_PER_PAGE \
+#define CM_DELAYS_PER_PAGE \
PAGE_SIZE / sizeof(CM_DELAYED_CLOSE_ENTRY)
//
@@ -429,9 +434,8 @@
//
typedef struct _HIVE_LIST_ENTRY
{
- PWCHAR FileName;
- PWCHAR BaseName;
- PWCHAR RegRootName;
+ PWSTR Name;
+ PWSTR BaseName;
PCMHIVE CmHive;
ULONG HHiveFlags;
ULONG CmHiveFlags;
@@ -439,7 +443,6 @@
BOOLEAN ThreadFinished;
BOOLEAN ThreadStarted;
BOOLEAN Allocate;
- BOOLEAN WinPERequired;
} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
//
@@ -759,6 +762,12 @@
IN ULONG CheckFlags
);
+VOID
+NTAPI
+CmpInitializeHiveList(
+ IN USHORT Flag
+);
+
//
// Registry Utility Functions
//
@@ -956,7 +965,7 @@
);
//
-// Flush Routines
+// Command Routines (Flush, Open, Close, Init);
//
BOOLEAN
NTAPI
@@ -974,6 +983,16 @@
NTAPI
CmpCmdInit(
IN BOOLEAN SetupBoot
+);
+
+NTSTATUS
+NTAPI
+CmpCmdHiveOpen(
+ IN POBJECT_ATTRIBUTES FileAttributes,
+ IN PSECURITY_CLIENT_CONTEXT ImpersonationContext,
+ IN OUT PBOOLEAN Allocate,
+ OUT PCMHIVE *NewHive,
+ IN ULONG CheckFlags
);
VOID
@@ -1351,7 +1370,7 @@
extern ULONG CmpConfigurationAreaSize;
extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
extern UNICODE_STRING CmTypeName[];
-extern HIVE_LIST_ENTRY CmpMachineHiveList[5];
+extern HIVE_LIST_ENTRY CmpMachineHiveList[];
extern UNICODE_STRING CmSymbolicLinkValueName;
extern UNICODE_STRING CmpSystemStartOptions;
extern UNICODE_STRING CmpLoadOptions;
Modified: trunk/reactos/ntoskrnl/config/cmapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmapi.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmapi.c (original)
+++ trunk/reactos/ntoskrnl/config/cmapi.c Thu Nov 22 21:38:32 2007
@@ -12,9 +12,6 @@
#include "cm.h"
#define NDEBUG
#include "debug.h"
-
-NTSTATUS
-CmiFlushRegistryHive(PCMHIVE RegistryHive);
/* FUNCTIONS *****************************************************************/
@@ -892,7 +889,7 @@
Info->KeyFullInformation.MaxNameLen = Node->MaxNameLen;
Info->KeyFullInformation.MaxClassLen = Node->MaxClassLen;
Info->KeyFullInformation.MaxValueNameLen = Node->MaxValueNameLen;
- Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
+ Info->KeyFullInformation.MaxValueDataLen = Node->MaxValueDataLen;
/* Check if we have a class */
if (Node->ClassLength > 0)
@@ -1202,3 +1199,121 @@
/* Return the status */
return Status;
}
+
+NTSTATUS
+NTAPI
+CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
+ IN POBJECT_ATTRIBUTES SourceFile,
+ IN ULONG Flags,
+ IN PKEY_OBJECT KeyBody)
+{
+ SECURITY_QUALITY_OF_SERVICE ServiceQos;
+ SECURITY_CLIENT_CONTEXT ClientSecurityContext;
+ HANDLE KeyHandle;
+ BOOLEAN Allocate = TRUE;
+ PCMHIVE CmHive;
+ NTSTATUS Status;
+
+ /* Check if we have a trust key */
+ if (KeyBody)
+ {
+ /* Fail */
+ DPRINT1("Trusted classes not yet supported\n");
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ /* Build a service QoS for a security context */
+ ServiceQos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
+ ServiceQos.ImpersonationLevel = SecurityImpersonation;
+ ServiceQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
+ ServiceQos.EffectiveOnly = TRUE;
+ Status = SeCreateClientSecurity(PsGetCurrentThread(),
+ &ServiceQos,
+ FALSE,
+ &ClientSecurityContext);
+ if (!NT_SUCCESS(Status))
+ {
+ /* Fail */
+ DPRINT1("Security context failed\n");
+ return Status;
+ }
+
+ /* Open the target key */
+ Status = ZwOpenKey(&KeyHandle, KEY_READ, TargetKey);
+ if (!NT_SUCCESS(Status)) KeyHandle = NULL;
+
+ /* Open the hive */
+ Status = CmpCmdHiveOpen(SourceFile,
+ &ClientSecurityContext,
+ &Allocate,
+ &CmHive,
+ 0);
+
+ /* Get rid of the security context */
+ SeDeleteClientSecurity(&ClientSecurityContext);
+
+ /* See if we failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* See if the target already existed */
+ if (KeyHandle)
+ {
+ /* Lock the registry */
+ CmpLockRegistryExclusive();
+
+ /* FIXME: Check if we are already loaded */
+
+ /* Release the registry */
+ CmpUnlockRegistry();
+ }
+
+ /* Close the key handle if we had one */
+ if (KeyHandle) ZwClose(KeyHandle);
+ DPRINT1("Failed: %lx\n", Status);
+ return Status;
+ }
+
+ /* Lock the registry shared */
+ //CmpLockRegistry();
+
+ /* Lock the hive to this thread */
+ CmHive->Hive.HiveFlags |= HIVE_IS_UNLOADING;
+ CmHive->CreatorOwner = KeGetCurrentThread();
+
+ /* Set flag */
+ if (Flags & REG_NO_LAZY_FLUSH) CmHive->Hive.HiveFlags |= HIVE_NOLAZYFLUSH;
+
+ /* Link the hive */
+ Status = CmpLinkHiveToMaster(TargetKey->ObjectName,
+ TargetKey->RootDirectory,
+ CmHive,
+ FALSE,
+ TargetKey->SecurityDescriptor);
+ if (NT_SUCCESS(Status))
+ {
+ /* FIXME: Add to HiveList key */
+
+ /* Sync the hive if necessary */
+ if (Allocate)
+ {
+ /* Sync it */
+ HvSyncHive(&CmHive->Hive);
+ }
+
+ /* Release the hive */
+ CmHive->Hive.HiveFlags &= ~HIVE_IS_UNLOADING;
+ CmHive->CreatorOwner = NULL;
+ }
+ else
+ {
+ /* FIXME: TODO */
+
+ }
+
+ /* Unlock the registry */
+ //CmpUnlockRegistry();
+
+ /* Close handle and return */
+ if (KeyHandle) ZwClose(KeyHandle);
+ return Status;
+}
Modified: trunk/reactos/ntoskrnl/config/cmdata.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmdata.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmdata.c (original)
+++ trunk/reactos/ntoskrnl/config/cmdata.c Thu Nov 22 21:38:32 2007
@@ -38,7 +38,16 @@
EX_PUSH_LOCK CmpHiveListHeadLock, CmpLoadHiveLock;
-HIVE_LIST_ENTRY CmpMachineHiveList[5];
+HIVE_LIST_ENTRY CmpMachineHiveList[] =
+{
+ { L"HARDWARE", L"MACHINE\\", NULL, HIVE_VOLATILE , 0
, NULL, FALSE, FALSE, FALSE},
+ { L"SECURITY", L"MACHINE\\", NULL, 0 , 0
, NULL, FALSE, FALSE, FALSE},
+ { L"SOFTWARE", L"MACHINE\\", NULL, 0 , 0
, NULL, FALSE, FALSE, FALSE},
+ { L"SYSTEM", L"MACHINE\\", NULL, 0 , 0
, NULL, FALSE, FALSE, FALSE},
+ { L"DEFAULT", L"USER\\.DEFAULT", NULL, 0 , 0 ,
NULL, FALSE, FALSE, FALSE},
+ { L"SAM", L"MACHINE\\", NULL, HIVE_NOLAZYFLUSH , 0
, NULL, FALSE, FALSE, FALSE},
+ { NULL, NULL, 0, 0 , 0 ,
NULL, FALSE, FALSE, FALSE}
+};
UNICODE_STRING CmSymbolicLinkValueName =
RTL_CONSTANT_STRING(L"SymbolicLinkValue");
Modified: trunk/reactos/ntoskrnl/config/cmlazy.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmlazy.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmlazy.c (original)
+++ trunk/reactos/ntoskrnl/config/cmlazy.c Thu Nov 22 21:38:32 2007
@@ -238,6 +238,56 @@
/* Testing: Force Lazy Flushing */
CmpHoldLazyFlush = FALSE;
+
+ /* Setup the hive list */
+ CmpInitializeHiveList(SetupBoot);
+}
+
+NTSTATUS
+NTAPI
+CmpCmdHiveOpen(IN POBJECT_ATTRIBUTES FileAttributes,
+ IN PSECURITY_CLIENT_CONTEXT ImpersonationContext,
+ IN OUT PBOOLEAN Allocate,
+ OUT PCMHIVE *NewHive,
+ IN ULONG CheckFlags)
+{
+ PUNICODE_STRING FileName;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* Open the file in the current security context */
+ FileName = FileAttributes->ObjectName;
+ Status = CmpInitHiveFromFile(FileName,
+ 0,
+ NewHive,
+ Allocate,
+ CheckFlags);
+ if (((Status == STATUS_ACCESS_DENIED) ||
+ (Status == STATUS_NO_SUCH_USER) ||
+ (Status == STATUS_WRONG_PASSWORD) ||
+ (Status == STATUS_ACCOUNT_EXPIRED) ||
+ (Status == STATUS_ACCOUNT_DISABLED) ||
+ (Status == STATUS_ACCOUNT_RESTRICTION)) &&
+ (ImpersonationContext))
+ {
+ /* We failed due to an account/security error, impersonate SYSTEM */
+ Status = SeImpersonateClientEx(ImpersonationContext, NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* Now try again */
+ Status = CmpInitHiveFromFile(FileName,
+ 0,
+ NewHive,
+ Allocate,
+ CheckFlags);
+
+ /* Restore impersonation token */
+ PsRevertToSelf();
+ }
+ }
+
+ /* Return status of open attempt */
+ return Status;
}
VOID
Modified: trunk/reactos/ntoskrnl/config/cmparse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmparse.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmparse.c (original)
+++ trunk/reactos/ntoskrnl/config/cmparse.c Thu Nov 22 21:38:32 2007
@@ -416,3 +416,299 @@
ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
return Status;
}
+
+NTSTATUS
+NTAPI
+CmpDoOpen(IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN PCM_KEY_NODE Node,
+ IN PACCESS_STATE AccessState,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG Attributes,
+ IN PCM_PARSE_CONTEXT Context OPTIONAL,
+ IN ULONG ControlFlags,
+ IN OUT PCM_KEY_CONTROL_BLOCK *CachedKcb,
+ IN PUNICODE_STRING KeyName,
+ OUT PVOID *Object)
+{
+ NTSTATUS Status;
+ PKEY_OBJECT KeyBody = NULL;
+ PCM_KEY_CONTROL_BLOCK Kcb = NULL;
+
+ /* Make sure the hive isn't locked */
+ if ((Hive->HiveFlags & HIVE_IS_UNLOADING) &&
+ (((PCMHIVE)Hive)->CreatorOwner != KeGetCurrentThread()))
+ {
+ /* It is, don't touch it */
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* If we have a KCB, make sure it's locked */
+ ASSERT(CmpIsKcbLockedExclusive(*CachedKcb));
+
+ /* Create the KCB */
+ Kcb = CmpCreateKeyControlBlock(Hive, Cell, Node, *CachedKcb, 0, KeyName);
+ if (!Kcb) return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Make sure it's also locked, and set the pointer */
+ ASSERT(CmpIsKcbLockedExclusive(Kcb));
+ *CachedKcb = Kcb;
+
+ /* Allocate the key object */
+ Status = ObCreateObject(AccessMode,
+ CmpKeyObjectType,
+ NULL,
+ AccessMode,
+ NULL,
+ sizeof(KEY_OBJECT),
+ 0,
+ 0,
+ Object);
+ if (NT_SUCCESS(Status))
+ {
+ /* Get the key body and fill it out */
+ KeyBody = (PKEY_OBJECT)(*Object);
+ KeyBody->KeyControlBlock = Kcb;
+ KeyBody->SubKeyCounts = 0;
+ KeyBody->SubKeys = NULL;
+ KeyBody->SizeOfSubKeys = 0;
+ InsertTailList(&CmiKeyObjectListHead, &KeyBody->KeyBodyList);
+ }
+ else
+ {
+ /* Failed, dereference the KCB */
+ CmpDereferenceKeyControlBlockWithLock(Kcb, FALSE);
+ }
+
+ /* Return status */
+ return Status;
+}
+
+/* Remove calls to CmCreateRootNode once this is used! */
+NTSTATUS
+NTAPI
+CmpCreateLinkNode(IN PHHIVE Hive,
+ IN HCELL_INDEX Cell,
+ IN PACCESS_STATE AccessState,
+ IN UNICODE_STRING Name,
+ IN KPROCESSOR_MODE AccessMode,
+ IN ULONG CreateOptions,
+ IN PCM_PARSE_CONTEXT Context,
+ IN PCM_KEY_CONTROL_BLOCK ParentKcb,
+ OUT PVOID *Object)
+{
+ NTSTATUS Status;
+ HCELL_INDEX KeyCell, LinkCell, ChildCell;
+ PKEY_OBJECT KeyBody;
+ LARGE_INTEGER TimeStamp;
+ PCM_KEY_NODE KeyNode;
+ PCM_KEY_CONTROL_BLOCK Kcb = ParentKcb;
+
+ /* Link nodes only allowed on the master */
+ if (Hive != &CmiVolatileHive->Hive)
+ {
+ /* Fail */
+ DPRINT1("Invalid link node attempt\n");
+ return STATUS_ACCESS_DENIED;
+ }
+
+ /* Acquire the flusher locks */
+ ExAcquirePushLockShared((PVOID)&((PCMHIVE)Hive)->FlusherLock);
+
ExAcquirePushLockShared((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock);
+
+ /* Check if the parent is being deleted */
+ if (ParentKcb->Delete)
+ {
+ /* It is, quit */
+ ASSERT(FALSE);
+ Status = STATUS_OBJECT_NAME_NOT_FOUND;
+ goto Exit;
+ }
+
+ /* Allocate a link node */
+ LinkCell = HvAllocateCell(Hive,
+ FIELD_OFFSET(CM_KEY_NODE, Name) +
+ CmpNameSize(Hive, &Name),
+ Stable,
+ HCELL_NIL);
+ if (LinkCell == HCELL_NIL)
+ {
+ /* Fail */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Get the key cell */
+ KeyCell = Context->ChildHive.KeyCell;
+ if (KeyCell != HCELL_NIL)
+ {
+ /* Hive exists! */
+ ChildCell = KeyCell;
+
+ /* Get the node data */
+ KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, ChildCell);
+ if (!KeyNode)
+ {
+ /* Fail */
+ ASSERT(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Fill out the data */
+ KeyNode->Parent = LinkCell;
+ KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
+ HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
+
+ /* Now open the key cell */
+ KeyNode = (PCM_KEY_NODE)HvGetCell(Context->ChildHive.KeyHive, KeyCell);
+ if (!KeyNode)
+ {
+ /* Fail */
+ ASSERT(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Open the parent */
+ Status = CmpDoOpen(Context->ChildHive.KeyHive,
+ KeyCell,
+ KeyNode,
+ AccessState,
+ AccessMode,
+ CreateOptions,
+ NULL,
+ 0,
+ &Kcb,
+ &Name,
+ Object);
+ HvReleaseCell(Context->ChildHive.KeyHive, KeyCell);
+ }
+ else
+ {
+ /* Do the actual create operation */
+ Status = CmpDoCreateChild(Context->ChildHive.KeyHive,
+ Cell,
+ NULL,
+ AccessState,
+ &Name,
+ AccessMode,
+ &Context->Class,
+ ParentKcb,
+ KEY_HIVE_ENTRY | KEY_NO_DELETE,
+ &ChildCell,
+ Object);
+ if (NT_SUCCESS(Status))
+ {
+ /* Setup root pointer */
+ Context->ChildHive.KeyHive->BaseBlock->RootCell = ChildCell;
+ }
+ }
+
+ /* Check if open or create suceeded */
+ if (NT_SUCCESS(Status))
+ {
+ /* Mark the cell dirty */
+ HvMarkCellDirty(Context->ChildHive.KeyHive, ChildCell, FALSE);
+
+ /* Get the key node */
+ KeyNode = HvGetCell(Context->ChildHive.KeyHive, ChildCell);
+ if (!KeyNode)
+ {
+ /* Fail */
+ ASSERT(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Release it */
+ HvReleaseCell(Context->ChildHive.KeyHive, ChildCell);
+
+ /* Set the parent adn flags */
+ KeyNode->Parent = LinkCell;
+ KeyNode->Flags |= KEY_HIVE_ENTRY | KEY_NO_DELETE;
+
+ /* Get the link node */
+ KeyNode = HvGetCell(Hive, LinkCell);
+ if (!KeyNode)
+ {
+ /* Fail */
+ ASSERT(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Set it up */
+ KeyNode->Signature = CM_LINK_NODE_SIGNATURE;
+ KeyNode->Flags = KEY_HIVE_EXIT | KEY_NO_DELETE;
+ KeyNode->Parent = Cell;
+ KeyNode->NameLength = CmpCopyName(Hive, KeyNode->Name, &Name);
+ if (KeyNode->NameLength < Name.Length) KeyNode->Flags |= KEY_COMP_NAME;
+ KeQuerySystemTime(&TimeStamp);
+ KeyNode->LastWriteTime = TimeStamp;
+
+ /* Clear out the rest */
+ KeyNode->SubKeyCounts[Stable] = 0;
+ KeyNode->SubKeyCounts[Volatile] = 0;
+ KeyNode->SubKeyLists[Stable] = HCELL_NIL;
+ KeyNode->SubKeyLists[Volatile] = HCELL_NIL;
+ KeyNode->ValueList.Count = 0;
+ KeyNode->ValueList.List = HCELL_NIL;
+ KeyNode->ClassLength = 0;
+
+ /* Reference the root node */
+ //KeyNode->ChildHiveReference.KeyHive = Context->ChildHive.KeyHive;
+ //KeyNode->ChildHiveReference.KeyCell = ChildCell;
+ HvReleaseCell(Hive, LinkCell);
+
+ /* Get the parent node */
+ KeyNode = HvGetCell(Hive, Cell);
+ if (!KeyNode)
+ {
+ /* Fail */
+ ASSERT(FALSE);
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ goto Exit;
+ }
+
+ /* Now add the subkey */
+ if (!CmpAddSubKey(Hive, Cell, LinkCell))
+ {
+ /* Failure! We don't handle this yet! */
+ ASSERT(FALSE);
+ }
+
+ /* Get the key body */
+ KeyBody = (PKEY_OBJECT)*Object;
+
+ /* Sanity checks */
+ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyCell == Cell);
+ ASSERT(KeyBody->KeyControlBlock->ParentKcb->KeyHive == Hive);
+ //ASSERT(KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen ==
KeyNode->MaxNameLen);
+
+ /* Update the timestamp */
+ KeQuerySystemTime(&TimeStamp);
+ KeyNode->LastWriteTime = TimeStamp;
+
+ /* Check if we need to update name maximum */
+ if (KeyNode->MaxNameLen < Name.Length)
+ {
+ /* Do it */
+ KeyNode->MaxNameLen = Name.Length;
+ KeyBody->KeyControlBlock->ParentKcb->KcbMaxNameLen = Name.Length;
+ }
+
+ /* Check if we need toupdate class length maximum */
+ if (KeyNode->MaxClassLen < Context->Class.Length)
+ {
+ /* Update it */
+ KeyNode->MaxClassLen = Context->Class.Length;
+ }
+ }
+
+Exit:
+ /* Release the flusher locks and return status */
+
ExReleasePushLock((PVOID)&((PCMHIVE)Context->ChildHive.KeyHive)->FlusherLock);
+ ExReleasePushLock((PVOID)&((PCMHIVE)Hive)->FlusherLock);
+ return Status;
+}
Modified: trunk/reactos/ntoskrnl/config/cmsysini.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmsysini.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmsysini.c (original)
+++ trunk/reactos/ntoskrnl/config/cmsysini.c Thu Nov 22 21:38:32 2007
@@ -15,6 +15,8 @@
KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead;
+KEVENT CmpLoadWorkerEvent;
+LONG CmpLoadWorkerIncrement;
PEPROCESS CmpSystemProcess;
BOOLEAN HvShutdownComplete;
PVOID CmpRegistryLockCallerCaller, CmpRegistryLockCaller;
@@ -496,11 +498,11 @@
}
else
{
+ /* Create it */
#if 0
- /* Create it */
- Status = CmpInitializeHive((PCMHIVE*)&SystemHive,
+ Status = CmpInitializeHive(&SystemHive,
HINIT_CREATE,
- HIVE_NOLAZYFLUSH,
+ 0, //HIVE_NOLAZYFLUSH,
HFILE_TYPE_LOG,
NULL,
NULL,
@@ -509,8 +511,10 @@
&HiveName,
0);
if (!NT_SUCCESS(Status)) return FALSE;
+
+ /* Set the hive filename */
+ RtlCreateUnicodeString(&SystemHive->FileFullPath, SYSTEM_REG_FILE);
#endif
-
/* Tell CmpLinkHiveToMaster to allocate a hive */
Allocate = TRUE;
}
@@ -746,6 +750,314 @@
return TRUE;
}
+VOID
+NTAPI
+CmpLoadHiveThread(IN PVOID StartContext)
+{
+ WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH];
+ UNICODE_STRING TempName, FileName, RegName;
+ ULONG FileStart, RegStart, i, ErrorResponse, ClusterSize, WorkerCount;
+ ULONG PrimaryDisposition, SecondaryDisposition, Length;
+ PCMHIVE CmHive;
+ HANDLE PrimaryHandle, LogHandle;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID ErrorParameters;
+ PAGED_CODE();
+
+ /* Get the hive index, make sure it makes sense */
+ i = (ULONG)StartContext;
+ ASSERT(CmpMachineHiveList[i].Name != NULL);
+ DPRINT1("[HiveLoad] Parallel Thread: %d\n", i);
+
+ /* We were started */
+ CmpMachineHiveList[i].ThreadStarted = TRUE;
+
+ /* Build the file name and registry name strings */
+ RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH);
+ RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH);
+
+ /* Now build the system root path */
+ RtlInitUnicodeString(&TempName, L"\\SystemRoot\\System32\\Config\\");
+ RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
+ FileStart = FileName.Length;
+
+ /* And build the registry root path */
+ RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+ RegStart = RegName.Length;
+
+ /* Build the base name */
+ RegName.Length = RegStart;
+ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+
+ /* Check if this is a child of the root */
+ if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\')
+ {
+ /* Then setup the whole name */
+ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+ }
+
+ /* Now Add tge rest if the file name */
+ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
+ FileName.Length = FileStart;
+ RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
+ if (!CmpMachineHiveList[i].CmHive)
+ {
+ /* We need to allocate a ne whive structure */
+ CmpMachineHiveList[i].Allocate = TRUE;
+
+ /* Load the hive file */
+ DPRINT1("[HiveLoad]: Load from file %wZ\n", &FileName);
+ CmpMachineHiveList[i].CmHive2 = (PVOID)0xBAADBEEF;
+ goto Later;
+ Status = CmpInitHiveFromFile(&FileName,
+ CmpMachineHiveList[i].HHiveFlags,
+ &CmHive,
+ &CmpMachineHiveList[i].Allocate,
+ 0);
+ if (!(NT_SUCCESS(Status)) || !(CmHive->FileHandles[HFILE_TYPE_LOG]))
+ {
+ /* We failed or couldn't get a log file, raise a hard error */
+ ErrorParameters = &FileName;
+ NtRaiseHardError(STATUS_CANNOT_LOAD_REGISTRY_FILE,
+ 1,
+ 1,
+ (PULONG_PTR)&ErrorParameters,
+ OptionOk,
+ &ErrorResponse);
+ }
+
+ /* Set the hive flags and newly allocated hive pointer */
+ CmHive->Flags = CmpMachineHiveList[i].CmHiveFlags;
+ CmpMachineHiveList[i].CmHive2 = CmHive;
+ }
+ else
+ {
+ /* We already have a hive, is it volatile? */
+ CmHive = CmpMachineHiveList[i].CmHive;
+ if (!(CmHive->Hive.HiveFlags & HIVE_VOLATILE))
+ {
+ DPRINT1("[HiveLoad]: Open from file %wZ\n", &FileName);
+ CmpMachineHiveList[i].CmHive2 = CmHive;
+ goto Later;
+
+ /* It's now, open the hive file and log */
+ Status = CmpOpenHiveFiles(&FileName,
+ L".LOG",
+ &PrimaryHandle,
+ &LogHandle,
+ &PrimaryDisposition,
+ &SecondaryDisposition,
+ TRUE,
+ TRUE,
+ FALSE,
+ &ClusterSize);
+ if (!(NT_SUCCESS(Status)) || !(LogHandle))
+ {
+ /* Couldn't open the hive or its log file, raise a hard error */
+ ErrorParameters = &FileName;
+ NtRaiseHardError(STATUS_CANNOT_LOAD_REGISTRY_FILE,
+ 1,
+ 1,
+ (PULONG_PTR)&ErrorParameters,
+ OptionOk,
+ &ErrorResponse);
+
+ /* And bugcheck for posterity's sake */
+ KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 0, i, Status);
+ }
+
+ /* Save the file handles. This should remove our sync hacks */
+ CmHive->FileHandles[HFILE_TYPE_LOG] = LogHandle;
+ CmHive->FileHandles[HFILE_TYPE_PRIMARY] = PrimaryHandle;
+
+ /* Allow lazy flushing since the handles are there -- remove sync hacks */
+ ASSERT(CmHive->Hive.HiveFlags & HIVE_NOLAZYFLUSH);
+ CmHive->Hive.HiveFlags &= ~HIVE_NOLAZYFLUSH;
+
+ /* Get the real size of the hive */
+ Length = CmHive->Hive.Storage[Stable].Length + HBLOCK_SIZE;
+
+ /* Check if the cluster size doesn't match */
+ if (CmHive->Hive.Cluster != ClusterSize) ASSERT(FALSE);
+
+ /* Set the file size */
+ if (!CmpFileSetSize((PHHIVE)CmHive, HFILE_TYPE_PRIMARY, Length, Length))
+ {
+ /* This shouldn't fail */
+ ASSERT(FALSE);
+ }
+
+ /* Another thing we don't support is NTLDR-recovery */
+ if (CmHive->Hive.BaseBlock->BootRecover) ASSERT(FALSE);
+
+ /* Finally, set our allocated hive to the same hive we've had */
+ CmpMachineHiveList[i].CmHive2 = CmHive;
+ ASSERT(CmpMachineHiveList[i].CmHive == CmpMachineHiveList[i].CmHive2);
+ }
+ }
+
+ /* We're done */
+Later:
+ CmpMachineHiveList[i].ThreadFinished = TRUE;
+
+ /* Check if we're the last worker */
+ WorkerCount = InterlockedIncrement(&CmpLoadWorkerIncrement);
+ if (WorkerCount == CM_NUMBER_OF_MACHINE_HIVES)
+
+ {
+ /* Signal the event */
+ KeSetEvent(&CmpLoadWorkerEvent, 0, FALSE);
+ }
+
+ /* Kill the thread */
+ PsTerminateSystemThread(Status);
+}
+
+VOID
+NTAPI
+CmpInitializeHiveList(IN USHORT Flag)
+{
+ WCHAR FileBuffer[MAX_PATH], RegBuffer[MAX_PATH];
+ UNICODE_STRING TempName, FileName, RegName;
+ HANDLE Thread;
+ NTSTATUS Status;
+ ULONG FileStart, RegStart, i;
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ PAGED_CODE();
+
+ /* Allow writing for now */
+ CmpNoWrite = FALSE;
+
+ /* Build the file name and registry name strings */
+ RtlInitEmptyUnicodeString(&FileName, FileBuffer, MAX_PATH);
+ RtlInitEmptyUnicodeString(&RegName, RegBuffer, MAX_PATH);
+
+ /* Now build the system root path */
+ RtlInitUnicodeString(&TempName, L"\\SystemRoot\\System32\\Config\\");
+ RtlAppendStringToString((PSTRING)&FileName, (PSTRING)&TempName);
+ FileStart = FileName.Length;
+
+ /* And build the registry root path */
+ RtlInitUnicodeString(&TempName, L"\\REGISTRY\\");
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+ RegStart = RegName.Length;
+
+ /* Setup the event to synchronize workers */
+ KeInitializeEvent(&CmpLoadWorkerEvent, SynchronizationEvent, FALSE);
+
+ /* Enter special boot condition */
+ CmpSpecialBootCondition = TRUE;
+
+ /* Create the SD for the root hives */
+ SecurityDescriptor = CmpHiveRootSecurityDescriptor();
+
+ /* Loop every hive we care about */
+ for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
+ {
+ /* Make sure the list is setup */
+ ASSERT(CmpMachineHiveList[i].Name != NULL);
+
+ /* Create a thread to handle this hive */
+ Status = PsCreateSystemThread(&Thread,
+ THREAD_ALL_ACCESS,
+ NULL,
+ 0,
+ NULL,
+ CmpLoadHiveThread,
+ (PVOID)i);
+ if (NT_SUCCESS(Status))
+ {
+ /* We don't care about the handle -- the thread self-terminates */
+ ZwClose(Thread);
+ }
+ else
+ {
+ /* Can't imagine this happening */
+ KeBugCheckEx(BAD_SYSTEM_CONFIG_INFO, 9, 3, i, Status);
+ }
+ }
+
+ /* Make sure we've reached the end of the list */
+ ASSERT(CmpMachineHiveList[i].Name == NULL);
+
+ /* Wait for hive loading to finish */
+ KeWaitForSingleObject(&CmpLoadWorkerEvent,
+ Executive,
+ KernelMode,
+ FALSE,
+ NULL);
+
+ /* Exit the special boot condition and make sure all workers completed */
+ CmpSpecialBootCondition = FALSE;
+ ASSERT(CmpLoadWorkerIncrement == CM_NUMBER_OF_MACHINE_HIVES);
+
+ /* Loop hives again */
+ for (i = 0; i < CM_NUMBER_OF_MACHINE_HIVES; i++)
+ {
+ /* Make sure the thread ran and finished */
+ ASSERT(CmpMachineHiveList[i].ThreadFinished == TRUE);
+ ASSERT(CmpMachineHiveList[i].ThreadStarted == TRUE);
+
+ /* Check if this was a new hive */
+ if (!CmpMachineHiveList[i].CmHive)
+ {
+ /* Make sure we allocated something */
+ ASSERT(CmpMachineHiveList[i].CmHive2 != NULL);
+
+ /* Build the base name */
+ RegName.Length = RegStart;
+ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].BaseName);
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+
+ /* Check if this is a child of the root */
+ if (RegName.Buffer[RegName.Length / sizeof(WCHAR) - 1] == '\\')
+ {
+ /* Then setup the whole name */
+ RtlInitUnicodeString(&TempName, CmpMachineHiveList[i].Name);
+ RtlAppendStringToString((PSTRING)&RegName, (PSTRING)&TempName);
+ }
+
+ /* Now link the hive to its master */
+ DPRINT1("[HiveLoad]: Link %wZ\n", &RegName);
+#if 0
+ Status = CmpLinkHiveToMaster(&RegName,
+ NULL,
+ CmpMachineHiveList[i].CmHive2,
+ CmpMachineHiveList[i].Allocate,
+ SecurityDescriptor);
+ if (Status != STATUS_SUCCESS)
+ {
+ /* Linking needs to work */
+ KeBugCheckEx(CONFIG_LIST_FAILED, 11, Status, i,
(ULONG_PTR)&RegName);
+ }
+
+ /* Check if we had to allocate a new hive */
+ if (CmpMachineHiveList[i].Allocate)
+ {
+ /* Sync the new hive */
+ HvSyncHive((PHHIVE)(CmpMachineHiveList[i].CmHive2));
+ }
+#endif
+ }
+
+ /* Check if we created a new hive */
+ if (CmpMachineHiveList[i].CmHive2)
+ {
+ /* TODO: Add to HiveList key */
+ }
+ }
+
+ /* Get rid of the SD */
+ ExFreePool(SecurityDescriptor);
+
+ /* FIXME: Link SECURITY to SAM */
+
+ /* FIXME: Link S-1-5-18 to .Default */
+}
+
BOOLEAN
NTAPI
CmInitSystem1(VOID)
Modified: trunk/reactos/ntoskrnl/config/ntapi.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/ntapi.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/config/ntapi.c (original)
+++ trunk/reactos/ntoskrnl/config/ntapi.c Thu Nov 22 21:38:32 2007
@@ -494,16 +494,69 @@
NTSTATUS
NTAPI
+NtLoadKey2(IN POBJECT_ATTRIBUTES KeyObjectAttributes,
+ IN POBJECT_ATTRIBUTES FileObjectAttributes,
+ IN ULONG Flags)
+{
+ return NtLoadKeyEx(KeyObjectAttributes, FileObjectAttributes, Flags, NULL);
+}
+
+NTSTATUS
+NTAPI
+CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
+ IN POBJECT_ATTRIBUTES SourceFile,
+ IN ULONG Flags,
+ IN PKEY_OBJECT KeyBody);
+
+NTSTATUS
+NTAPI
NtLoadKeyEx(IN POBJECT_ATTRIBUTES TargetKey,
IN POBJECT_ATTRIBUTES SourceFile,
IN ULONG Flags,
- IN HANDLE TrustClassKey,
- IN HANDLE Event,
- IN ACCESS_MASK DesiredAccess,
- OUT PHANDLE RootHandle)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ IN HANDLE TrustClassKey)
+{
+ NTSTATUS Status;
+ KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
+ PKEY_OBJECT KeyBody = NULL;
+ PAGED_CODE();
+
+ /* Validate flags */
+ if (Flags & ~REG_NO_LAZY_FLUSH) return STATUS_INVALID_PARAMETER;
+
+ /* Validate privilege */
+ if (!SeSinglePrivilegeCheck(SeRestorePrivilege, PreviousMode))
+ {
+ /* Fail */
+ DPRINT1("Restore Privilege missing!\n");
+ //return STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ /* Block APCs */
+ KeEnterCriticalRegion();
+
+ /* Check if we have a trust class */
+ if (TrustClassKey)
+ {
+ /* Reference it */
+ Status = ObReferenceObjectByHandle(TrustClassKey,
+ 0,
+ CmpKeyObjectType,
+ PreviousMode,
+ (PVOID *)&KeyBody,
+ NULL);
+ }
+
+ /* Call the internal API */
+ Status = CmLoadKey(TargetKey, SourceFile, Flags, KeyBody);
+
+ /* Dereference the trust key, if any */
+ if (KeyBody) ObDereferenceObject(KeyBody);
+
+ /* Bring back APCs */
+ KeLeaveCriticalRegion();
+
+ /* Return status */
+ return Status;
}
NTSTATUS
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Thu Nov 22 21:38:32 2007
@@ -140,7 +140,6 @@
</directory>
<directory name="cm">
<file>ntfunc.c</file>
- <file>regfile.c</file>
<file>registry.c</file>
<file>regobj.c</file>
</directory>
Modified: trunk/reactos/ntoskrnl/sysfuncs.lst
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/sysfuncs.lst?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/sysfuncs.lst (original)
+++ trunk/reactos/ntoskrnl/sysfuncs.lst Thu Nov 22 21:38:32 2007
@@ -101,7 +101,7 @@
NtLoadDriver 1
NtLoadKey 2
NtLoadKey2 3
-NtLoadKeyEx 7
+NtLoadKeyEx 4
NtLockFile 10
NtLockProductActivationKeys 2
NtLockRegistryKey 1