📄 cpgpmsgbackup.cpp
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: CPGPMsgBackup.cpp,v 1.14 2002/11/14 22:57:23 sdas Exp $
____________________________________________________________________________*/
#include "CPGPexch.h"
#include <mapiutil.h>
#include "pgpDebug.h"
#include "cpgpmsgbackuphash.h"
extern "C" void ExchPluginTrace(LPCTSTR lpszFormat, ...);
extern CPGPMsgBackupHash g_MsgBackupHash;
#ifdef _DEBUG
static void TraceNotification(LPNOTIFICATION lpNotifications);
#endif
CPGPMsgBackup::CPGPMsgBackup(void *pCPGPexch, PGPMemoryMgrRef memMgr,
IMsgStore *pMsgStore, IMessage *pmsg) : _cRef(1)
{
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - constructed for CPGPexch(%#x)\n", this, pCPGPexch);
#endif
m_ulBkRef = 1;
m_pEntryID = NULL;
m_ulEntryIDSize = 0;
pgpAssert(NULL != pMsgStore);
if (pMsgStore != NULL)
pMsgStore->AddRef();
m_pMsgStore = pMsgStore;
pgpAssert(NULL != pmsg);
if (NULL != pmsg)
pmsg->AddRef();
m_pMsg = pmsg;
pgpAssert(NULL != pCPGPexch);
m_pCPGPexch = pCPGPexch;
m_ulAdvise = 0;
pgpAssert(NULL != m_memMgr);
m_memMgr = memMgr;
m_szMsg = NULL;
m_dwMsgSize = 0;
m_ulFormatIndex = 0;
m_bHTML = FALSE;
m_bRTF = FALSE;
m_pFormat = NULL;
m_pHead = NULL;
m_pCurrent = NULL;
}
CPGPMsgBackup::~CPGPMsgBackup()
{
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - being destroyed\n", this);
#endif
//restore the backup message
this->RestoreBackup();
if (m_szMsg != NULL)
{
PGPFreeData(m_szMsg);
m_szMsg = NULL;
}
FreeAttachList(m_pFormat);
FreeAttachList(m_pHead);
if ((m_pMsgStore != NULL) && (0 < m_ulAdvise))
{
m_pMsgStore->Unadvise(m_ulAdvise);
m_ulAdvise = 0;
}
if (m_pMsg != NULL)
{
m_pMsg->Release();
m_pMsg = NULL;
}
if (m_pMsgStore != NULL)
{
m_pMsgStore->Release();
m_pMsgStore = NULL;
}
if(NULL != m_pEntryID)
{
pgpAssert(0 < m_ulEntryIDSize);
free(m_pEntryID);
m_pEntryID = NULL;
m_ulEntryIDSize = 0;
}
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - destruction complete\n", this);
#endif
}
STDMETHODIMP CPGPMsgBackup::QueryInterface(REFIID riid, void** ppvObj)
{
*ppvObj = NULL;
HRESULT hr = S_OK;
IUnknown* punk = NULL;
if (( IID_IUnknown == riid) || ( IID_IMAPIAdviseSink == riid) )
{
punk = this;
}
else
hr = E_NOINTERFACE;
if (NULL != punk)
{
*ppvObj = punk;
AddRef();
}
return hr;
}
ULONG CPGPMsgBackup::BackupAddRef()
{
pgpAssert(0 != m_ulBkRef);//should not already be gone
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - BackupAddRef(incrementing to %d)\n)",
this, m_ulBkRef+1);
#endif
++m_ulBkRef;
return m_ulBkRef;
}
ULONG CPGPMsgBackup::BackupRelease()
{
pgpAssert(0 != m_ulBkRef);//should not already be gone
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - BackupRelease(decrementing to %d)\n",
this, m_ulBkRef-1);
#endif
ULONG ulCount = --m_ulBkRef;
if (!ulCount)
delete this; //self-destruct
return ulCount;
}
LPVOID CPGPMsgBackup::GetCreator()
{
return m_pCPGPexch;
}
//method to set the entryid on the message around which this object operates
STDMETHODIMP CPGPMsgBackup::SetMessageEntryID(LPVOID lpEntryID, ULONG ulSize)
{
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - SetMessageEntryID(entryid->%#x of len %d)\n",
this, lpEntryID, ulSize);
#endif
BOOL bRet = FALSE;
//check parameters
pgpAssert(NULL != lpEntryID);
pgpAssert(ulSize > 0);
if((NULL == lpEntryID) || (0 == ulSize))//if null pointer or zero length
return E_INVALIDARG;//we are done/invalid parameter(s)
pgpAssert(!IsBadReadPtr(lpEntryID, ulSize));
if(TRUE == IsBadReadPtr(lpEntryID, ulSize))
return E_POINTER;//bad parameter/pointer
//check object state
pgpAssert(NULL == m_pEntryID);//we should be called to set the message entry ID only once
if(NULL != m_pEntryID)//if we are being called for a second time
return E_FAIL;//ignore such attempts
//allocate for the size required
m_pEntryID = (LPENTRYID)calloc(1, ulSize);
if(NULL == m_pEntryID)//failed to allocate
return E_OUTOFMEMORY;
//copy the entry id to object member
memcpy(m_pEntryID, lpEntryID, ulSize);
m_ulEntryIDSize = ulSize;
//insert this into backup hash
bRet = InsertThisToBackupHash();
pgpAssert(TRUE == bRet);//failed to insert into hash !!
return S_OK;
}
STDMETHODIMP CPGPMsgBackup::WatchMsgForDelOrMove(BOOL bStart)
{
HRESULT hrRet = S_OK;
pgpAssert(NULL != m_pMsgStore);//should know the store
pgpAssert(NULL != m_pMsg);//should know the message
pgpAssert(NULL != m_pEntryID);//should also know the entry id
pgpAssert(bStart == (0 == m_ulAdvise));//should not be watching already if we are
//being told now to (or vice versa)
if((NULL == m_pMsgStore) || (NULL == m_pMsg) ||
(NULL == m_pEntryID) || (bStart != (0 == m_ulAdvise)))
return E_FAIL;
//if we are being told to start watching for this message
if(TRUE == bStart)
{
//watch the message for deletion or move
hrRet = m_pMsgStore->Advise(m_ulEntryIDSize, (LPENTRYID)m_pEntryID,
fnevObjectDeleted|fnevObjectMoved,
(IMAPIAdviseSink *) this, &m_ulAdvise);
pgpAssert(SUCCEEDED(hrRet) && (m_ulAdvise > 0));
#ifdef _DEBUG
if(SUCCEEDED(hrRet) && (m_ulAdvise > 0))
ExchPluginTrace("CPGPMsgBackup(%#x) - watching message {..%#x..%#x..%#x..} id len = %d sink = %d\n",
this, ((char *)m_pEntryID)[m_ulEntryIDSize/4], ((char *)m_pEntryID)[m_ulEntryIDSize/2],
((char *)m_pEntryID)[3*m_ulEntryIDSize/4], m_ulEntryIDSize, m_ulAdvise);
#endif
}
else
{
//we are being told to stop watching for this message
pgpAssert(0 < m_ulAdvise);
hrRet = m_pMsgStore->Unadvise(m_ulAdvise);
pgpAssert(SUCCEEDED(hrRet));//cant do much if this fails
m_ulAdvise = 0;//disremember the previous sink
}
return hrRet;
}
STDMETHODIMP_(ULONG)
CPGPMsgBackup::OnNotify(ULONG cNotif, LPNOTIFICATION lpNotifications)
{
if (cNotif > 0)
{
ULONG ulType;
HRESULT hrRet = S_OK;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - OnNotify\n", this);
TraceNotification(lpNotifications);
#endif
if(m_pMsg != NULL)
{
//delete the decryption tag we put in the message since we dont know
//if we will get back at any message after releasing this
/*SizedSPropTagArray(1, tagArr) = {1, {PR_PGPEXCH_DECRYPTED}};
hrRet = m_pMsg->DeleteProps((SPropTagArray *)&tagArr, NULL);
pgpAssert(SUCCEEDED(hrRet));*/
m_pMsg->Release();
m_pMsg = NULL;
}
pgpAssert(NULL == m_pMsg);
pgpAssert(NULL != m_pMsgStore);
hrRet = m_pMsgStore->OpenEntry(lpNotifications->info.obj.cbEntryID,
lpNotifications->info.obj.lpEntryID, NULL, MAPI_MODIFY,
&ulType, (IUnknown **) &m_pMsg);
pgpAssert(SUCCEEDED(hrRet) && (NULL != m_pMsg));
#ifdef _DEBUG
if(SUCCEEDED(hrRet) && (NULL != m_pMsg))
ExchPluginTrace("CPGPMsgBackup(%#x) - now watching message %#x%#x...%#x now\n",
this, lpNotifications->info.obj.lpEntryID[0],
lpNotifications->info.obj.lpEntryID[1],
lpNotifications->info.obj.lpEntryID[lpNotifications->info.obj.cbEntryID-1]);
#endif
}
return S_OK;
}
HRESULT CPGPMsgBackup::AddMessage(char *szMsg, DWORD dwSize)
{
//check parameters
pgpAssert(NULL != szMsg);
pgpAssert(dwSize > 0);
if((NULL == szMsg) || (0 == dwSize))
return E_INVALIDARG;
//check object state
pgpAssert(NULL == m_szMsg);
if(NULL != m_szMsg)
return E_FAIL;
//allocate as necessary
m_szMsg = (char *) PGPNewData(m_memMgr, dwSize+1, kPGPMemoryMgrFlags_Clear);
pgpAssert(NULL != m_szMsg);
if(NULL == m_szMsg)
return E_OUTOFMEMORY;
//copy to member
memcpy(m_szMsg, szMsg, dwSize);
m_szMsg[dwSize] = '\0';
m_dwMsgSize = dwSize;
return S_OK;
}
void CPGPMsgBackup::SetFormat(BOOL bHTML, BOOL bRTF)
{
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - SetFormat (\"%s\")\n",
this, bHTML?"HTML":(bRTF?"RTF":"PLAIN"));
#endif
pgpAssert((TRUE == bHTML)?(FALSE == bRTF):TRUE);//both cannot be set
m_bHTML = bHTML;
m_bRTF = bRTF;
return;
}
void CPGPMsgBackup::AddAttachment(ULONG ulIndex, BOOL bIsFormat, char *szName,
char *szLongName, char *szDisplayName,
char *szData, DWORD dwSize)
{
PGPMsgBackupList *pNew = NULL;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - AddAttachment (\"%s\" of size %d) at index=%d format=%d\n",
this, szLongName, dwSize, ulIndex, bIsFormat);
#endif
if (bIsFormat)
{
AddToAttachList(ulIndex, &m_pFormat, NULL);
pNew = m_pFormat;
m_ulFormatIndex = ulIndex;
}
else
{
AddToAttachList(ulIndex, &m_pHead, &m_pCurrent);
pNew = m_pCurrent;
}
if (szName != NULL)
{
pNew->szName = (char *) PGPNewData(m_memMgr, strlen(szName)+1, kPGPMemoryMgrFlags_Clear);
strcpy(pNew->szName, szName);
}
if (szLongName != NULL)
{
pNew->szLongName = (char *) PGPNewData(m_memMgr, strlen(szLongName)+1, kPGPMemoryMgrFlags_Clear);
strcpy(pNew->szLongName, szLongName);
}
pNew->szData = (char *) PGPNewData(m_memMgr, dwSize+1, kPGPMemoryMgrFlags_Clear);
memcpy(pNew->szData, szData, dwSize);
pNew->szData[dwSize] = 0;
pNew->dwSize = dwSize;
return;
}
void CPGPMsgBackup::AddOLE(ULONG ulIndex, WCHAR *pwcsName, char *szData,
DWORD dwSize)
{
PGPMsgBackupList *pNew = NULL;
PGPOLEBackupList *pOLE = NULL;
pNew = FindAttachment(ulIndex);
if (pNew == NULL)
{
AddToAttachList(ulIndex, &m_pHead, &m_pCurrent);
pNew = m_pCurrent;
}
pOLE = (PGPOLEBackupList *) PGPNewData(m_memMgr, sizeof(PGPOLEBackupList),
kPGPMemoryMgrFlags_Clear);
if (pwcsName != NULL)
{
pOLE->pwcsName = (WCHAR *) PGPNewData(m_memMgr, (wcslen(pwcsName)+1) * sizeof(WCHAR),
kPGPMemoryMgrFlags_Clear);
wcscpy(pOLE->pwcsName, pwcsName);
}
pOLE->szData = (char *) PGPNewData(m_memMgr, dwSize+1, kPGPMemoryMgrFlags_Clear);
memcpy(pOLE->szData, szData, dwSize);
pOLE->szData[dwSize] = 0;
pOLE->dwSize = dwSize;
if (pNew->poleHead == NULL)
pNew->poleHead = pOLE;
if (pNew->poleCurrent != NULL)
pNew->poleCurrent->pNext = pOLE;
pNew->poleCurrent = pOLE;
return;
}
HRESULT CPGPMsgBackup::IsBackupOfMsg(IMessage *pMsg, BOOL &bResult)
{
SPropValue *pval = NULL;
HRESULT hrRet = S_OK;
ULONG ulResult = 0;
pgpAssert(NULL != pMsg);
if(NULL == pMsg)
return E_INVALIDARG;
//get the entry id of the message
hrRet = HrGetOneProp(pMsg, PR_ENTRYID, &pval);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pval) &&
(NULL != pval->Value.bin.lpb) && (0 < pval->Value.bin.cb));
if(FAILED(hrRet) || (NULL == pval) || (NULL == pval->Value.bin.lpb) ||
(0 == pval->Value.bin.cb))
goto cleanup;
//compare the entry id to the one we represent currently
pgpAssert(NULL != m_pMsgStore);
hrRet = m_pMsgStore->CompareEntryIDs(m_ulEntryIDSize, m_pEntryID, pval->Value.bin.cb,
(LPENTRYID)pval->Value.bin.lpb, 0, &ulResult);
pgpAssert(SUCCEEDED(hrRet));
if(FAILED(hrRet))
goto cleanup;
//copy the result to the out parameter
bResult = ulResult;
cleanup:
if(NULL != pval)
{
HRESULT hrResult = MAPIFreeBuffer(pval);
pgpAssert(S_OK == hrResult);
pval = NULL;
}
return hrRet;
}
HRESULT CPGPMsgBackup::IsAlreadyBackedUp(LPMDB lpMsgStore, LPMESSAGE lpMsg,
CPGPMsgBackup *&ppmbMsgBackup)
{
SPropValue *pval = NULL;
PBACKUPMSGINFO pbmiMsgInfo = NULL;
HRESULT hrRet = S_OK;
//check parameters
pgpAssert(NULL != lpMsgStore);
pgpAssert(NULL != lpMsg);
if((NULL == lpMsgStore) || (NULL == lpMsg))
{
hrRet = E_INVALIDARG;
goto cleanup;
}
//get the entry id of the message
hrRet = HrGetOneProp(lpMsg, PR_ENTRYID, &pval);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pval) &&
(NULL != pval->Value.bin.lpb) && (0 < pval->Value.bin.cb));
if(FAILED(hrRet) || (NULL == pval) || (NULL == pval->Value.bin.lpb) ||
(0 == pval->Value.bin.cb))
{
hrRet = E_FAIL;
goto cleanup;
}
//find this message in the backup hash (if it is in there somewhere)
pbmiMsgInfo = g_MsgBackupHash.Get(lpMsgStore, (LPENTRYID)pval->Value.bin.lpb,
pval->Value.bin.cb);
if(NULL != pbmiMsgInfo)//if we got the object pointer
{
//copy it to out param
g_MsgBackupHash.Lock();
ppmbMsgBackup = pbmiMsgInfo->pBackupObj;
g_MsgBackupHash.UnLock();
}
hrRet = S_OK; //all success
cleanup:
if(NULL != pval)
{
HRESULT hrResult = MAPIFreeBuffer(pval);
pgpAssert(S_OK == hrResult);
pval = NULL;
}
return hrRet;
}
HRESULT CPGPMsgBackup::GetFormatInfoIfAny(void *&pFormatInfo,
DWORD &dwFormatInfoSize, DWORD &dwFormatInfoType)
{
HRESULT hrRet = S_OK;
//check state
pgpAssert(NULL != m_pMsg);
//reset contents of output params
pFormatInfo = NULL;
dwFormatInfoSize = 0;
dwFormatInfoType = 0;
//if there is no formatting information
if((TRUE != m_bHTML) && (TRUE != m_bRTF))
return S_OK;//we are done - this is a plain text message
pgpAssert((NULL != m_pFormat) && (0 < m_pFormat->dwSize) && (NULL != m_pFormat->szData));
if((NULL == m_pFormat) || (0 == m_pFormat->dwSize) || (NULL == m_pFormat->szData))
return E_FAIL;
//allocate space necessary
pgpAssert(NULL == pFormatInfo);
pFormatInfo = calloc(1, m_pFormat->dwSize);
pgpAssert(NULL != pFormatInfo);
if(NULL == pFormatInfo)
{
hrRet = E_OUTOFMEMORY;
goto cleanup;
}
//copy the buffer
memcpy(pFormatInfo, m_pFormat->szData, m_pFormat->dwSize);
dwFormatInfoSize = m_pFormat->dwSize;
dwFormatInfoType = m_bHTML?SFPA_FOUND_HTML_DATA:SFPA_FOUND_RTF_DATA;
hrRet = S_OK;
cleanup:
if(FAILED(hrRet))//in case we failed
{
//free the allocated buffer if required
if(NULL != pFormatInfo)
{
free(pFormatInfo);
pFormatInfo = NULL;
}
}
return hrRet;
}
void CPGPMsgBackup::RestoreBackup()
{
HRESULT hrRet = S_OK;
IStream *pstrmBody = NULL;
IStream *pstrmRTF = NULL;
LARGE_INTEGER li = {0};
ULARGE_INTEGER uli = {1,0};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -