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;
|
|||
|
}
|