mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 08:55:19 +00:00
- 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:
parent
f82ee64534
commit
158a642e6b
3 changed files with 171 additions and 5 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue