test: cmapi2.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# cmapi2.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1991  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     cmapi2.c
    00008
    00009 Abstract:
    00010
    00011     This module contains CM level entry points for the registry,
    00012     particularly those which we don't want to link into tools,
    00013     setup, the boot loader, etc.
    00014
    00015 Author:
    00016
    00017     Bryan M. Willman (bryanwi) 26-Jan-1993
    00018
    00019 Revision History:
    00020
    00021 --*/
    00022
    00023 #include "cmp.h"
    00024
    00025 #ifdef ALLOC_PRAGMA
    00026 #pragma alloc_text(PAGE,CmDeleteKey)
    00027 #endif
    00028
    00029
    00030 NTSTATUS
    00031 CmDeleteKey(
    00032     IN PCM_KEY_BODY KeyBody
    00033     )
    00034 /*++
    00035
    00036 Routine Description:
    00037
    00038     Delete a registry key, clean up Notify block.
    00039
    00040 Arguments:
    00041
    00042     KeyBody - pointer to key handle object
    00043
    00044 Return Value:
    00045
    00046     NTSTATUS
    00047
    00048 --*/
    00049 {
    00050     NTSTATUS    status;
    00051     PCM_KEY_NODE  ptarget;
    00052     PHHIVE      Hive;
    00053     HCELL_INDEX Cell;
    00054     PCM_KEY_CONTROL_BLOCK   KeyControlBlock;
    00055
    00056     CMLOG(CML_WORKER, CMS_CM) KdPrint(("CmDeleteKey\n"));
    00057
    00058     CmpLockRegistryExclusive();
    00059
    00060     //
    00061     // If already marked for deletion, storage is gone, so
    00062     // do nothing and return success.
    00063     //
    00064     KeyControlBlock = KeyBody->KeyControlBlock;
    00065
    00066     if (KeyControlBlock->Delete == TRUE) {
    00067         status = STATUS_SUCCESS;
    00068         goto Exit;
    00069     }
    00070
    00071     // Mark the hive as read only
    00072     CmpMarkAllBinsReadOnly(KeyControlBlock->KeyHive);
    00073
    00074     ptarget = KeyControlBlock->KeyNode;
    00075
    00076     if ( ((ptarget->SubKeyCounts[Stable] +
    00077            ptarget->SubKeyCounts[Volatile]) == 0) &&
    00078          ((ptarget->Flags & KEY_NO_DELETE) == 0))
    00079     {
    00080         //
    00081         // Cell is NOT marked NO_DELETE and does NOT have children
    00082         // Send Notification while key still present, if delete fails,
    00083         //   we'll have sent a spurious notify, that doesn't matter
    00084         // Delete the actual storage
    00085         //
    00086         Hive = KeyControlBlock->KeyHive;
    00087         Cell = KeyControlBlock->KeyCell;
    00088
    00089         CmpReportNotify(
    00090             KeyControlBlock,
    00091             Hive,
    00092             Cell,
    00093             REG_NOTIFY_CHANGE_NAME
    00094             );
    00095
    00096         status = CmpFreeKeyByCell(Hive, Cell, TRUE);
    00097
    00098         if (NT_SUCCESS(status)) {
    00099             //
    00100             // post any waiting notifies
    00101             //
    00102 #ifdef KCB_TO_KEYBODY_LINK
    00103             CmpFlushNotifiesOnKeyBodyList(KeyControlBlock);
    00104 #else
    00105             CmpFlushNotify(KeyBody);
    00106 #endif
    00107
    00108             //
    00109             // Remove kcb out of cache, but do NOT
    00110             // free its storage, CmDelete will do that when
    00111             // the RefCount becomes zero.
    00112             //
    00113             // There are two things that can hold the RefCount non-zero.
    00114             //
    00115             // 1. open handles for this key
    00116             // 2. Fake subKeys that are still in DelayClose.
    00117             //
    00118             // At this point, we have no way of deleting the fake subkeys from cache
    00119             // unless we do a search for the whole cache, which is too expensive.
    00120             // Thus, we decide to either let the fake keys age out of cache or when
    00121             // someone is doing the lookup for the fake key, then we delete it at that point.
    00122             // See routine CmpCacheLookup in cmparse.c for more details.
    00123             //
    00124             // If the parent has the subkey info or hint cached, free it.
    00125             // Again, registry is locked exclusively, no need to lock KCB.
    00126             //
    00127             ASSERT_CM_LOCK_OWNED_EXCLUSIVE();
    00128             CmpCleanUpSubKeyInfo(KeyControlBlock->ParentKcb);
    00129             KeyControlBlock->Delete = TRUE;
    00130             CmpRemoveKeyControlBlock(KeyControlBlock);
    00131             KeyControlBlock->KeyCell = HCELL_NIL;
    00132             KeyControlBlock->KeyNode = NULL;
    00133         }
    00134
    00135     } else {
    00136
    00137         status = STATUS_CANNOT_DELETE;
    00138
    00139     }
    00140
    00141 Exit:
    00142     CmpUnlockRegistry();
    00143
    00144     // Mark the hive as read only
    00145     CmpMarkAllBinsReadOnly(KeyControlBlock->KeyHive);
    00146
    00147     return status;
    00148 }