cpgpmsgbackuphash.cpp

来自「PGP8.0源码 请认真阅读您的文件包然后写出其具体功能」· C++ 代码 · 共 388 行

CPP
388
字号
////////////////////////////////////////////////////////////////////////////////
//  File : cpgpmsgbackuphash.cpp
//
//  Copyright (C) 2002 PGP Corporation
//
//  ABSTRACT
//		
// 
//  Author: Satya S. Das
////////////////////////////////////////////////////////////////////////////////

#include "CPGPexch.h"
#include "CPGPMsgBackupHash.h"
#include "pgpdebug.h"
#include "utils.h"


//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::CPGPMsgBackupHash				
//
//  Description:CPGPMsgBackupHash constructor. 
//  
//  In:	none
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
CPGPMsgBackupHash::CPGPMsgBackupHash()
{
	ZeroMemory(m_leArray, sizeof(m_leArray));

	m_ulCount=0;
	m_hMutex=NULL;
	m_bInited=FALSE;
}


//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::Init()
//
//  Description:Initializes the object if it has not been already
//				inited. changes the m_bInited flag to true if
//				successful.
//  In:	none
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
BOOL CPGPMsgBackupHash::Init()
{
	pgpAssert(0 == m_ulCount);
	pgpAssert(NULL == m_hMutex);
	pgpAssert(FALSE == m_bInited);
	if(TRUE == m_bInited)
		return TRUE;

	for (int iIndex=0;iIndex < BACKUPMSGINFO_HASHTABLE_SIZE; iIndex++)
        InitializeListHead(&m_leArray[iIndex]);
    
	m_hMutex=CreateMutex(NULL, FALSE, NULL);
	pgpAssert(NULL != m_hMutex);
	if(NULL == m_hMutex)
	{
#ifdef _DEBUG
		ExchPluginTrace("CreateMutex failed with error %d\n", GetLastError());
#endif
		return FALSE;
	}

	m_bInited=TRUE;
	return TRUE;
}

//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::Insert				
//
//  Description:This allows the client to insert a BACKUPMSGINFO block
//				into the hash.returns TRUE/FALSE depending on success
//				or failure.
//  In:	BACKUPMSGINFO pointer that is malloced should be passed to this.
//  
//  Out: 
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
BOOL CPGPMsgBackupHash::Insert(PBACKUPMSGINFO pMsgInfo)
{
	BOOL bRet=TRUE;
	ULONG ulIndex=0;

	//check parameters
	pgpAssert(NULL != pMsgInfo);
	pgpAssert(!IsBadReadPtr(pMsgInfo, sizeof(BACKUPMSGINFO)));
	if((NULL == pMsgInfo) || IsBadReadPtr(pMsgInfo, sizeof(BACKUPMSGINFO)))
		return FALSE;

	//if not inited
	if(FALSE == m_bInited)
	{
		bRet=Init();//initialze ourselves
		if(FALSE == bRet)
			return FALSE;
	}

	pgpAssert(NULL != pMsgInfo->lpEntryID);
	pgpAssert(0 < pMsgInfo->m_ulEntryIDSize);
	pgpAssert(NULL != pMsgInfo->pBackupObj);

	ulIndex=(pMsgInfo->m_ulEntryIDSize)%BACKUPMSGINFO_HASHTABLE_SIZE;
	pgpAssert(ulIndex < BACKUPMSGINFO_HASHTABLE_SIZE);//TODO: this may not be optimal

	
	pgpAssert(NULL != m_hMutex);
	WaitForSingleObject(m_hMutex, INFINITE);
	InsertHeadList(&m_leArray[ulIndex], (PLIST_ENTRY)pMsgInfo);
	m_ulCount++;
	ReleaseMutex(m_hMutex);

	return TRUE;
}


