コード例 #1
0
ファイル: cmkcbncb.c プロジェクト: HBelusca/NasuTek-Odyssey
VOID
NTAPI
CmpCleanUpKcbValueCache(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
    PULONG_PTR CachedList;
    ULONG i;

    /* Sanity check */
    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
           (CmpTestRegistryLockExclusive() == TRUE));

    /* Check if the value list is cached */
    if (CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList))
    {
        /* Get the cache list */
        CachedList = (PULONG_PTR)CMP_GET_CACHED_DATA(Kcb->ValueCache.ValueList);
        for (i = 0; i < Kcb->ValueCache.Count; i++)
        {
            /* Check if this cell is cached */
            if (CMP_IS_CELL_CACHED(CachedList[i]))
            {
                /* Free it */
                CmpFree((PVOID)CMP_GET_CACHED_CELL(CachedList[i]), 0);
            }
        }

        /* Now free the list */
        CmpFree((PVOID)CMP_GET_CACHED_CELL(Kcb->ValueCache.ValueList), 0);
        Kcb->ValueCache.ValueList = HCELL_NIL;
    }
    else if (Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND)
    {
        /* This is a sym link, check if there's only one reference left */
        if ((Kcb->ValueCache.RealKcb->RefCount == 1) &&
                !(Kcb->ValueCache.RealKcb->Delete))
        {
            /* Disable delay close for the KCB */
            Kcb->ValueCache.RealKcb->ExtFlags |= CM_KCB_NO_DELAY_CLOSE;
        }

        /* Dereference the KCB */
        CmpDelayDerefKeyControlBlock(Kcb->ValueCache.RealKcb);
        Kcb->ExtFlags &= ~CM_KCB_SYM_LINK_FOUND;
    }
}
コード例 #2
0
ファイル: cmkcbncb.c プロジェクト: HBelusca/NasuTek-Odyssey
VOID
NTAPI
CmpCleanUpKcbCacheWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb,
                           IN BOOLEAN LockHeldExclusively)
{
    PCM_KEY_CONTROL_BLOCK Parent;
    PAGED_CODE();

    /* Sanity checks */
    ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
           (CmpTestRegistryLockExclusive() == TRUE));
    ASSERT(Kcb->RefCount == 0);

    /* Cleanup the value cache */
    CmpCleanUpKcbValueCache(Kcb);

    /* Dereference the NCB */
    CmpDereferenceNameControlBlockWithLock(Kcb->NameBlock);

    /* Check if we have an index hint block and free it */
    if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT) CmpFree(Kcb->IndexHint, 0);

    /* Check if we were already deleted */
    Parent = Kcb->ParentKcb;
    if (!Kcb->Delete) CmpRemoveKeyControlBlock(Kcb);

    /* Set invalid KCB signature */
    Kcb->Signature = CM_KCB_INVALID_SIGNATURE;

    /* Free the KCB as well */
    CmpFreeKeyControlBlock(Kcb);

    /* Check if we have a parent */
    if (Parent)
    {
        /* Dereference the parent */
        LockHeldExclusively ?
        CmpDereferenceKeyControlBlockWithLock(Parent,LockHeldExclusively) :
        CmpDelayDerefKeyControlBlock(Parent);
    }
}
コード例 #3
0
ファイル: cmdelete.c プロジェクト: BaoYu0721/WRK-1.2
VOID
CmpDeleteKeyObject(
    IN  PVOID   Object
    )
/*++

Routine Description:

    This routine interfaces to the NT Object Manager.  It is invoked when
    the last reference to a particular Key object (or Key Root object)
    is destroyed.

    If the Key object going away holds the last reference to
    the extension it is associated with, that extension is destroyed.

Arguments:

    Object - supplies a pointer to a KeyRoot or Key, thus -> KEY_BODY.

Return Value:

    NONE.

--*/
{
    PCM_KEY_CONTROL_BLOCK   KeyControlBlock;
    PCM_KEY_BODY            KeyBody;
    PCMHIVE                 CmHive = NULL;
    BOOLEAN                 DoUnloadCheck = FALSE;

    CM_PAGED_CODE();

    CmKdPrintEx((DPFLTR_CONFIG_ID,CML_FLOW,"CmpDeleteKeyObject: Object = %p\n", Object));

    //
    // HandleClose callback
    //
    if ( CmAreCallbacksRegistered() ) {
        REG_KEY_HANDLE_CLOSE_INFORMATION  KeyHandleCloseInfo;
       
        KeyHandleCloseInfo.Object = Object;

        CmpCallCallBacks(RegNtPreKeyHandleClose,&KeyHandleCloseInfo,TRUE,RegNtPostKeyHandleClose,Object);
    }

    KeyBody = (PCM_KEY_BODY)Object;

    BEGIN_LOCK_CHECKPOINT;

    CmpLockRegistry();

    if (KeyBody->Type==KEY_BODY_TYPE) {
        KeyControlBlock = KeyBody->KeyControlBlock;

        //
        // the keybody should be initialized; when kcb is null, something went wrong
        // between the creation and the dereferenciation of the object
        //
        if( KeyControlBlock != NULL ) {
            //
            // Clean up any outstanding notifies attached to the KeyBody
            //
            CmpFlushNotify(KeyBody,FALSE);

            //
            // Remove our reference to the KeyControlBlock, clean it up, perform any
            // pend-till-final-close operations.
            //
            // NOTE: Delete notification is seen at the parent of the deleted key,
            //       not the deleted key itself.  If any notify was outstanding on
            //       this key, it was cleared away above us.  Only parent/ancestor
            //       keys will see the report.
            //
            //
            // The dereference will free the KeyControlBlock.  If the key was deleted, it
            // has already been removed from the hash table, and relevant notifications
            // posted then as well.  All we are doing is freeing the tombstone.
            //
            // If it was not deleted, we're both cutting the kcb out of
            // the kcb list/tree, AND freeing its storage.
            //

           
            //
            // Replace this with the definition so we avoid dropping and reacquiring the lock
            DelistKeyBodyFromKCB(KeyBody,FALSE);

            //
            // take additional precaution in the case the hive has been unloaded and this is the root
            //
            if( !KeyControlBlock->Delete ) {
                CmHive = (PCMHIVE)CONTAINING_RECORD(KeyControlBlock->KeyHive, CMHIVE, Hive);
                if( IsHiveFrozen(CmHive) ) {
                    //
                    // unload is pending for this hive;
                    //
                    DoUnloadCheck = TRUE;

                }
            }

            CmpDelayDerefKeyControlBlock(KeyControlBlock);

        }
    } else {
        //
        // This must be a predefined handle
        //  some sanity asserts
        //
        KeyControlBlock = KeyBody->KeyControlBlock;

        ASSERT( KeyBody->Type&REG_PREDEF_HANDLE_MASK);
        ASSERT( KeyControlBlock->Flags&KEY_PREDEF_HANDLE );

        if( KeyControlBlock != NULL ) {
            CmHive = (PCMHIVE)CONTAINING_RECORD(KeyControlBlock->KeyHive, CMHIVE, Hive);
            if( IsHiveFrozen(CmHive) ) {
                //
                // unload is pending for this hive; we shouldn't put the kcb in the delay
                // close table
                //
                DoUnloadCheck = TRUE;

            }
            CmpDereferenceKeyControlBlock(KeyControlBlock);
        }

    }

    //
    // if a handle inside a frozen hive has been closed, we may need to unload the hive
    //
    if( DoUnloadCheck == TRUE ) {
        CmpDoQueueLateUnloadWorker(CmHive);
    }

    CmpUnlockRegistry();
    END_LOCK_CHECKPOINT;

    // 
    // just a notification; disregard the return status
    //
    CmPostCallbackNotification(RegNtPostKeyHandleClose,NULL,STATUS_SUCCESS);
    return;
}