⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpmemorymgr.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	PGPMemoryMgrRef 	mgr,
	PGPSize 			requestSize,
	PGPMemoryMgrFlags	flags)
{
	void	*allocation		= NULL;
	PGPSize	allocationSize	= requestSize;
	
	allocationSize	+= kRealHeaderSize;
	
	pgpAssert( PGPMemoryMgrIsValid( mgr ) );
	
	if( PGPMemoryMgrIsValid( mgr ) )
	{
		allocation = (*mgr->allocProc)( mgr, mgr->customValue,
						allocationSize, flags );
	}
	
	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			= kPGPError_NoErr;
	
	PGPValidateParam( PGPMemoryMgrIsValid( mgr ) );
	PGPValidatePtr( userPtr );

	/* 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( PGPMemoryMgrIsValid( mgr ) )
	{
		allocation = (*mgr->secureAllocProc)( mgr, mgr->customValue,
						allocationSize, flags, &isNonPageable );
	}
	
	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 );
	}
}
#if TESTING

/* test reallocation, then dispose of the ptr */
	static void
sTestUsingPtr(
	PGPMemoryMgrRef	mgr,
	void *			data )
{
	PGPError		err	= kPGPError_NoErr;

	(void)mgr;
	err	= PGPReallocData( mgr, &data, 20000, 0 );
	pgpAssertNoErr( err );
	err	= PGPReallocData( mgr, &data, 500, 0 );
	pgpAssertNoErr( err );
	err	= PGPReallocData( mgr, &data, 0, 0 );
	pgpAssertNoErr( err );
	err	= PGPReallocData( mgr, &data, 20001, 0 );
	pgpAssertNoErr( err );
	
	PGPFreeData( data );
}

	static void
sTestMultiAllocations( PGPMemoryMgrRef	mgr)
{
#define kNumTestPtrs	50
	void *		plain[ kNumTestPtrs ];
	void *		secure[ kNumTestPtrs ];
	PGPUInt32	idx;
	void *		temp;
	PGPError	err	= kPGPError_NoErr;
	
	for( idx = 0; idx < kNumTestPtrs; ++idx )
	{
		PGPSize			ptrSize;
		PGPFlags		flags;
		
		ptrSize	= idx * 17;
		plain[ idx ]	= PGPNewData( mgr, ptrSize, 0);
		if ( IsntNull( plain[ idx ] ) )
		{
			flags	= PGPGetMemoryMgrDataInfo( plain[ idx ] );
			pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Valid ) != 0 );
			pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Secure ) == 0 );
			pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_NonPageable ) == 0 );
		}
		
		secure[ idx ]	= PGPNewSecureData( mgr, ptrSize, 0 );
		if ( IsntNull( secure[ idx ] ) )
		{
			flags	= PGPGetMemoryMgrDataInfo( secure[ idx ] );
			pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Valid ) != 0 );
			pgpAssert( ( flags & kPGPMemoryMgrBlockInfo_Secure ) != 0 );
		}
	}
	
	/* free even numbered items */
	for( idx = 0; idx < kNumTestPtrs; idx += 2 )
	{
		PGPFreeData( plain[ idx ] );
		PGPFreeData( secure[ idx ] );
	}
	
	/* free odd numbered items */
	for( idx = 1; idx < kNumTestPtrs; idx += 2 )
	{
		PGPFreeData( plain[ idx ] );
		PGPFreeData( secure[ idx ] );
	}

	/* test realloc case with NULL ptr */
	temp	= NULL;
	err	= PGPReallocData( mgr, &temp, 1000, 0 );
	pgpAssertNoErr( err );
	pgpAssert( IsntNull( temp ) );

	PGPFreeData( temp );
}


	static void
sTestMemoryMgr( PGPMemoryMgrRef mgr )
{
	void *			temp	= NULL;
	
	/* test normal allocation */
	temp	= PGPNewData( mgr, 1000,
				kPGPMemoryMgrFlags_Clear );
	if ( IsntNull( temp ) )
	{
		sTestUsingPtr( mgr, temp );
	}
	sTestMultiAllocations( mgr );

	/* test secure allocation */
	temp	= PGPNewSecureData( mgr, 1000,
				kPGPMemoryMgrFlags_Clear );
	if ( IsntNull( temp ) )
	{
		sTestUsingPtr( mgr, temp );
	}

	sTestMultiAllocations( mgr );
	
#if MEMORY_MGR_TRACK_LEAKS
	pgpAssert( mgr->numAllocations == 0 );
#endif

}

#endif


/*__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 + -