VOID CmpCleanUpKcbValueCache( PCM_KEY_CONTROL_BLOCK KeyControlBlock ) /*++ Routine Description: Clean up cached value/data that are associated to this key. Arguments: KeyControlBlock - pointer to a key control block. Return Value: NONE. --*/ { ULONG i; PULONG_PTR CachedList; PCELL_DATA pcell; ULONG realsize; BOOLEAN small; if (CMP_IS_CELL_CACHED(KeyControlBlock->ValueCache.ValueList)) { CachedList = (PULONG_PTR) CMP_GET_CACHED_CELLDATA(KeyControlBlock->ValueCache.ValueList); for (i = 0; i < KeyControlBlock->ValueCache.Count; i++) { if (CMP_IS_CELL_CACHED(CachedList[i])) { // Trying to catch the BAD guy who writes over our pool. CmpMakeSpecialPoolReadWrite( CMP_GET_CACHED_ADDRESS(CachedList[i]) ); ExFreePool((PVOID) CMP_GET_CACHED_ADDRESS(CachedList[i])); } } // Trying to catch the BAD guy who writes over our pool. CmpMakeSpecialPoolReadWrite( CMP_GET_CACHED_ADDRESS(KeyControlBlock->ValueCache.ValueList) ); ExFreePool((PVOID) CMP_GET_CACHED_ADDRESS(KeyControlBlock->ValueCache.ValueList)); // Mark the ValueList as NULL KeyControlBlock->ValueCache.ValueList = HCELL_NIL; } else if (KeyControlBlock->ExtFlags & CM_KCB_SYM_LINK_FOUND) { // // This is a symbolic link key with symbolic name resolved. // Dereference to its real kcb and clear the bit. // if ((KeyControlBlock->ValueCache.RealKcb->RefCount == 1) && !(KeyControlBlock->ValueCache.RealKcb->Delete)) { KeyControlBlock->ValueCache.RealKcb->ExtFlags |= CM_KCB_NO_DELAY_CLOSE; } CmpDereferenceKeyControlBlockWithLock(KeyControlBlock->ValueCache.RealKcb); KeyControlBlock->ExtFlags &= ~CM_KCB_SYM_LINK_FOUND; } }
VALUE_SEARCH_RETURN_TYPE CmpGetValueListFromCache( IN PCM_KEY_CONTROL_BLOCK KeyControlBlock, OUT PCELL_DATA *List, OUT BOOLEAN *IndexCached, OUT PHCELL_INDEX ValueListToRelease ) /*++ Routine Description: Get the Valve Index Array. Check if it is already cached, if not, cache it and return the cached entry. Arguments: Hive - pointer to hive control structure for hive of interest ChildList - pointer/index to the Value Index array IndexCached - Indicating whether Value Index list is cached or not. Return Value: Pointer to the Valve Index Array. NULL when we could not map view --*/ { HCELL_INDEX CellToRelease; PCACHED_CHILD_LIST ChildList; PHHIVE Hive; #ifndef _WIN64 ULONG AllocSize; PCM_CACHED_VALUE_INDEX CachedValueIndex; ULONG i; #endif ASSERT_KCB_LOCKED(KeyControlBlock); Hive = KeyControlBlock->KeyHive; ChildList = &(KeyControlBlock->ValueCache); *ValueListToRelease = HCELL_NIL; #ifndef _WIN64 *IndexCached = TRUE; if (CMP_IS_CELL_CACHED(ChildList->ValueList)) { // // The entry is already cached. // *List = CMP_GET_CACHED_CELLDATA(ChildList->ValueList); } else { // // The entry is not cached. The element contains the hive index. // ensure exclusive lock. // if( (CmpIsKCBLockedExclusive(KeyControlBlock) == FALSE) && (CmpTryConvertKCBLockSharedToExclusive(KeyControlBlock) == FALSE) ) { // // need to upgrade lock to exclusive // return SearchNeedExclusiveLock; } CellToRelease = CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList); *List = (PCELL_DATA) HvGetCell(Hive, CellToRelease); if( *List == NULL ) { // // we couldn't map a view for this cell // *IndexCached = FALSE; return SearchFail; } // // Allocate a PagedPool to cache the value index cell. // AllocSize = ChildList->Count * sizeof(ULONG_PTR) + FIELD_OFFSET(CM_CACHED_VALUE_INDEX, Data); CachedValueIndex = (PCM_CACHED_VALUE_INDEX) ExAllocatePoolWithTag(PagedPool, AllocSize, CM_CACHE_VALUE_INDEX_TAG); if (CachedValueIndex) { CachedValueIndex->CellIndex = CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList); #pragma prefast(suppress:12009, "no overflow") for (i=0; i<ChildList->Count; i++) { CachedValueIndex->Data.List[i] = (ULONG_PTR) (*List)->u.KeyList[i]; } ChildList->ValueList = CMP_MARK_CELL_CACHED(CachedValueIndex); // Trying to catch the BAD guy who writes over our pool. CmpMakeSpecialPoolReadOnly( CachedValueIndex ); // // Now we have the stuff cached, use the cache data. // *List = CMP_GET_CACHED_CELLDATA(ChildList->ValueList); } else { // // If the allocation fails, just do not cache it. continue. // *IndexCached = FALSE; } *ValueListToRelease = CellToRelease; } #else CellToRelease = CMP_GET_CACHED_CELL_INDEX(ChildList->ValueList); *List = (PCELL_DATA) HvGetCell(Hive, CellToRelease); *IndexCached = FALSE; if( *List == NULL ) { // // we couldn't map a view for this cell // OBS: we can drop this as we return List anyway; just for clarity // return SearchFail; } *ValueListToRelease = CellToRelease; #endif return SearchSuccess; }