From c76fa603f3697d0ce563d9890b44e61c367a880e Mon Sep 17 00:00:00 2001 From: Aleksey Bragin Date: Fri, 7 Dec 2007 16:11:02 +0000 Subject: [PATCH] - 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. svn path=/trunk/; revision=31056 --- reactos/ntoskrnl/cm/regobj.c | 50 -------- reactos/ntoskrnl/config/cmkcbncb.c | 9 +- reactos/ntoskrnl/config/cmparse.c | 45 ++++++- reactos/ntoskrnl/config/cmsysini.c | 189 +++++++++++++++++------------ 4 files changed, 160 insertions(+), 133 deletions(-) diff --git a/reactos/ntoskrnl/cm/regobj.c b/reactos/ntoskrnl/cm/regobj.c index 4a02a2c6eef..8e18c890078 100644 --- a/reactos/ntoskrnl/cm/regobj.c +++ b/reactos/ntoskrnl/cm/regobj.c @@ -815,56 +815,6 @@ CmpParseKey(IN PVOID ParsedObject, 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, diff --git a/reactos/ntoskrnl/config/cmkcbncb.c b/reactos/ntoskrnl/config/cmkcbncb.c index 6d5aa3d93cc..6afa09542d4 100644 --- a/reactos/ntoskrnl/config/cmkcbncb.c +++ b/reactos/ntoskrnl/config/cmkcbncb.c @@ -812,7 +812,12 @@ NTAPI 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 */ } - diff --git a/reactos/ntoskrnl/config/cmparse.c b/reactos/ntoskrnl/config/cmparse.c index 6a5b3ad9de2..e8b6b4a4c33 100644 --- a/reactos/ntoskrnl/config/cmparse.c +++ b/reactos/ntoskrnl/config/cmparse.c @@ -165,7 +165,11 @@ CmpDoCreateChild(IN PHHIVE Hive, 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 @@ CmpDoCreateChild(IN PHHIVE Hive, 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 @@ CmpDoOpen(IN PHHIVE Hive, /* 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 @@ CmpCreateLinkNode(IN PHHIVE Hive, /* 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 @@ CmpCreateLinkNode(IN PHHIVE Hive, /* 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 @@ CmpParseKey2(IN PVOID ParseObject, /* 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 @@ CmpParseKey2(IN PVOID ParseObject, 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; diff --git a/reactos/ntoskrnl/config/cmsysini.c b/reactos/ntoskrnl/config/cmsysini.c index 892d110b90f..53d90ad3933 100644 --- a/reactos/ntoskrnl/config/cmsysini.c +++ b/reactos/ntoskrnl/config/cmsysini.c @@ -72,6 +72,96 @@ CmpRosGetHardwareHive(OUT PULONG Length) 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 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, 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 @@ CmpLinkHiveToMaster(IN PUNICODE_STRING LinkName, 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; + /* ReactOS Hack: Keep alive */ + Status = ObReferenceObjectByHandle(KeyHandle, + 0, + CmpKeyObjectType, + KernelMode, + (PVOID*)&KeyBody, + NULL); + ASSERT(NT_SUCCESS(Status)); - /* Reference the new key */ - ObReferenceObject(NewKey); - - /* Link this key to the parent */ - InsertTailList(&ParentKey->KeyControlBlock->KeyBodyListHead, &NewKey->KeyBodyList); + /* Close the extra handle */ + ZwClose(KeyHandle); return STATUS_SUCCESS; } @@ -767,7 +792,7 @@ CmpCreateObjectTypes(VOID) ObjectTypeInitializer.ParseProcedure = CmpParseKey; ObjectTypeInitializer.SecurityProcedure = CmpSecurityMethod; ObjectTypeInitializer.QueryNameProcedure = CmpQueryKeyName; - //ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject; + ObjectTypeInitializer.CloseProcedure = CmpCloseKeyObject; ObjectTypeInitializer.SecurityRequired = TRUE; /* Create it */ @@ -892,10 +917,13 @@ CmpCreateRegistryRoot(VOID) /* 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, NULL, @@ -928,7 +956,7 @@ CmpGetRegistryPath(IN PWCHAR ConfigPath) 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 @@ CmpLoadHiveThread(IN PVOID StartContext) &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;