//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::Remove				
//
//  Description:This function accepts request to remove a certain
//				BACKUPMSGINFO blob from the hash based on the entry 
//				id So this searches the hash table for that and when 
//				found deletes it from the hash table. returns 
//				TRUE/FALSE.
//  
//  In:	the key to the BACKUPMSGINFO blob(=HWND)
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
BOOL CPGPMsgBackupHash::Remove(LPMDB lpMsgStore, LPENTRYID lpEntryId, 
							   ULONG ulEntryIDLen)
{
#ifdef _DEBUG
	ExchPluginTrace("CPGPMsgBackupHash::Remove lpEntryId=%#x of len = %d\n", 
			lpEntryId, ulEntryIDLen);	
#endif

	ULONG ulIndex=0;
	ULONG ulResult=0;
	PBACKUPMSGINFO pMsgInfo=NULL;
	PLIST_ENTRY pListEntry=NULL;
	BOOL bRet=FALSE;
	HRESULT hrRet=S_OK;

	//if not inited
	if(FALSE == m_bInited)
	{
		pgpAssert(FALSE);//should have been inited by now
		return FALSE;//if not inited there cannot be anything to remove
	}

	ulIndex=(ulEntryIDLen)%BACKUPMSGINFO_HASHTABLE_SIZE;
	pgpAssert(ulIndex < BACKUPMSGINFO_HASHTABLE_SIZE);

	pgpAssert(NULL != m_hMutex);
	WaitForSingleObject(m_hMutex, INFINITE);

	for (pListEntry=m_leArray[ulIndex].Flink; 
		 pListEntry != &m_leArray[ulIndex];
		 pListEntry = pListEntry->Flink)
	{
		pMsgInfo = (PBACKUPMSGINFO)pListEntry;
		pgpAssert(NULL != pMsgInfo); 

		//compare the entry id to the one represented in this backup
		pgpAssert(NULL != lpMsgStore);
		hrRet = lpMsgStore->CompareEntryIDs(ulEntryIDLen, lpEntryId, 
				pMsgInfo->m_ulEntryIDSize, pMsgInfo->lpEntryID, 0, &ulResult);
		pgpAssert(SUCCEEDED(hrRet));//NOTE we do not quit upon failure to compare
		if(SUCCEEDED(hrRet) && (TRUE == ulResult))//if we found the entry in the hash
		{
			//remove from the linked list
			RemoveEntryList(pListEntry);

			//free the entry itself
			FreeMsgInfo((PBACKUPMSGINFO)pListEntry);

#ifdef _DEBUG
			ExchPluginTrace("CPGPMsgBackupHash::Removed entry for CPGPMsgBackup(%#x)\n", 
					pMsgInfo->pBackupObj);	
#endif
			
			//object chores
			m_ulCount--;
			bRet=TRUE;
			break;
		}
	}

	pgpAssert(TRUE == bRet);//we were called to remove something that was not in
							//the hash in the first place (not good)

	pgpAssert(NULL != m_hMutex);
	ReleaseMutex(m_hMutex);
	return bRet;
}

//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::Get				
//
//  Description:Searches the hash table for a particular entry id. 
//				Pass the id and this will find the corresponding 
//				BACKUPMSGINFO block of info that was inserted 
//				earlier into this hash table. It returns NULL pointer 
//				if there is no info.
//  
//  In:	the key.
//  
//  Out: BACKUPMSGINFO pointer that was inserted earlier
//  
//  Comments:caller MUST NOT free the PBACKUPMSGINFO returned from this 
//			function. The PBACKUPMSGINFO gotten is the original 
//			PBACKUPMSGINFO that was inserted so freeing this will corrupt 
//			the hash table. caller MUST take due care while accessing 
//			members	of the struct as multiple threads could be accessing 
//			it at any given time.
///////////////////////////////////////////////////////////////////
PBACKUPMSGINFO CPGPMsgBackupHash::Get(LPMDB lpMsgStore, 
				LPENTRYID lpEntryId, ULONG ulEntryIDLen)
{
	ULONG ulIndex=0;
	ULONG ulResult=0;
	HRESULT hrRet=S_OK;
	BOOL bRet=FALSE;
	PBACKUPMSGINFO pMsgInfo=NULL;
	PLIST_ENTRY pListEntry=NULL;

	//if not inited
	if(FALSE == m_bInited)
	{
		bRet=Init();//initialize ourselves
		if(FALSE == bRet)
			return FALSE;
	}

	ulIndex=ulEntryIDLen%BACKUPMSGINFO_HASHTABLE_SIZE;
	pgpAssert(ulIndex < BACKUPMSGINFO_HASHTABLE_SIZE);

	pgpAssert(NULL != m_hMutex);
	WaitForSingleObject(m_hMutex, INFINITE);

	for (pListEntry = m_leArray[ulIndex].Flink; 
		 pListEntry != &m_leArray[ulIndex];
		 pListEntry = pListEntry->Flink)
	{
		pMsgInfo = (PBACKUPMSGINFO)pListEntry;
		pgpAssert(NULL != pMsgInfo);
		pgpAssert(!IsBadReadPtr(pMsgInfo, sizeof(BACKUPMSGINFO)));

		//compare the entry id to the one represented in this backup
		pgpAssert(NULL != lpMsgStore);
		hrRet = lpMsgStore->CompareEntryIDs(ulEntryIDLen, lpEntryId, 
				pMsgInfo->m_ulEntryIDSize, pMsgInfo->lpEntryID, 0, &ulResult);
		pgpAssert(SUCCEEDED(hrRet));//NOTE we do not quit upon failure to compare
		if(SUCCEEDED(hrRet) && (TRUE == ulResult))//if we found the entry in the hash
		{
			bRet=TRUE;
			break;
		}
	}

	pgpAssert(NULL != m_hMutex);
	ReleaseMutex(m_hMutex);

	return (bRet?pMsgInfo:NULL);
}

