Author: fireball
Date: Fri Dec 7 19:11:02 2007
New Revision: 31056
URL:
http://svn.reactos.org/svn/reactos?rev=31056&view=rev
Log:
- Fix LiveCD.
- Move CmpQueryKeyName and CmpDeleteKeyObject to config, and actually make
CmpDeleteKeyObject do something.
- Partly implement CmpCloseKeyObject.
- Rewrite CmpLinkHiveToMaster to use ObOpenObjectByName instead of Ob-hacks, and add
proper call in new parse routine to handle link node creation. We don't use Ob hacks
for this anymore!
- Setup the CM_KEY_BODY when required.
- Call (and partly implement) EnlistKeyBodyWithKCB when required.
Modified:
trunk/reactos/ntoskrnl/cm/regobj.c
trunk/reactos/ntoskrnl/config/cmkcbncb.c
trunk/reactos/ntoskrnl/config/cmparse.c
trunk/reactos/ntoskrnl/config/cmsysini.c
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 Fri Dec 7 19:11:02 2007
@@ -815,56 +815,6 @@
return(STATUS_SUCCESS);
}
-VOID
-NTAPI
-CmpDeleteKeyObject(PVOID DeletedObject)
-{
- PCM_KEY_BODY KeyObject;
- REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo;
- REG_POST_OPERATION_INFORMATION PostOperationInfo;
- NTSTATUS Status;
-
- DPRINT("Delete key object (%p)\n", DeletedObject);
-
- KeyObject = (PCM_KEY_BODY) DeletedObject;
-
-
- PostOperationInfo.Object = (PVOID)KeyObject;
- KeyHandleCloseInfo.Object = (PVOID)KeyObject;
- Status = CmiCallRegisteredCallbacks(RegNtPreKeyHandleClose,
&KeyHandleCloseInfo);
- if (!NT_SUCCESS(Status))
- {
- PostOperationInfo.Status = Status;
- CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
- return;
- }
-
- /* Acquire hive lock */
- KeEnterCriticalRegion();
- ExAcquireResourceExclusiveLite(&CmpRegistryLock, TRUE);
-
- ASSERT((KeyObject->KeyControlBlock->Delete) == FALSE);
-
- ExReleaseResourceLite(&CmpRegistryLock);
- KeLeaveCriticalRegion();
- PostOperationInfo.Status = STATUS_SUCCESS;
- CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
-}
-
-NTSTATUS
-NTAPI
-CmpQueryKeyName(PVOID ObjectBody,
- IN BOOLEAN HasName,
- POBJECT_NAME_INFORMATION ObjectNameInfo,
- ULONG Length,
- PULONG ReturnLength,
- IN KPROCESSOR_MODE PreviousMode)
-{
- DPRINT1("CmpQueryKeyName() called\n");
- while (TRUE);
- return STATUS_SUCCESS;
-}
-
static NTSTATUS
CmiGetLinkTarget(PCMHIVE RegistryHive,
PCM_KEY_NODE KeyCell,
Modified: trunk/reactos/ntoskrnl/config/cmkcbncb.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/config/cmkcbncb.c…
==============================================================================
--- trunk/reactos/ntoskrnl/config/cmkcbncb.c (original)
+++ trunk/reactos/ntoskrnl/config/cmkcbncb.c Fri Dec 7 19:11:02 2007
@@ -812,7 +812,12 @@
EnlistKeyBodyWithKCB(IN PCM_KEY_BODY KeyBody,
IN ULONG Flags)
{
- ASSERT(FALSE);
-}
-
-
+ /* Sanity check */
+ ASSERT(KeyBody->KeyControlBlock != NULL);
+
+ /* Initialize the list entry */
+ InitializeListHead(&KeyBody->KeyBodyList);
+
+ /* FIXME: Implement once we don't link parents to children anymore */
+}
+
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 Fri Dec 7 19:11:02 2007
@@ -165,7 +165,11 @@
0,
Object);
if (!NT_SUCCESS(Status)) goto Quickie;
+
+ /* Setup the key body */
KeyBody = (PCM_KEY_BODY)(*Object);
+ KeyBody->Type = TAG('k', 'y', '0', '2');
+ KeyBody->KeyControlBlock = NULL;
/* Check if we had a class */
if (ParseContext->Class.Length > 0)
@@ -232,7 +236,12 @@
ASSERT(Kcb->RefCount == 1);
/* Now fill out the Cm object */
+ KeyBody->NotifyBlock = NULL;
+ KeyBody->ProcessID = PsGetCurrentProcessId();
KeyBody->KeyControlBlock = Kcb;
+
+ /* Link it with the KCB */
+ EnlistKeyBodyWithKCB(KeyBody, 0);
Quickie:
/* Check if we got here because of failure */
@@ -484,6 +493,12 @@
/* Get the key body and fill it out */
KeyBody = (PCM_KEY_BODY)(*Object);
KeyBody->KeyControlBlock = Kcb;
+ KeyBody->Type = TAG('k', 'y', '0', '2');
+ KeyBody->ProcessID = PsGetCurrentProcessId();
+ KeyBody->NotifyBlock = NULL;
+
+ /* Link to the KCB */
+ EnlistKeyBodyWithKCB(KeyBody, 0);
}
else
{
@@ -703,6 +718,7 @@
/* Update the timestamp */
KeQuerySystemTime(&TimeStamp);
KeyNode->LastWriteTime = TimeStamp;
+ KeyBody->KeyControlBlock->ParentKcb->KcbLastWriteTime = TimeStamp;
/* Check if we need to update name maximum */
if (KeyNode->MaxNameLen < Name.Length)
@@ -718,6 +734,14 @@
/* Update it */
KeyNode->MaxClassLen = Context->Class.Length;
}
+
+ /* Release the cell */
+ HvReleaseCell(Hive, Cell);
+ }
+ else
+ {
+ /* Release the link cell */
+ HvReleaseCell(Hive, LinkCell);
}
Exit:
@@ -986,11 +1010,22 @@
/* Check if this was the last key for a create */
if ((Last) && (ParseContext))
{
+ PCM_KEY_BODY KeyBody;
+
/* Check if we're doing a link node */
if (ParseContext->CreateLink)
{
/* The only thing we should see */
- DPRINT1("Expected: Creating new link\n");
+ Status = CmpCreateLinkNode(Hive,
+ Cell,
+ AccessState,
+ NextName,
+ AccessMode,
+ Attributes,
+ ParseContext,
+ ParentKcb,
+ Object);
+ DPRINT1("Link created: %lx\n", Status);
}
else
{
@@ -998,6 +1033,14 @@
DPRINT1("Unexpected: Creating new child\n");
while (TRUE);
}
+
+ /* Check for reparse (in this case, someone beat us) */
+ if (Status == STATUS_REPARSE) break;
+
+ /* ReactOS Hack: Link this key to the parent */
+ KeyBody = (PCM_KEY_BODY)*Object;
+ InsertTailList(&ParentKcb->KeyBodyListHead,
+ &KeyBody->KeyBodyList);
/* Update disposition */
ParseContext->Disposition = REG_CREATED_NEW_KEY;
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 Fri Dec 7 19:11:02 2007
@@ -72,6 +72,96 @@
return (PVOID)((MdBlock->BasePage << PAGE_SHIFT) | KSEG0_BASE);
}
+VOID
+NTAPI
+CmpDeleteKeyObject(PVOID DeletedObject)
+{
+ PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)DeletedObject;
+ PCM_KEY_CONTROL_BLOCK Kcb;
+ REG_KEY_HANDLE_CLOSE_INFORMATION KeyHandleCloseInfo;
+ REG_POST_OPERATION_INFORMATION PostOperationInfo;
+ NTSTATUS Status;
+ PAGED_CODE();
+
+ /* First off, prepare the handle close information callback */
+ PostOperationInfo.Object = KeyBody;
+ KeyHandleCloseInfo.Object = KeyBody;
+ Status = CmiCallRegisteredCallbacks(RegNtPreKeyHandleClose,
+ &KeyHandleCloseInfo);
+ if (!NT_SUCCESS(Status))
+ {
+ /* If we failed, notify the post routine */
+ PostOperationInfo.Status = Status;
+ CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
+ return;
+ }
+
+ /* Acquire hive lock */
+ CmpLockRegistry();
+
+ /* Make sure this is a valid key body */
+ if (KeyBody->Type == TAG('k', 'y', '0', '2'))
+ {
+ /* Get the KCB */
+ Kcb = KeyBody->KeyControlBlock;
+ if (Kcb)
+ {
+ /* Delist the key (once new parse routines are used) */
+ //DelistKeyBodyFromKCB(KeyBody, FALSE);
+ }
+
+ /* Dereference the KCB */
+ CmpDelayDerefKeyControlBlock(Kcb);
+
+ }
+
+ /* Release the registry lock */
+ CmpUnlockRegistry();
+
+ /* Do the post callback */
+ PostOperationInfo.Status = STATUS_SUCCESS;
+ CmiCallRegisteredCallbacks(RegNtPostKeyHandleClose, &PostOperationInfo);
+}
+
+VOID
+NTAPI
+CmpCloseKeyObject(IN PEPROCESS Process OPTIONAL,
+ IN PVOID Object,
+ IN ACCESS_MASK GrantedAccess,
+ IN ULONG ProcessHandleCount,
+ IN ULONG SystemHandleCount)
+{
+ PCM_KEY_BODY KeyBody = (PCM_KEY_BODY)Object;
+ PAGED_CODE();
+
+ /* Don't do anything if we're not the last handle */
+ if (SystemHandleCount > 1) return;
+
+ /* Make sure we're a valid key body */
+ if (KeyBody->Type == TAG('k', 'y', '0', '2'))
+ {
+ /* Don't do anything if we don't have a notify block */
+ if (!KeyBody->NotifyBlock) return;
+
+ /* This shouldn't happen yet */
+ ASSERT(FALSE);
+ }
+}
+
+NTSTATUS
+NTAPI
+CmpQueryKeyName(IN PVOID ObjectBody,
+ IN BOOLEAN HasName,
+ IN OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
+ IN ULONG Length,
+ OUT PULONG ReturnLength,
+ IN KPROCESSOR_MODE PreviousMode)
+{
+ DPRINT1("CmpQueryKeyName() called\n");
+ while (TRUE);
+ return STATUS_SUCCESS;
+}
+
NTSTATUS
NTAPI
CmpInitHiveFromFile(IN PCUNICODE_STRING HiveName,
@@ -491,14 +581,10 @@
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
OBJECT_ATTRIBUTES ObjectAttributes;
- UNICODE_STRING RemainingPath;
- PCM_KEY_BODY ParentKey;
- PCM_KEY_BODY NewKey;
NTSTATUS Status;
- UNICODE_STRING ObjectName;
- OBJECT_CREATE_INFORMATION ObjectCreateInfo;
CM_PARSE_CONTEXT ParseContext = {0};
HANDLE KeyHandle;
+ PCM_KEY_BODY KeyBody;
PAGED_CODE();
/* Setup the object attributes */
@@ -533,83 +619,22 @@
KEY_READ | KEY_WRITE,
(PVOID)&ParseContext,
&KeyHandle);
-
- /* Capture all the info */
- Status = ObpCaptureObjectAttributes(&ObjectAttributes,
- KernelMode,
- FALSE,
- &ObjectCreateInfo,
- &ObjectName);
if (!NT_SUCCESS(Status)) return Status;
-
- /* Do the parse */
- Status = CmFindObject(&ObjectCreateInfo,
- &ObjectName,
- (PVOID*)&ParentKey,
- &RemainingPath,
- CmpKeyObjectType,
- NULL,
- NULL);
-
- /* Let go of captured attributes and name */
- ObpReleaseCapturedAttributes(&ObjectCreateInfo);
- if (ObjectName.Buffer) ObpFreeObjectNameBuffer(&ObjectName);
-
- /* Get out of here if we failed */
- if (!NT_SUCCESS(Status)) return Status;
-
- /* Scan for no name */
- if (!(RemainingPath.Length) || (RemainingPath.Buffer[0] == UNICODE_NULL))
- {
- /* Fail */
- ObDereferenceObject(ParentKey);
- return STATUS_OBJECT_NAME_NOT_FOUND;
- }
-
- /* Scan for leading backslash */
- while ((RemainingPath.Length) &&
- (*RemainingPath.Buffer == OBJ_NAME_PATH_SEPARATOR))
- {
- /* Ignore it */
- RemainingPath.Length -= sizeof(WCHAR);
- RemainingPath.MaximumLength -= sizeof(WCHAR);
- RemainingPath.Buffer++;
- }
-
- /* Create the link node */
- Status = CmpCreateLinkNode(ParentKey->KeyControlBlock->KeyHive,
- ParentKey->KeyControlBlock->KeyCell,
- NULL,
- RemainingPath,
- KernelMode,
- 0,
- &ParseContext,
- ParentKey->KeyControlBlock,
- (PVOID*)&NewKey);
- if (!NT_SUCCESS(Status))
- {
- /* Failed */
- DPRINT1("CmpLinkHiveToMaster failed: %lx\n", Status);
- ObDereferenceObject(ParentKey);
- return Status;
- }
-
- /* Free the create information */
-
ObpFreeAndReleaseCapturedAttributes(OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo);
- OBJECT_TO_OBJECT_HEADER(NewKey)->ObjectCreateInfo = NULL;
/* Mark the hive as clean */
RegistryHive->Hive.DirtyFlag = FALSE;
- /* Update KCB information */
- NewKey->KeyControlBlock->KeyCell =
RegistryHive->Hive.BaseBlock->RootCell;
- NewKey->KeyControlBlock->KeyHive = &RegistryHive->Hive;
-
- /* Reference the new key */
- ObReferenceObject(NewKey);
-
- /* Link this key to the parent */
- InsertTailList(&ParentKey->KeyControlBlock->KeyBodyListHead,
&NewKey->KeyBodyList);
+ /* ReactOS Hack: Keep alive */
+ Status = ObReferenceObjectByHandle(KeyHandle,
+ 0,
+ CmpKeyObjectType,
+ KernelMode,
+ (PVOID*)&KeyBody,
+ NULL);
+ ASSERT(NT_SUCCESS(Status));
+
+ /* Close the extra handle */
+ ZwClose(KeyHandle);
return STATUS_SUCCESS;
}
@@ -767,7 +792,7 @@
ObjectTypeInitializer.ParseProcedure = CmpParseKey;
ObjectTypeInitializer.SecurityProcedure = CmpSecurityMethod;
ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName;
- //ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
+ ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject;
ObjectTypeInitializer.SecurityRequired = TRUE;
/* Create it */
@@ -892,9 +917,12 @@
/* Initialize the object */
RootKey->KeyControlBlock = Kcb;
- RootKey->Type = TAG('k', 'v', '0', '2');
+ RootKey->Type = TAG('k', 'y', '0', '2');
RootKey->NotifyBlock = NULL;
RootKey->ProcessID = PsGetCurrentProcessId();
+
+ /* Link with KCB */
+ EnlistKeyBodyWithKCB(RootKey, 0);
/* Insert the key into the namespace */
Status = ObInsertObject(RootKey,
@@ -928,7 +956,7 @@
PKEY_VALUE_PARTIAL_INFORMATION ValueInfo;
UNICODE_STRING KeyName =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\HARDWARE");
UNICODE_STRING ValueName = RTL_CONSTANT_STRING(L"InstallPath");
- ULONG BufferSize,ResultSize;
+ ULONG BufferSize, ResultSize;
/* Check if we are booted in setup */
if (ExpInTextModeSetup)
@@ -1056,7 +1084,8 @@
&CmHive,
&CmpMachineHiveList[i].Allocate,
0);
- if (!(NT_SUCCESS(Status)) || !(CmHive->FileHandles[HFILE_TYPE_LOG]))
+ if (!(NT_SUCCESS(Status)) ||
+ (!(CmHive->FileHandles[HFILE_TYPE_LOG]) && !(CmpMiniNTBoot))) //
hak
{
/* We failed or couldn't get a log file, raise a hard error */
ErrorParameters = &FileName;