- Make NtUnloadKey call a newer version of the NTAPI - NtUnloadKey2.

- Implement NtUnloadKey2 as a wrapper around internal CM API - CmUnloadKey.
- Stub CmUnloadKey.
- Fix a typo in ps/process.c comments.

svn path=/trunk/; revision=42591
This commit is contained in:
Aleksey Bragin 2009-08-10 13:44:54 +00:00
parent f82ee64534
commit 158a642e6b
3 changed files with 171 additions and 5 deletions

View file

@ -1493,3 +1493,12 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
if (KeyHandle) ZwClose(KeyHandle);
return Status;
}
NTSTATUS
NTAPI
CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
IN ULONG Flags)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}

View file

@ -1122,8 +1122,7 @@ NTSTATUS
NTAPI
NtUnloadKey(IN POBJECT_ATTRIBUTES KeyObjectAttributes)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
return NtUnloadKey2(KeyObjectAttributes, 0);
}
NTSTATUS
@ -1131,8 +1130,166 @@ NTAPI
NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
IN ULONG Flags)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status = STATUS_SUCCESS;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ObjectName;
CM_PARSE_CONTEXT ParseContext = {0};
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
PCM_KEY_BODY KeyBody = NULL;
ULONG ParentConv = 0, ChildConv = 0;
HANDLE Handle;
PAGED_CODE();
/* Validate privilege */
if (!SeSinglePrivilegeCheck(SeRestorePrivilege, PreviousMode))
{
/* Fail */
DPRINT1("Restore Privilege missing!\n");
return STATUS_PRIVILEGE_NOT_HELD;
}
/* Check for user-mode caller */
if (PreviousMode != KernelMode)
{
/* Prepare to probe parameters */
_SEH2_TRY
{
/* Probe object attributes */
ProbeForRead(TargetKey,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectAttributes = *TargetKey;
/* Probe the string */
ProbeForReadUnicodeString(&TargetKey->ObjectName);
ObjectName = *TargetKey->ObjectName;
ProbeForRead(ObjectName.Buffer,
ObjectName.Length,
sizeof(WCHAR));
ObjectAttributes.ObjectName = &ObjectName;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Get the error code */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if(!NT_SUCCESS(Status)) return Status;
}
else
{
/* Save the target attributes directly */
ObjectAttributes = *TargetKey;
}
/* Setup the parse context */
ParseContext.CreateOperation = TRUE;
ParseContext.CreateOptions = REG_OPTION_BACKUP_RESTORE;
/* Do the create */
Status = ObOpenObjectByName(&ObjectAttributes,
CmpKeyObjectType,
KernelMode,
NULL,
KEY_WRITE,
&ParseContext,
&Handle);
/* Return if failure encountered */
if (!NT_SUCCESS(Status)) return Status;
/* Reference it */
Status = ObReferenceObjectByHandle(Handle,
KEY_WRITE,
CmpKeyObjectType,
KernelMode,
(PVOID *)&KeyBody,
NULL);
/* Close the handle */
ZwClose(Handle);
/* Return if failure encountered */
if (!NT_SUCCESS(Status)) return Status;
/* Acquire the lock depending on flags */
if (Flags == REG_FORCE_UNLOAD)
{
/* Lock registry exclusively */
CmpLockRegistryExclusive();
}
else
{
/* Lock registry */
CmpLockRegistry();
/* Acquire the hive loading lock */
ExAcquirePushLockExclusive(&CmpLoadHiveLock);
/* Lock parent and child */
if (KeyBody->KeyControlBlock->ParentKcb)
ParentConv = KeyBody->KeyControlBlock->ParentKcb->ConvKey;
else
ParentConv = KeyBody->KeyControlBlock->ConvKey;
ChildConv = KeyBody->KeyControlBlock->ConvKey;
CmpAcquireTwoKcbLocksExclusiveByKey(ChildConv, ParentConv);
}
/* Check if it's being deleted already */
if (KeyBody->KeyControlBlock->Delete)
{
/* Return appropriate status */
Status = STATUS_KEY_DELETED;
goto Quickie;
}
/* Check if it's a readonly key */
if (KeyBody->KeyControlBlock->ExtFlags & CM_KCB_READ_ONLY_KEY)
{
/* Return appropriate status */
Status = STATUS_ACCESS_DENIED;
goto Quickie;
}
/* Call the internal API */
Status = CmUnloadKey(KeyBody->KeyControlBlock,
Flags);
/* Check if we failed, but really need to succeed */
if ((Status == STATUS_CANNOT_DELETE) && (Flags == REG_FORCE_UNLOAD))
{
/* TODO: We should perform another attempt here */
ASSERT(FALSE);
}
/* If CmUnloadKey failed we need to unlock registry ourselves */
if (!NT_SUCCESS(Status))
{
if (Flags != REG_FORCE_UNLOAD)
{
/* Release the hive loading lock */
ExReleasePushLockExclusive(&CmpLoadHiveLock);
/* Release two KCBs lock */
CmpReleaseTwoKcbLockByKey(ChildConv, ParentConv);
}
/* Unlock the registry */
CmpUnlockRegistry();
}
Quickie:
/* Dereference the key */
ObDereferenceObject(KeyBody);
/* Return status */
return Status;
}
NTSTATUS

View file

@ -451,7 +451,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
/* Check if we have a parent */
if (Parent)
{
/* Ineherit PID and Hard Error Processing */
/* Inherit PID and Hard Error Processing */
Process->InheritedFromUniqueProcessId = Parent->UniqueProcessId;
Process->DefaultHardErrorProcessing = Parent->
DefaultHardErrorProcessing;