Пример #1
0
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);
    }
}
Пример #2
0
VOID
CmpCleanUpKcbCacheWithLock(
    PCM_KEY_CONTROL_BLOCK   KeyControlBlock
    )
/*++

Routine Description:

    Clean up all cached allocations that are associated to this key.
    If the parent is still open just because of this one, Remove the parent as well.

Arguments:

    KeyControlBlock - pointer to a key control block.

Return Value:

    NONE.

--*/
{
    PCM_KEY_CONTROL_BLOCK   Kcb;
    PCM_KEY_CONTROL_BLOCK   ParentKcb;

    Kcb = KeyControlBlock;

    ASSERT(KeyControlBlock->RefCount == 0);

    while (Kcb->RefCount == 0) {
        //
        // First, free allocations for Value/data.
        //
    
        CmpCleanUpKcbValueCache(Kcb);
    
        //
        // Free the kcb and dereference parentkcb and nameblock.
        //
    
        CmpDereferenceNameControlBlockWithLock(Kcb->NameBlock);
    
        if (Kcb->ExtFlags & CM_KCB_SUBKEY_HINT) {
            //
            // Now free the HintIndex allocation
            //
            ExFreePoolWithTag(Kcb->IndexHint, CM_CACHE_INDEX_TAG | PROTECTED_POOL);
        }

        //
        // Save the ParentKcb before we free the Kcb
        //
        ParentKcb = Kcb->ParentKcb;
        
        //
        // We cannot call CmpDereferenceKeyControlBlockWithLock so we can avoid recurrsion.
        //
        
        if (!Kcb->Delete) {
            CmpRemoveKeyControlBlock(Kcb);
        }
        SET_KCB_SIGNATURE(Kcb, '4FmC');
        ASSERT_KEYBODY_LIST_EMPTY(Kcb);
        ExFreePoolWithTag(Kcb, CM_KCB_TAG | PROTECTED_POOL);

        Kcb = ParentKcb;
        Kcb->RefCount--;
    }
}
Пример #3
0
VALUE_SEARCH_RETURN_TYPE
NTAPI
CmpCompareNewValueDataAgainstKCBCache(IN PCM_KEY_CONTROL_BLOCK Kcb,
                                      IN PUNICODE_STRING ValueName,
                                      IN ULONG Type,
                                      IN PVOID Data,
                                      IN ULONG DataSize)
{
    VALUE_SEARCH_RETURN_TYPE SearchResult;
    PCM_KEY_NODE KeyNode;
    PCM_CACHED_VALUE *CachedValue;
    ULONG Index;
    PCM_KEY_VALUE Value;
    BOOLEAN ValueCached, BufferAllocated = FALSE;
    PVOID Buffer;
    HCELL_INDEX ValueCellToRelease = HCELL_NIL, CellToRelease = HCELL_NIL;
    BOOLEAN IsSmall;
    ULONG CompareResult;
    PAGED_CODE();

    /* Check if this is a symlink */
    if (Kcb->Flags & KEY_SYM_LINK)
    {
        /* We need the exclusive lock */
        if (!(CmpIsKcbLockedExclusive(Kcb)) &&
            !(CmpTryToConvertKcbSharedToExclusive(Kcb)))
        {
            /* We need the exclusive lock */
            return SearchNeedExclusiveLock;
        }
        
        /* Otherwise, get the key node */
        KeyNode = (PCM_KEY_NODE)HvGetCell(Kcb->KeyHive, Kcb->KeyCell);
        if (!KeyNode) return SearchFail;
        
        /* Cleanup the KCB cache */
        CmpCleanUpKcbValueCache(Kcb);
        
        /* Sanity checks */
        ASSERT(!(CMP_IS_CELL_CACHED(Kcb->ValueCache.ValueList)));
        ASSERT(!(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND));
        
        /* Set the value cache */
        Kcb->ValueCache.Count = KeyNode->ValueList.Count;
        Kcb->ValueCache.ValueList = KeyNode->ValueList.List;
        
        /* Release the cell */
        HvReleaseCell(Kcb->KeyHive, Kcb->KeyCell);
    }
    
    /* Do the search */
    SearchResult = CmpFindValueByNameFromCache(Kcb,
                                               ValueName,
                                               &CachedValue,
                                               &Index,
                                               &Value,
                                               &ValueCached,
                                               &ValueCellToRelease);
    if (SearchResult == SearchNeedExclusiveLock)
    {
        /* We need the exclusive lock */
        ASSERT(!CmpIsKcbLockedExclusive(Kcb));
        ASSERT(ValueCellToRelease == HCELL_NIL);
        ASSERT(Value == NULL);
        goto Quickie;
    }
    else if (SearchResult == SearchSuccess)
    {
        /* Sanity check */
        ASSERT(Value);
        
        /* First of all, check if the key size and type matches */
        if ((Type == Value->Type) &&
            (DataSize == (Value->DataLength & ~CM_KEY_VALUE_SPECIAL_SIZE)))
        {
            /* Check if this is a small key */
            IsSmall = (DataSize <= CM_KEY_VALUE_SMALL) ? TRUE: FALSE;
            if (IsSmall)
            {
                /* Compare against the data directly */
                Buffer = &Value->Data;
            }
            else
            {
                /* Do a search */
                SearchResult = CmpGetValueDataFromCache(Kcb,
                                                        CachedValue,
                                                        (PCELL_DATA)Value,
                                                        ValueCached,
                                                        &Buffer,
                                                        &BufferAllocated,
                                                        &CellToRelease);
                if (SearchResult != SearchSuccess)
                {
                    /* Sanity checks */
                    ASSERT(Buffer == NULL);
                    ASSERT(BufferAllocated == FALSE);
                    goto Quickie;
                }
            }
            
            /* Now check the data size */
            if (DataSize)
            {
                /* Do the compare */
                CompareResult = RtlCompareMemory(Buffer,
                                                 Data,
                                                 DataSize &
                                                 ~CM_KEY_VALUE_SPECIAL_SIZE);
            }
            else
            {
                /* It's equal */
                CompareResult = 0;
            }
            
            /* Now check if the compare wasn't equal */
            if (CompareResult != DataSize) SearchResult = SearchFail;
        }
        else
        {
            /* The length or type isn't equal */
            SearchResult = SearchFail;
        }
    }

Quickie:
    /* Release the value cell */
    if (ValueCellToRelease) HvReleaseCell(Kcb->KeyHive, ValueCellToRelease);
    
    /* Free the buffer */
    if (BufferAllocated) CmpFree(Buffer, 0);
    
    /* Free the cell */
    if (CellToRelease) HvReleaseCell(Kcb->KeyHive, CellToRelease);

    /* Return the search result */
    return SearchResult;
}