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 + -
显示快捷键?