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=31... ============================================================================== --- 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?r... ============================================================================== --- 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;