907 lines
22 KiB
C++
907 lines
22 KiB
C++
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows NT Security
|
||
|
// Copyright (C) Microsoft Corporation, 1997 - 1999
|
||
|
//
|
||
|
// File: lru.cpp
|
||
|
//
|
||
|
// Contents: LRU cache implementation
|
||
|
//
|
||
|
// History: 24-Dec-97 kirtd Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
#include <global.hxx>
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruEntry::CLruEntry, public
|
||
|
//
|
||
|
// Synopsis: Constructor
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CLruEntry::CLruEntry (
|
||
|
IN PCLRUCACHE pCache,
|
||
|
IN PCRYPT_DATA_BLOB pIdentifier,
|
||
|
IN LPVOID pvData,
|
||
|
OUT BOOL& rfResult
|
||
|
)
|
||
|
{
|
||
|
rfResult = TRUE;
|
||
|
|
||
|
m_cRefs = 1;
|
||
|
m_pPrevEntry = NULL;
|
||
|
m_pNextEntry = NULL;
|
||
|
m_Usage = 0;
|
||
|
|
||
|
m_pCache = pCache;
|
||
|
m_pvData = pvData;
|
||
|
m_pBucket = pCache->BucketFromIdentifier( pIdentifier );
|
||
|
|
||
|
if ( pCache->Flags() & LRU_CACHE_NO_COPY_IDENTIFIER )
|
||
|
{
|
||
|
m_Identifier = *pIdentifier;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_Identifier.cbData = pIdentifier->cbData;
|
||
|
m_Identifier.pbData = new BYTE [ pIdentifier->cbData ];
|
||
|
if ( m_Identifier.pbData != NULL )
|
||
|
{
|
||
|
memcpy(
|
||
|
m_Identifier.pbData,
|
||
|
pIdentifier->pbData,
|
||
|
pIdentifier->cbData
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
rfResult = FALSE;
|
||
|
SetLastError( (DWORD) E_OUTOFMEMORY );
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assert( m_pBucket != NULL );
|
||
|
assert( m_Identifier.pbData != NULL );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruEntry::~CLruEntry, public
|
||
|
//
|
||
|
// Synopsis: Destructor
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CLruEntry::~CLruEntry ()
|
||
|
{
|
||
|
m_pCache->FreeEntryData( m_pvData );
|
||
|
|
||
|
if ( !( m_pCache->Flags() & LRU_CACHE_NO_COPY_IDENTIFIER ) )
|
||
|
{
|
||
|
delete m_Identifier.pbData;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::CLruCache, public
|
||
|
//
|
||
|
// Synopsis: Constructor
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CLruCache::CLruCache (
|
||
|
IN PLRU_CACHE_CONFIG pConfig,
|
||
|
OUT BOOL& rfResult
|
||
|
)
|
||
|
{
|
||
|
rfResult = TRUE;
|
||
|
|
||
|
m_Config.dwFlags = LRU_CACHE_NO_SERIALIZE;
|
||
|
m_cEntries = 0;
|
||
|
m_aBucket = new LRU_CACHE_BUCKET [ pConfig->cBuckets ];
|
||
|
if ( m_aBucket == NULL )
|
||
|
{
|
||
|
rfResult = FALSE;
|
||
|
SetLastError( (DWORD) E_OUTOFMEMORY );
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
memset( m_aBucket, 0, sizeof( LRU_CACHE_BUCKET ) * pConfig->cBuckets );
|
||
|
|
||
|
if ( !( pConfig->dwFlags & LRU_CACHE_NO_SERIALIZE ) )
|
||
|
{
|
||
|
if (! Pki_InitializeCriticalSection( &m_Lock ))
|
||
|
{
|
||
|
rfResult = FALSE;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
m_Config = *pConfig;
|
||
|
m_UsageClock = 0;
|
||
|
m_cLruDisabled = 0;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::~CLruCache, public
|
||
|
//
|
||
|
// Synopsis: Destructor
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
CLruCache::~CLruCache ()
|
||
|
{
|
||
|
if ( m_cEntries > 0 )
|
||
|
{
|
||
|
PurgeAllEntries( 0, NULL );
|
||
|
}
|
||
|
|
||
|
if ( !( m_Config.dwFlags & LRU_CACHE_NO_SERIALIZE ) )
|
||
|
{
|
||
|
DeleteCriticalSection( &m_Lock );
|
||
|
}
|
||
|
|
||
|
delete m_aBucket;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::EnableLruOfEntries, public
|
||
|
//
|
||
|
// Synopsis: enable LRU of entries and purge anything over the watermark
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::EnableLruOfEntries (IN OPTIONAL LPVOID pvLruRemovalContext)
|
||
|
{
|
||
|
LockCache();
|
||
|
|
||
|
assert( m_cLruDisabled > 0 );
|
||
|
|
||
|
if ( m_cLruDisabled == 0 )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
m_cLruDisabled -= 1;
|
||
|
|
||
|
if ( m_cLruDisabled == 0 )
|
||
|
{
|
||
|
while ( m_cEntries > m_Config.MaxEntries )
|
||
|
{
|
||
|
PurgeLeastRecentlyUsed( pvLruRemovalContext );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::DisableLruOfEntries, public
|
||
|
//
|
||
|
// Synopsis: disable LRU of entries
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::DisableLruOfEntries ()
|
||
|
{
|
||
|
LockCache();
|
||
|
|
||
|
m_cLruDisabled += 1;
|
||
|
|
||
|
UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::InsertEntry, public
|
||
|
//
|
||
|
// Synopsis: insert an entry into the cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::InsertEntry (
|
||
|
IN PCLRUENTRY pEntry,
|
||
|
IN OPTIONAL LPVOID pvLruRemovalContext
|
||
|
)
|
||
|
{
|
||
|
assert( pEntry->PrevPointer() == NULL );
|
||
|
assert( pEntry->NextPointer() == NULL );
|
||
|
|
||
|
pEntry->AddRef();
|
||
|
|
||
|
LockCache();
|
||
|
|
||
|
if ( ( m_cEntries == m_Config.MaxEntries ) &&
|
||
|
( m_Config.MaxEntries != 0 ) &&
|
||
|
( m_cLruDisabled == 0 ) )
|
||
|
{
|
||
|
PurgeLeastRecentlyUsed( pvLruRemovalContext );
|
||
|
}
|
||
|
|
||
|
assert( ( m_cEntries < m_Config.MaxEntries ) ||
|
||
|
( m_Config.MaxEntries == 0 ) ||
|
||
|
( m_cLruDisabled > 0 ) );
|
||
|
|
||
|
pEntry->SetNextPointer( pEntry->Bucket()->pList );
|
||
|
|
||
|
if ( pEntry->Bucket()->pList != NULL )
|
||
|
{
|
||
|
pEntry->Bucket()->pList->SetPrevPointer( pEntry );
|
||
|
}
|
||
|
|
||
|
pEntry->Bucket()->pList = pEntry;
|
||
|
|
||
|
m_cEntries += 1;
|
||
|
|
||
|
TouchEntryNoLock( pEntry, 0 );
|
||
|
|
||
|
UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::RemoveEntry, public
|
||
|
//
|
||
|
// Synopsis: remove an entry from the cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::RemoveEntry (
|
||
|
IN PCLRUENTRY pEntry,
|
||
|
IN DWORD dwFlags,
|
||
|
IN OPTIONAL LPVOID pvRemovalContext
|
||
|
)
|
||
|
{
|
||
|
LockCache();
|
||
|
|
||
|
RemoveEntryFromBucket(
|
||
|
pEntry->Bucket(),
|
||
|
pEntry,
|
||
|
dwFlags,
|
||
|
pvRemovalContext
|
||
|
);
|
||
|
|
||
|
UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::TouchEntry, public
|
||
|
//
|
||
|
// Synopsis: touch the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::TouchEntry (IN PCLRUENTRY pEntry, IN DWORD dwFlags)
|
||
|
{
|
||
|
LockCache();
|
||
|
|
||
|
TouchEntryNoLock( pEntry, dwFlags );
|
||
|
|
||
|
UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::FindEntry, public
|
||
|
//
|
||
|
// Synopsis: find the entry matching the given identifier
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PCLRUENTRY
|
||
|
CLruCache::FindEntry (IN PCRYPT_DATA_BLOB pIdentifier, IN BOOL fTouchEntry)
|
||
|
{
|
||
|
PLRU_CACHE_BUCKET pBucket;
|
||
|
|
||
|
pBucket = BucketFromIdentifier( pIdentifier );
|
||
|
|
||
|
assert( pBucket != NULL );
|
||
|
|
||
|
return( FindNextMatchingEntryInBucket(
|
||
|
pBucket,
|
||
|
NULL,
|
||
|
pIdentifier,
|
||
|
fTouchEntry
|
||
|
) );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::NextMatchingEntry, public
|
||
|
//
|
||
|
// Synopsis: find the next matching entry to pPrevEntry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PCLRUENTRY
|
||
|
CLruCache::NextMatchingEntry (IN PCLRUENTRY pPrevEntry, IN BOOL fTouchEntry)
|
||
|
{
|
||
|
PCLRUENTRY pNextEntry;
|
||
|
|
||
|
pNextEntry = FindNextMatchingEntryInBucket(
|
||
|
NULL,
|
||
|
pPrevEntry,
|
||
|
NULL,
|
||
|
fTouchEntry
|
||
|
);
|
||
|
|
||
|
pPrevEntry->Release();
|
||
|
|
||
|
return( pNextEntry );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::WalkEntries, public
|
||
|
//
|
||
|
// Synopsis: walk the entries
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::WalkEntries (IN PFN_WALK_ENTRIES pfnWalk, IN LPVOID pvParameter)
|
||
|
{
|
||
|
DWORD cCount;
|
||
|
PCLRUENTRY pEntry;
|
||
|
PCLRUENTRY pNextEntry;
|
||
|
|
||
|
for ( cCount = 0; cCount < m_Config.cBuckets; cCount++ )
|
||
|
{
|
||
|
pEntry = m_aBucket[ cCount ].pList;
|
||
|
|
||
|
while ( pEntry != NULL )
|
||
|
{
|
||
|
pNextEntry = pEntry->NextPointer();
|
||
|
|
||
|
if ( ( *pfnWalk )( pvParameter, pEntry ) == FALSE )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
pEntry = pNextEntry;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::RemoveEntryFromBucket, public
|
||
|
//
|
||
|
// Synopsis: remove entry from bucket
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::RemoveEntryFromBucket (
|
||
|
IN PLRU_CACHE_BUCKET pBucket,
|
||
|
IN PCLRUENTRY pEntry,
|
||
|
IN DWORD dwFlags,
|
||
|
IN OPTIONAL LPVOID pvRemovalContext
|
||
|
)
|
||
|
{
|
||
|
if ( pEntry->PrevPointer() != NULL )
|
||
|
{
|
||
|
pEntry->PrevPointer()->SetNextPointer( pEntry->NextPointer() );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
assert( pBucket->pList == pEntry );
|
||
|
|
||
|
pBucket->pList = pEntry->NextPointer();
|
||
|
}
|
||
|
|
||
|
if ( pEntry->NextPointer() != NULL )
|
||
|
{
|
||
|
pEntry->NextPointer()->SetPrevPointer( pEntry->PrevPointer() );
|
||
|
}
|
||
|
|
||
|
pEntry->SetPrevPointer( NULL );
|
||
|
pEntry->SetNextPointer( NULL );
|
||
|
|
||
|
m_cEntries -= 1;
|
||
|
|
||
|
if ( ( m_Config.pfnOnRemoval != NULL ) &&
|
||
|
!( dwFlags & LRU_SUPPRESS_REMOVAL_NOTIFICATION ) )
|
||
|
{
|
||
|
( *m_Config.pfnOnRemoval )( pEntry->Data(), pvRemovalContext );
|
||
|
}
|
||
|
|
||
|
pEntry->Release();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::FindNextMatchingEntryInBucket, public
|
||
|
//
|
||
|
// Synopsis: find the next matching entry in the given bucket. If pCurrent
|
||
|
// is non NULL then start from there, the bucket is not needed and
|
||
|
// pIdentifier is ignored. If pCurrent is NULL then pIdentifier
|
||
|
// and the bucket must both be non NULL
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PCLRUENTRY
|
||
|
CLruCache::FindNextMatchingEntryInBucket (
|
||
|
IN PLRU_CACHE_BUCKET pBucket,
|
||
|
IN PCLRUENTRY pCurrent,
|
||
|
IN PCRYPT_DATA_BLOB pIdentifier,
|
||
|
IN BOOL fTouchEntry
|
||
|
)
|
||
|
{
|
||
|
LockCache();
|
||
|
|
||
|
if ( pCurrent == NULL )
|
||
|
{
|
||
|
pCurrent = pBucket->pList;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
pIdentifier = pCurrent->Identifier();
|
||
|
pCurrent = pCurrent->NextPointer();
|
||
|
}
|
||
|
|
||
|
while ( pCurrent != NULL )
|
||
|
{
|
||
|
if ( ( pIdentifier->cbData == pCurrent->Identifier()->cbData ) &&
|
||
|
( memcmp(
|
||
|
pIdentifier->pbData,
|
||
|
pCurrent->Identifier()->pbData,
|
||
|
pIdentifier->cbData
|
||
|
) == 0 ) )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pCurrent = pCurrent->NextPointer();
|
||
|
}
|
||
|
|
||
|
if ( pCurrent != NULL )
|
||
|
{
|
||
|
pCurrent->AddRef();
|
||
|
|
||
|
if ( fTouchEntry == TRUE )
|
||
|
{
|
||
|
TouchEntryNoLock( pCurrent, 0 );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
UnlockCache();
|
||
|
|
||
|
return( pCurrent );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::PurgeLeastRecentlyUsed, public
|
||
|
//
|
||
|
// Synopsis: find and remove the least recently used entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::PurgeLeastRecentlyUsed (IN OPTIONAL LPVOID pvLruRemovalContext)
|
||
|
{
|
||
|
DWORD cCount;
|
||
|
PLRU_CACHE_BUCKET pBucket;
|
||
|
PCLRUENTRY pEntry;
|
||
|
PCLRUENTRY pLRU;
|
||
|
|
||
|
assert( m_cEntries > 0 );
|
||
|
|
||
|
for ( cCount = 0; cCount < m_Config.cBuckets; cCount++ )
|
||
|
{
|
||
|
if ( m_aBucket[cCount].pList != NULL )
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pBucket = &m_aBucket[cCount];
|
||
|
cCount += 1;
|
||
|
for ( ; cCount < m_Config.cBuckets; cCount++ )
|
||
|
{
|
||
|
if ( ( m_aBucket[cCount].pList != NULL ) &&
|
||
|
( m_aBucket[cCount].Usage < pBucket->Usage ) )
|
||
|
{
|
||
|
pBucket = &m_aBucket[cCount];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assert( pBucket != NULL );
|
||
|
assert( pBucket->pList != NULL );
|
||
|
|
||
|
pLRU = pBucket->pList;
|
||
|
pEntry = pLRU->NextPointer();
|
||
|
|
||
|
while ( pEntry != NULL )
|
||
|
{
|
||
|
if ( pEntry->Usage() < pLRU->Usage() )
|
||
|
{
|
||
|
pLRU = pEntry;
|
||
|
}
|
||
|
|
||
|
pEntry = pEntry->NextPointer();
|
||
|
}
|
||
|
|
||
|
RemoveEntryFromBucket( pBucket, pLRU, 0, pvLruRemovalContext );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CLruCache::PurgeAllEntries, public
|
||
|
//
|
||
|
// Synopsis: remove all entries from the cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID
|
||
|
CLruCache::PurgeAllEntries (
|
||
|
IN DWORD dwFlags,
|
||
|
IN OPTIONAL LPVOID pvRemovalContext
|
||
|
)
|
||
|
{
|
||
|
DWORD cCount;
|
||
|
|
||
|
for ( cCount = 0; cCount < m_Config.cBuckets; cCount++ )
|
||
|
{
|
||
|
while ( m_aBucket[cCount].pList != NULL )
|
||
|
{
|
||
|
RemoveEntryFromBucket(
|
||
|
&m_aBucket[cCount],
|
||
|
m_aBucket[cCount].pList,
|
||
|
dwFlags,
|
||
|
pvRemovalContext
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
assert( m_cEntries == 0 );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptCreateLruCache
|
||
|
//
|
||
|
// Synopsis: create an LRU cache area
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL WINAPI
|
||
|
I_CryptCreateLruCache (
|
||
|
IN PLRU_CACHE_CONFIG pConfig,
|
||
|
OUT HLRUCACHE* phCache
|
||
|
)
|
||
|
{
|
||
|
BOOL fResult = FALSE;
|
||
|
PCLRUCACHE pCache;
|
||
|
|
||
|
pCache = new CLruCache( pConfig, fResult );
|
||
|
if ( pCache == NULL )
|
||
|
{
|
||
|
SetLastError( (DWORD) E_OUTOFMEMORY );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if ( fResult == FALSE )
|
||
|
{
|
||
|
delete pCache;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
*phCache = (HLRUCACHE)pCache;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptFlushLruCache
|
||
|
//
|
||
|
// Synopsis: flush the cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptFlushLruCache (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN OPTIONAL DWORD dwFlags,
|
||
|
IN OPTIONAL LPVOID pvRemovalContext
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUCACHE)hCache )->LockCache();
|
||
|
|
||
|
( (PCLRUCACHE)hCache )->PurgeAllEntries( dwFlags, pvRemovalContext );
|
||
|
|
||
|
( (PCLRUCACHE)hCache )->UnlockCache();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptFreeLruCache
|
||
|
//
|
||
|
// Synopsis: free the LRU cache area
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptFreeLruCache (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN DWORD dwFlags,
|
||
|
IN OPTIONAL LPVOID pvRemovalContext
|
||
|
)
|
||
|
{
|
||
|
if ( hCache == NULL )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( dwFlags != 0 )
|
||
|
{
|
||
|
( (PCLRUCACHE)hCache )->PurgeAllEntries( dwFlags, pvRemovalContext );
|
||
|
}
|
||
|
|
||
|
delete (PCLRUCACHE)hCache;
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptCreateLruEntry
|
||
|
//
|
||
|
// Synopsis: create an LRU entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
BOOL WINAPI
|
||
|
I_CryptCreateLruEntry (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN PCRYPT_DATA_BLOB pIdentifier,
|
||
|
IN LPVOID pvData,
|
||
|
OUT HLRUENTRY* phEntry
|
||
|
)
|
||
|
{
|
||
|
BOOL fResult = FALSE;
|
||
|
PCLRUENTRY pEntry;
|
||
|
|
||
|
pEntry = new CLruEntry(
|
||
|
(PCLRUCACHE)hCache,
|
||
|
pIdentifier,
|
||
|
pvData,
|
||
|
fResult
|
||
|
);
|
||
|
|
||
|
if ( pEntry == NULL )
|
||
|
{
|
||
|
SetLastError( (DWORD) E_OUTOFMEMORY );
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
if ( fResult == FALSE )
|
||
|
{
|
||
|
delete pEntry;
|
||
|
return( FALSE );
|
||
|
}
|
||
|
|
||
|
*phEntry = (HLRUENTRY)pEntry;
|
||
|
return( TRUE );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptGetLruEntryIdentifier
|
||
|
//
|
||
|
// Synopsis: return the identifier for the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
PCRYPT_DATA_BLOB WINAPI
|
||
|
I_CryptGetLruEntryIdentifier (
|
||
|
IN HLRUENTRY hEntry
|
||
|
)
|
||
|
{
|
||
|
return( ( (PCLRUENTRY)hEntry )->Identifier() );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptGetLruEntryData
|
||
|
//
|
||
|
// Synopsis: get the data associated with the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
LPVOID WINAPI
|
||
|
I_CryptGetLruEntryData (
|
||
|
IN HLRUENTRY hEntry
|
||
|
)
|
||
|
{
|
||
|
return( ( (PCLRUENTRY)hEntry )->Data() );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptAddRefLruEntry
|
||
|
//
|
||
|
// Synopsis: add a reference to the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptAddRefLruEntry (
|
||
|
IN HLRUENTRY hEntry
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUENTRY)hEntry )->AddRef();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptReleaseLruEntry
|
||
|
//
|
||
|
// Synopsis: remove a reference from the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptReleaseLruEntry (
|
||
|
IN HLRUENTRY hEntry
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUENTRY)hEntry )->Release();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptInsertLruEntry
|
||
|
//
|
||
|
// Synopsis: insert the entry into its associated cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptInsertLruEntry (
|
||
|
IN HLRUENTRY hEntry,
|
||
|
IN OPTIONAL LPVOID pvLruRemovalContext
|
||
|
)
|
||
|
{
|
||
|
PCLRUENTRY pEntry = (PCLRUENTRY)hEntry;
|
||
|
|
||
|
pEntry->Cache()->InsertEntry( pEntry, pvLruRemovalContext );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptRemoveLruEntry
|
||
|
//
|
||
|
// Synopsis: remove the entry from its associated cache
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptRemoveLruEntry (
|
||
|
IN HLRUENTRY hEntry,
|
||
|
IN DWORD dwFlags,
|
||
|
IN LPVOID pvLruRemovalContext
|
||
|
)
|
||
|
{
|
||
|
PCLRUENTRY pEntry = (PCLRUENTRY)hEntry;
|
||
|
|
||
|
pEntry->Cache()->RemoveEntry( pEntry, dwFlags, pvLruRemovalContext );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptTouchLruEntry
|
||
|
//
|
||
|
// Synopsis: touch the entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptTouchLruEntry (
|
||
|
IN HLRUENTRY hEntry,
|
||
|
IN DWORD dwFlags
|
||
|
)
|
||
|
{
|
||
|
PCLRUENTRY pEntry = (PCLRUENTRY)hEntry;
|
||
|
|
||
|
pEntry->Cache()->TouchEntry( pEntry, dwFlags );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptFindLruEntry
|
||
|
//
|
||
|
// Synopsis: find the entry with the given identifier
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HLRUENTRY WINAPI
|
||
|
I_CryptFindLruEntry (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN PCRYPT_DATA_BLOB pIdentifier
|
||
|
)
|
||
|
{
|
||
|
PCLRUCACHE pCache = (PCLRUCACHE)hCache;
|
||
|
|
||
|
return( pCache->FindEntry( pIdentifier, FALSE ) );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptFindLruEntryData
|
||
|
//
|
||
|
// Synopsis: find the entry with the given identifier
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
LPVOID WINAPI
|
||
|
I_CryptFindLruEntryData (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN PCRYPT_DATA_BLOB pIdentifier,
|
||
|
OUT HLRUENTRY* phEntry
|
||
|
)
|
||
|
{
|
||
|
PCLRUCACHE pCache = (PCLRUCACHE)hCache;
|
||
|
PCLRUENTRY pEntry;
|
||
|
|
||
|
pEntry = pCache->FindEntry( pIdentifier, TRUE );
|
||
|
*phEntry = (HLRUENTRY)pEntry;
|
||
|
|
||
|
if ( pEntry != NULL )
|
||
|
{
|
||
|
return( pEntry->Data() );
|
||
|
}
|
||
|
|
||
|
return( NULL );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptEnumMatchingLruEntries
|
||
|
//
|
||
|
// Synopsis: get the next matching entry
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
HLRUENTRY WINAPI
|
||
|
I_CryptEnumMatchingLruEntries (
|
||
|
IN HLRUENTRY hPrevEntry
|
||
|
)
|
||
|
{
|
||
|
PCLRUCACHE pCache = ( (PCLRUENTRY)hPrevEntry )->Cache();
|
||
|
PCLRUENTRY pNextEntry;
|
||
|
|
||
|
pNextEntry = pCache->NextMatchingEntry( (PCLRUENTRY)hPrevEntry, FALSE );
|
||
|
|
||
|
return( (HLRUENTRY)pNextEntry );
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptEnableLruOfEntries
|
||
|
//
|
||
|
// Synopsis: enable LRU of entries
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptEnableLruOfEntries (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN OPTIONAL LPVOID pvLruRemovalContext
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUCACHE)hCache )->EnableLruOfEntries( pvLruRemovalContext);
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptDisableLruOfEntries
|
||
|
//
|
||
|
// Synopsis: disable LRU of entries
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptDisableLruOfEntries (
|
||
|
IN HLRUCACHE hCache
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUCACHE)hCache )->DisableLruOfEntries();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: I_CryptWalkAllLruCacheEntries
|
||
|
//
|
||
|
// Synopsis: walk the LRU cache entries
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
VOID WINAPI
|
||
|
I_CryptWalkAllLruCacheEntries (
|
||
|
IN HLRUCACHE hCache,
|
||
|
IN PFN_WALK_ENTRIES pfnWalk,
|
||
|
IN LPVOID pvParameter
|
||
|
)
|
||
|
{
|
||
|
( (PCLRUCACHE)hCache )->WalkEntries( pfnWalk, pvParameter );
|
||
|
}
|
||
|
|