mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- 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
This commit is contained in:
parent
d709944d3b
commit
c76fa603f3
4 changed files with 160 additions and 133 deletions
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue