[NTOSKRNL]

Implement NtUnloadKey2. TODO: Destroy the unlinked hive.
CORE-3094

svn path=/trunk/; revision=68295
This commit is contained in:
Eric Kohl 2015-06-27 19:26:12 +00:00
parent bc5c68db6d
commit 3507ef2ac6
5 changed files with 139 additions and 19 deletions

View file

@ -2127,13 +2127,123 @@ CmLoadKey(IN POBJECT_ATTRIBUTES TargetKey,
return Status;
}
static
BOOLEAN
NTAPI
CmpUnlinkHiveFromMaster(IN PHHIVE Hive,
IN HCELL_INDEX Cell)
{
PCELL_DATA CellData;
HCELL_INDEX LinkCell;
NTSTATUS Status;
DPRINT("CmpUnlinkHiveFromMaster()\n");
/* Get the cell data */
CellData = HvGetCell(Hive, Cell);
if (CellData == NULL)
return FALSE;
/* Get the link cell and release the current cell */
LinkCell = CellData->u.KeyNode.Parent;
HvReleaseCell(Hive, Cell);
/* Remove the link cell from the master hive */
CmpLockHiveFlusherExclusive(CmiVolatileHive);
Status = CmpFreeKeyByCell((PHHIVE)CmiVolatileHive,
LinkCell,
TRUE);
CmpUnlockHiveFlusher(CmiVolatileHive);
if (!NT_SUCCESS(Status))
{
DPRINT1("CmpFreeKeyByCell() failed (Status 0x%08lx)\n", Status);
return FALSE;
}
/* Lock the hive list */
ExAcquirePushLockExclusive(&CmpHiveListHeadLock);
/* Remove this hive */
RemoveEntryList(&((PCMHIVE)Hive)->HiveList);
/* Release the lock */
ExReleasePushLock(&CmpHiveListHeadLock);
return TRUE;
}
NTSTATUS
NTAPI
CmUnloadKey(IN PCM_KEY_CONTROL_BLOCK Kcb,
IN ULONG Flags)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PHHIVE Hive;
PCMHIVE CmHive;
HCELL_INDEX Cell;
DPRINT("CmUnloadKey(%p, %lx)\n", Kcb, Flags);
/* Get the hive */
Hive = Kcb->KeyHive;
Cell = Kcb->KeyCell;
CmHive = (PCMHIVE)Hive;
/* Fail if the key is no a hive root key */
if (Cell != Hive->BaseBlock->RootCell)
{
DPRINT1("Key is not a hive root key!\n");
return STATUS_INVALID_PARAMETER;
}
/* Fail if we try to unload the master hive */
if (CmHive == CmiVolatileHive)
{
DPRINT1("Do not try to unload the master hive!\n");
return STATUS_INVALID_PARAMETER;
}
/* Flush the hive */
CmFlushKey(Kcb, TRUE);
/* Unlink the hive from the master hive */
if (!CmpUnlinkHiveFromMaster(Hive, Cell))
{
DPRINT("CmpUnlinkHiveFromMaster() failed!\n");
/* Remove the unloading flag */
Hive->HiveFlags &= ~HIVE_IS_UNLOADING;
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Clean up information we have on the subkey */
CmpCleanUpSubKeyInfo(Kcb->ParentKcb);
/* Set the KCB in delete mode and remove it */
Kcb->Delete = TRUE;
CmpRemoveKeyControlBlock(Kcb);
if (Flags != REG_FORCE_UNLOAD)
{
/* Release the KCB locks */
CmpReleaseTwoKcbLockByKey(Kcb->ConvKey, Kcb->ParentKcb->ConvKey);
/* Release the hive loading lock */
ExReleasePushLockExclusive(&CmpLoadHiveLock);
}
/* Release hive lock */
CmpUnlockRegistry();
/* Close file handles */
CmpCloseHiveFiles(CmHive);
/* Remove the hive from the hive file list */
CmpRemoveFromHiveFileList(CmHive);
/* FIXME: Destroy the hive */
return STATUS_SUCCESS;
}
ULONG

View file

@ -626,3 +626,19 @@ CmpOpenHiveFiles(IN PCUNICODE_STRING BaseName,
ZwClose(EventHandle);
return STATUS_SUCCESS;
}
VOID
NTAPI
CmpCloseHiveFiles(IN PCMHIVE Hive)
{
ULONG i;
for (i = 0; i < HFILE_TYPE_MAX; i++)
{
if (Hive->FileHandles[i] != NULL)
{
ZwClose(Hive->FileHandles[i]);
Hive->FileHandles[i] = NULL;
}
}
}

View file

@ -2138,7 +2138,6 @@ CmShutdownSystem(VOID)
{
PLIST_ENTRY ListEntry;
PCMHIVE Hive;
ULONG i;
/* Kill the workers */
if (!CmFirstTime) CmpShutdownWorkers();
@ -2153,14 +2152,7 @@ CmShutdownSystem(VOID)
{
Hive = CONTAINING_RECORD(ListEntry, CMHIVE, HiveList);
for (i = 0; i < HFILE_TYPE_MAX; i++)
{
if (Hive->FileHandles[i] != NULL)
{
ZwClose(Hive->FileHandles[i]);
Hive->FileHandles[i] = NULL;
}
}
CmpCloseHiveFiles(Hive);
ListEntry = ListEntry->Flink;
}

View file

@ -1372,7 +1372,6 @@ NTAPI
NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
IN ULONG Flags)
{
#if 0
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING ObjectName;
@ -1381,6 +1380,7 @@ NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
PCM_KEY_BODY KeyBody = NULL;
ULONG ParentConv = 0, ChildConv = 0;
HANDLE Handle;
PAGED_CODE();
/* Validate privilege */
@ -1515,11 +1515,11 @@ NtUnloadKey2(IN POBJECT_ATTRIBUTES TargetKey,
{
if (Flags != REG_FORCE_UNLOAD)
{
/* Release the hive loading lock */
ExReleasePushLockExclusive(&CmpLoadHiveLock);
/* Release two KCBs lock */
CmpReleaseTwoKcbLockByKey(ChildConv, ParentConv);
/* Release the hive loading lock */
ExReleasePushLockExclusive(&CmpLoadHiveLock);
}
/* Unlock the registry */
@ -1532,10 +1532,6 @@ Quickie:
/* Return status */
return Status;
#else
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
#endif
}
NTSTATUS

View file

@ -828,6 +828,12 @@ CmpOpenHiveFiles(
OUT PULONG ClusterSize OPTIONAL
);
VOID
NTAPI
CmpCloseHiveFiles(
IN PCMHIVE Hive
);
NTSTATUS
NTAPI
CmpInitHiveFromFile(