//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::~CPGPMsgBackupHash				
//
//  Description:CPGPMsgBackupHash destructor. If we have any blobs in the
//				the hash table we free up the blobs. We also free the
//				mutex object.
//  
//  In:	none
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
CPGPMsgBackupHash::~CPGPMsgBackupHash()
{
	if(m_bInited && (0 < m_ulCount))//if inited and non-empty linked list
	{
		//free all the elements in the linked lists
		pgpAssert(NULL != m_hMutex);
		WaitForSingleObject(m_hMutex, INFINITE);

		PLIST_ENTRY pListEntry=NULL;
		for (int iIndex=0;iIndex < BACKUPMSGINFO_HASHTABLE_SIZE; iIndex++)
		{
			for (pListEntry = m_leArray[iIndex].Flink; 
				 pListEntry != &m_leArray[iIndex];
				 pListEntry=pListEntry->Flink)
			{
				//remove from the linked list
				pgpAssert(NULL != pListEntry);
				RemoveEntryList(pListEntry);

				//free the entry itself
				FreeMsgInfo((PBACKUPMSGINFO)pListEntry);

				pListEntry=m_leArray[iIndex].Flink;
			}
		}

		pgpAssert(NULL != m_hMutex);
		ReleaseMutex(m_hMutex);
	}


	if(NULL != m_hMutex)
	{
		BOOL bRet=CloseHandle(m_hMutex);
		pgpAssert(TRUE == bRet);
		m_hMutex=NULL;
	}
}


//////////////////////////////////////////////////////////////////
//	Name:CPGPMsgBackupHash::FreeMsgInfo				
//
//  Description:Routine used internally to free the BACKUPMSGINFO blob.
//				If you add new members to BACKUPMSGINFO structure add 
//				the	cleanup code in this function.
//  
//  In:	PBACKUPMSGINFO - the pointer to the BACKUPMSGINFO block to be 
//		cleaned up
//  
//  Out: none
//  
//  Comments:		
///////////////////////////////////////////////////////////////////
void CPGPMsgBackupHash::FreeMsgInfo(PBACKUPMSGINFO lpMsgInfo)
{
	PLIST_ENTRY pListEntry=NULL;

	pgpAssert(NULL != lpMsgInfo);
	if(NULL == lpMsgInfo)
		return;

	pgpAssert(NULL != lpMsgInfo->lpEntryID);
	pgpAssert(0 < lpMsgInfo->m_ulEntryIDSize);
	if(NULL != lpMsgInfo->lpEntryID)
	{
		free(lpMsgInfo->lpEntryID);
		lpMsgInfo->lpEntryID = NULL;
		lpMsgInfo->m_ulEntryIDSize = 0;
	}

	free(lpMsgInfo);
	lpMsgInfo=NULL;
}

void CPGPMsgBackupHash::Lock()
{
	pgpAssert(TRUE == m_bInited);
	pgpAssert(NULL != m_hMutex);
	if((TRUE == m_bInited) && (NULL != m_hMutex))
	{
		DWORD dwRet = WaitForSingleObject(m_hMutex, INFINITE);
		pgpAssert(WAIT_OBJECT_0 == dwRet);
	}
}

void CPGPMsgBackupHash::UnLock()
{
	pgpAssert(TRUE == m_bInited);
	pgpAssert(NULL != m_hMutex);
	if((TRUE == m_bInited) && (NULL != m_hMutex))
	{
		BOOL bRet = ReleaseMutex(m_hMutex);
		pgpAssert(TRUE == bRet);
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?