📄 pgpmemorymgr.c
字号:
PGPGetMemoryMgrCustomValue(
PGPMemoryMgrRef mgr,
PGPUserValue * customValue)
{
PGPError err = kPGPError_NoErr;
PGPValidatePtr( customValue );
*customValue = NULL;
PGPValidateMemoryMgr( mgr );
/* illegal to change user value of default allocator */
PGPValidateParam( ! mgr->isDefault );
err = PGPValidateMemoryMgr( mgr );
if( IsntPGPError( err ) )
{
if( IsntNull( customValue ) )
{
*customValue = mgr->customValue;
}
else
{
err = kPGPError_BadParams;
}
}
return( err );
}
PGPError
PGPSetMemoryMgrCustomValue(
PGPMemoryMgrRef mgr,
PGPUserValue customValue)
{
PGPError err = kPGPError_NoErr;
PGPValidateMemoryMgr( mgr );
/* illegal to change user value of default allocator */
PGPValidateParam( ! mgr->isDefault );
err = PGPValidateMemoryMgr( mgr );
if( IsntPGPError( err ) )
{
mgr->customValue = customValue;
}
else
{
err = kPGPError_BadParams;
}
return( err );
}
/*____________________________________________________________________________
Allocate a block of memory using the allocator stored in a PFLContext.
____________________________________________________________________________*/
void *
PGPNewData(
PGPMemoryMgrRef mgr,
PGPSize requestSize,
PGPMemoryMgrFlags flags)
{
void *allocation = NULL;
PGPSize allocationSize = requestSize;
allocationSize += kRealHeaderSize;
if( IsntPGPError( PGPValidateMemoryMgr( mgr ) ) )
{
allocation = (*mgr->allocProc)( mgr, mgr->customValue,
allocationSize, flags );
}
else
{
pgpDebugMsg( "PGPNewData(): Invalid memory mgr" );
}
if ( IsntNull( allocation ) )
{
DataHeader * header = NULL;
if ( (flags & kPGPMemoryMgrFlags_Clear ) != 0 )
{
pgpClearMemory( allocation, allocationSize );
}
else
{
pgpDebugWhackMemory( allocation, allocationSize );
}
header = (DataHeader *)allocation;
sInitDataHeader( mgr, requestSize, header );
allocation = HeaderToUserBlock( allocation );
AssertBlockValid( allocation );
sAddToLeaksList( mgr, header );
}
return( allocation );
}
/*____________________________________________________________________________
Allocate a block of memory (secure or non-secure).
____________________________________________________________________________*/
PGPError
PGPReallocData(
PGPMemoryMgrRef mgr,
void ** userPtr,
PGPSize requestSize,
PGPMemoryMgrFlags flags)
{
PGPError err;
PGPValidatePtr( userPtr );
err = PGPValidateMemoryMgr( mgr );
if( IsntPGPError( err ) )
{
/* allow a NULL input */
if ( IsntNull( *userPtr ) )
{
DataHeader * header = UserBlockToHeader( *userPtr );
PGPSize oldRequestSize = header->requestSize;
sRemoveFromLeaksList( mgr, header );
if ( header->secureAlloc )
{
AssertBlockValid( *userPtr );
err = sSecureMemoryReallocProc( mgr,
(void **) &header,
kRealHeaderSize + requestSize,
flags,
kRealHeaderSize + header->requestSize );
}
else
{
AssertBlockValid( *userPtr );
err = (*(mgr->reallocProc))( mgr, mgr->customValue,
(void **) &header,
kRealHeaderSize + requestSize,
flags,
kRealHeaderSize + header->requestSize );
}
sAddToLeaksList( mgr, header );
if ( IsntPGPError( err ) )
{
*userPtr = HeaderToUserBlock( header );
header->requestSize = requestSize;
AssertBlockValid( *userPtr );
}
if ( IsntPGPError( err ) && requestSize > oldRequestSize )
{
if ( (flags & kPGPMemoryMgrFlags_Clear ) != 0 )
{
pgpClearMemory( ((char *)(*userPtr)) + oldRequestSize,
requestSize - oldRequestSize );
}
else
{
#if PGP_DEBUG
/* clear all newly allocated data to garbage */
pgpDebugWhackMemory( ((char *)(*userPtr)) + oldRequestSize,
requestSize - oldRequestSize );
#endif
}
}
}
else
{
/* allocate a brand-new block */
*userPtr = PGPNewData( mgr, requestSize, flags );
if ( IsNull( *userPtr ) )
{
err = kPGPError_OutOfMemory;
}
}
}
return( err );
}
/*____________________________________________________________________________
Free a block of memory, whether secure or not.
____________________________________________________________________________*/
PGPError
PGPFreeData( void * allocation )
{
PGPError err = kPGPError_NoErr;
PGPMemoryMgrRef mgr = NULL;
DataHeader * header;
PGPSize allocationSize;
PGPValidatePtr( allocation );
header = UserBlockToHeader( allocation );
PGPValidateParam( sDataHeaderIsValid( header ) );
mgr = header->mgr;
allocationSize = kRealHeaderSize + header->requestSize;
sRemoveFromLeaksList( mgr, header );
if ( header->secureAlloc )
{
pgpClearMemory( allocation, header->requestSize );
err = (*(mgr->secureDeallocProc))(
mgr, mgr->customValue,
header,
allocationSize,
(PGPBoolean)header->nonPageable );
}
else
{
pgpDebugWhackMemory( header, allocationSize );
err = (*(mgr->deallocProc))(
mgr, mgr->customValue,
header,
allocationSize );
}
return( err );
}
void *
PGPNewSecureData(
PGPMemoryMgrRef mgr,
PGPSize requestSize,
PGPMemoryMgrFlags flags )
{
void * allocation = NULL;
PGPSize allocationSize = requestSize;
PGPBoolean isNonPageable;
allocationSize += kRealHeaderSize;
if( IsntPGPError( PGPValidateMemoryMgr( mgr ) ) )
{
allocation = (*mgr->secureAllocProc)( mgr, mgr->customValue,
allocationSize, flags, &isNonPageable );
}
else
{
pgpDebugMsg( "PGPNewSecureData(): Invalid memory mgr" );
}
if ( IsntNull( allocation ) )
{
DataHeader * header = NULL;
if ( (flags & kPGPMemoryMgrFlags_Clear ) != 0)
{
pgpClearMemory( allocation, allocationSize );
}
else
{
pgpDebugWhackMemory( allocation, allocationSize );
}
header = (DataHeader *)allocation;
sInitDataHeader( mgr, requestSize, header );
header->secureAlloc = TRUE;
header->nonPageable = isNonPageable;
allocation = HeaderToUserBlock( allocation );
AssertBlockValid( allocation );
sAddToLeaksList( mgr, header );
}
return( allocation );
}
PGPFlags
PGPGetMemoryMgrDataInfo( void *allocation )
{
PGPFlags flags = 0;
DataHeader * header;
if ( IsNull( allocation ) )
return( 0 );
header = UserBlockToHeader( allocation );
if ( sDataHeaderIsValid( header ) )
{
flags |= kPGPMemoryMgrBlockInfo_Valid;
if ( header->secureAlloc )
flags |= kPGPMemoryMgrBlockInfo_Secure;
if ( header->nonPageable )
flags |= kPGPMemoryMgrBlockInfo_NonPageable;
}
return( flags );
}
typedef struct MemoryMgrInfo
{
struct MemoryMgrInfo *next;
PGPMemoryMgrRef mgr;
} MemoryMgrInfo;
static PGPMemoryMgrRef sDefaultMemoryMgr = kInvalidPGPMemoryMgrRef;
static MemoryMgrInfo *sMemoryMgrList = NULL;
static PGPRMWOLock sMemoryMgrListLock;
PGPMemoryMgrRef
PGPGetDefaultMemoryMgr(void)
{
PGPMemoryMgrRef mgr;
if( IsntNull( sMemoryMgrList ) )
{
/*
** If the list is non-null, then we have a mgr. We need to use a RMWO
** lock because this is a global list
*/
PGPRMWOLockStartReading( &sMemoryMgrListLock );
mgr = sDefaultMemoryMgr;
PGPRMWOLockStopReading( &sMemoryMgrListLock );
}
else
{
mgr = kInvalidPGPMemoryMgrRef;
}
return( mgr );
}
PGPError
PGPSetDefaultMemoryMgr(PGPMemoryMgrRef memoryMgr)
{
PGPError err = kPGPError_NoErr;
PGPBoolean foundMemoryMgr = FALSE;
PGPValidateParam( PGPMemoryMgrRefIsValid( memoryMgr ) );
if( IsNull( sMemoryMgrList ) )
{
/*
** If there is no list, initialize the RMWO lock. This presents
** a small window where the lock could get initialized twice,
** however this is not a call likely to introduce race conditions.
*/
InitializePGPRMWOLock( &sMemoryMgrListLock );
}
PGPRMWOLockStartWriting( &sMemoryMgrListLock );
if( IsntNull( sMemoryMgrList ) )
{
MemoryMgrInfo *cur;
/*
** Check to see if this memory mgr is already in our list and use
** it if it is
*/
cur = sMemoryMgrList;
while( IsntNull( cur ) )
{
if( cur->mgr == memoryMgr )
{
foundMemoryMgr = TRUE;
break;
}
cur = cur->next;
}
}
if( ! foundMemoryMgr )
{
MemoryMgrInfo *info;
info = (MemoryMgrInfo *) PGPNewData( memoryMgr, sizeof( *info ), 0 );
if( IsntNull( info ) )
{
info->mgr = memoryMgr;
info->next = sMemoryMgrList;
sMemoryMgrList = info;
}
else
{
err = kPGPError_OutOfMemory;
}
}
if( IsntPGPError( err ) )
sDefaultMemoryMgr = memoryMgr;
PGPRMWOLockStopWriting( &sMemoryMgrListLock );
return( err );
}
void
pgpFreeDefaultMemoryMgrList(void)
{
if( IsntNull( sMemoryMgrList ) )
{
MemoryMgrInfo *cur;
PGPRMWOLockStartWriting( &sMemoryMgrListLock );
cur = sMemoryMgrList;
while( IsntNull( cur ) )
{
MemoryMgrInfo *next;
PGPMemoryMgrRef mgr;
next = cur->next;
mgr = cur->mgr;
PGPFreeData( cur );
PGPFreeMemoryMgr( mgr );
cur = next;
}
sMemoryMgrList = NULL;
PGPRMWOLockStopWriting( &sMemoryMgrListLock );
DeletePGPRMWOLock( &sMemoryMgrListLock );
}
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -