124 lines
2.5 KiB
C
124 lines
2.5 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
cmapi2.c
|
||
|
||
Abstract:
|
||
|
||
This module contains CM level entry points for the registry,
|
||
particularly those which we don't want to link into tools,
|
||
setup, the boot loader, etc.
|
||
|
||
Author:
|
||
|
||
Bryan M. Willman (bryanwi) 26-Jan-1993
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "cmp.h"
|
||
|
||
#ifdef ALLOC_PRAGMA
|
||
#pragma alloc_text(PAGE,CmDeleteKey)
|
||
#endif
|
||
|
||
|
||
NTSTATUS
|
||
CmDeleteKey(
|
||
IN PCM_KEY_BODY KeyBody
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Delete a registry key, clean up Notify block.
|
||
|
||
Arguments:
|
||
|
||
KeyBody - pointer to key handle object
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS status;
|
||
PCM_KEY_NODE ptarget;
|
||
PHHIVE Hive;
|
||
HCELL_INDEX Cell;
|
||
PCM_KEY_CONTROL_BLOCK KeyControlBlock;
|
||
|
||
|
||
CMLOG(CML_WORKER, CMS_CM) KdPrint(("CmDeleteKey\n"));
|
||
|
||
CmpLockRegistryExclusive();
|
||
|
||
//
|
||
// If already marked for deletion, storage is gone, so
|
||
// do nothing and return success.
|
||
//
|
||
KeyControlBlock = KeyBody->KeyControlBlock;
|
||
if (KeyControlBlock->Delete == TRUE) {
|
||
status = STATUS_SUCCESS;
|
||
goto Exit;
|
||
}
|
||
|
||
ptarget = KeyControlBlock->KeyNode;
|
||
|
||
if ( ((ptarget->SubKeyCounts[Stable] +
|
||
ptarget->SubKeyCounts[Volatile]) == 0) &&
|
||
((ptarget->Flags & KEY_NO_DELETE) == 0))
|
||
{
|
||
//
|
||
// Cell is NOT marked NO_DELETE and does NOT have children
|
||
// Send Notification while key still present, if delete fails,
|
||
// we'll have sent a spurious notify, that doesn't matter
|
||
// Delete the actual storage
|
||
//
|
||
Hive = KeyControlBlock->KeyHive;
|
||
Cell = KeyControlBlock->KeyCell;
|
||
|
||
CmpReportNotify(
|
||
KeyControlBlock->FullName,
|
||
Hive,
|
||
Cell,
|
||
REG_NOTIFY_CHANGE_NAME
|
||
);
|
||
|
||
status = CmpFreeKeyByCell(Hive, Cell, TRUE);
|
||
|
||
if (NT_SUCCESS(status)) {
|
||
//
|
||
// post any waiting notifies
|
||
//
|
||
CmpFlushNotify(KeyBody);
|
||
|
||
//
|
||
// Remove kcb from kcb list/tree, but do NOT
|
||
// free its storage, CmDelete will do that when
|
||
// the last refering handle is closed
|
||
//
|
||
CmpRemoveKeyControlBlock(KeyControlBlock);
|
||
KeyControlBlock->KeyHive = NULL;
|
||
KeyControlBlock->KeyCell = HCELL_NIL;
|
||
KeyControlBlock->KeyNode = NULL;
|
||
|
||
KeyControlBlock->Delete = TRUE;
|
||
}
|
||
|
||
} else {
|
||
|
||
status = STATUS_CANNOT_DELETE;
|
||
|
||
}
|
||
|
||
Exit:
|
||
CmpUnlockRegistry();
|
||
return status;
|
||
}
|