📄 cpgpmsgbackup.cpp
字号:
BOOL fPartied;
LPMAPITABLE ptableAttach = NULL;
SizedSPropTagArray(1, tagaTable) = {1, {PR_ATTACH_NUM}};
SRowSet *prAttach = NULL;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - RestoreBackup, pMsg = %#x, m_szMsg = %#x, "
"mail type = %s \n", this, m_pMsg, m_szMsg, m_bRTF?"RTF":(m_bHTML?"HTML":"PLAIN"));
#endif
//remove ourselves from the hash. doing this first alleviates the problem
//of this object being picked up from hash while it is being destroyed.
g_MsgBackupHash.Remove(m_pMsgStore, m_pEntryID, m_ulEntryIDSize);
hrRet = HrDispatchNotifications(0);
pgpAssert(S_OK == hrRet);
Sleep(250);
pgpAssert(NULL != m_pMsg);
if(NULL == m_pMsg)//if no message to operate on now
return;//bail out
/*if(NULL != m_pMsg)
{
//delete the decryption tag we put in the message since we are
//switching back to the original message now
SPropTagArray tagArr = {0};
tagArr.cValues = 1;
tagArr.aulPropTag[0] = PR_PGPEXCH_DECRYPTED;
hrRet = m_pMsg->DeleteProps(&tagArr, NULL);
pgpAssert(SUCCEEDED(hrRet));
}*/
if (m_szMsg != NULL)
{
SPropTagArray taga = {0};
#ifdef _DEBUG
ExchPluginTrace("\t CPGPMsgBackup(%#x) - Saved Mail => {%#x...%#x} \n", this, m_szMsg[0],
(0 < strlen(m_szMsg))?m_szMsg[strlen(m_szMsg)-1]:'\0');
#endif
taga.cValues = 1;
taga.aulPropTag[0] = PR_BODY_HTML;
hrRet = m_pMsg->DeleteProps(&taga, NULL);
pgpAssert(SUCCEEDED(hrRet));//failed to find the html body of the message
if (m_bRTF)
{
pgpAssert(NULL == pstrmBody);
hrRet = m_pMsg->OpenProperty(PR_RTF_COMPRESSED, &IID_IStream,
STGM_READWRITE, MAPI_MODIFY, (IUnknown**)&pstrmBody);
pgpAssert((S_OK == hrRet) && (NULL != pstrmBody));
if((S_OK == hrRet) && (NULL != pstrmBody))
{
hrRet = WrapCompressedRTFStream(pstrmBody, MAPI_MODIFY, &pstrmRTF);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pstrmRTF));
if(SUCCEEDED(hrRet) && (NULL != pstrmRTF))
{
hrRet = pstrmRTF->Write("\0", 1, NULL);
pgpAssert(S_OK == hrRet);
hrRet = pstrmRTF->SetSize(uli);
//pgpAssert(S_OK == hrRet);//TODO: investigate E_NOTIMPL
hrRet = pstrmRTF->Commit(STGC_DEFAULT);
pgpAssert(S_OK == hrRet);
pstrmRTF->Release();
pstrmRTF = NULL;
}
pstrmBody->Release();
pstrmBody = NULL;
hrRet = RTFSync(m_pMsg, RTF_SYNC_RTF_CHANGED, &fPartied);
pgpAssert(S_OK == hrRet);
}
}
pgpAssert(NULL == pstrmBody);
pgpAssert(NULL != m_pMsg);
if(NULL != m_pMsg)
{
hrRet = m_pMsg->OpenProperty(PR_BODY, &IID_IStream, STGM_READWRITE,
MAPI_MODIFY, (IUnknown**)&pstrmBody);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pstrmBody));
if (SUCCEEDED(hrRet) && (NULL != pstrmBody))
{
hrRet = pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
pgpAssert(S_OK == hrRet);
hrRet = pstrmBody->Write("\0", 1, NULL);
pgpAssert(S_OK == hrRet);
hrRet = pstrmBody->SetSize(uli);
pgpAssert(S_OK == hrRet);
hrRet = pstrmBody->Commit(STGC_DEFAULT);
pgpAssert(S_OK == hrRet);
pstrmBody->Release();
pstrmBody = NULL;
hrRet = RTFSync(m_pMsg, RTF_SYNC_BODY_CHANGED, &fPartied);
pgpAssert(S_OK == hrRet);
}
}
if(NULL != m_pMsg)
{
pgpAssert(NULL == pstrmBody);
hrRet = m_pMsg->OpenProperty(PR_BODY, &IID_IStream, STGM_READWRITE,
MAPI_CREATE | MAPI_MODIFY, (IUnknown**)&pstrmBody);//create if does not exist
pgpAssert(SUCCEEDED(hrRet) && (NULL != pstrmBody));
if(SUCCEEDED(hrRet) && (NULL != pstrmBody))
{
uli.LowPart = m_dwMsgSize;
hrRet = pstrmBody->Seek(li, STREAM_SEEK_SET, NULL);
pgpAssert(S_OK == hrRet);
hrRet = pstrmBody->Write(m_szMsg, m_dwMsgSize, NULL);
pgpAssert(S_OK == hrRet);
#ifdef _DEBUG
ExchPluginTrace("\t CPGPMsgBackup(%#x) - Saved body (%d bytes) written to PR_BODY \n",
this, m_dwMsgSize);
#endif
hrRet = pstrmBody->SetSize(uli);
pgpAssert(S_OK == hrRet);
hrRet = pstrmBody->Commit(STGC_DEFAULT);
pgpAssert(S_OK == hrRet);
pstrmBody->Release();
pstrmBody = NULL;
hrRet = RTFSync(m_pMsg, RTF_SYNC_BODY_CHANGED, &fPartied);
pgpAssert(S_OK == hrRet);
}
}
}
if (m_pFormat)
{
ULONG ulAttachNum = 0;
ULONG ulNumOfValues = 2;//to keep track of how many values we can set
LPATTACH pAttach = NULL;
IStream *pstrmAttach = NULL;
SPropValue pVal[5] = {0};
LPVOID lpBuffer = NULL;
#ifdef _DEBUG
ExchPluginTrace("\t CPGPMsgBackup(%#x) - Trying to restore formatted buffer of size %d {%#x %#x ... %#x}\n",
this, m_pFormat->dwSize, m_pFormat->szData?m_pFormat->szData[0]:'\0',
(m_pFormat->dwSize > 2)?m_pFormat->szData[1]:'\0',
(m_pFormat->dwSize > 3)?m_pFormat->szData[m_pFormat->dwSize-1]:'\0');
#endif
uli.LowPart = m_pFormat->dwSize;
pVal[0].ulPropTag = PR_ATTACH_METHOD;
pVal[0].Value.l = ATTACH_BY_VALUE;
pVal[1].ulPropTag = PR_RENDERING_POSITION;
pVal[1].Value.l = -1;
pVal[2].ulPropTag = PR_ATTACH_FILENAME;
hrRet = MAPIAllocateBuffer(MAX_PATH, (void **) &(pVal[2].Value.lpszA));
pgpAssert(SUCCEEDED(hrRet) && (NULL != pVal[2].Value.lpszA));
if(SUCCEEDED(hrRet) && (NULL != pVal[2].Value.lpszA))
{
pgpAssert(NULL == lpBuffer);
lpBuffer = pVal[2].Value.lpszA;//remember the first allocation
strcpy(pVal[2].Value.lpszA, m_pFormat->szName);
ulNumOfValues++;
}
if(3 == ulNumOfValues)
{
pVal[3].ulPropTag = PR_ATTACH_LONG_FILENAME;
pgpAssert(NULL != lpBuffer);
hrRet = MAPIAllocateMore(MAX_PATH, lpBuffer, (void **) &(pVal[3].Value.lpszA));
pgpAssert(SUCCEEDED(hrRet) && (NULL != pVal[3].Value.lpszA));
if(SUCCEEDED(hrRet) && (NULL != pVal[3].Value.lpszA))
{
strcpy(pVal[3].Value.lpszA, m_pFormat->szLongName);
ulNumOfValues++;
}
}
if(4 == ulNumOfValues)
{
pVal[4].ulPropTag = PR_DISPLAY_NAME;
pgpAssert(NULL != lpBuffer);
hrRet = MAPIAllocateMore(MAX_PATH, lpBuffer, (void **) &(pVal[4].Value.lpszA));
pgpAssert(SUCCEEDED(hrRet) && (NULL != pVal[4].Value.lpszA));
if(SUCCEEDED(hrRet) && (NULL != pVal[4].Value.lpszA))
{
strcpy(pVal[4].Value.lpszA, m_pFormat->szLongName);
ulNumOfValues++;
}
}
hrRet = m_pMsg->CreateAttach(NULL, 0, &ulAttachNum, &pAttach);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pAttach));
if(SUCCEEDED(hrRet) && (NULL != pAttach))
{
hrRet = pAttach->SetProps(ulNumOfValues, pVal, NULL);
pgpAssert(S_OK == hrRet);
pgpAssert(NULL == pstrmAttach);
hrRet = pAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, 0,
MAPI_CREATE | MAPI_MODIFY, (LPUNKNOWN *) &pstrmAttach);
pgpAssert(SUCCEEDED(hrRet) && (NULL != pstrmAttach));
if(SUCCEEDED(hrRet) && (NULL != pstrmAttach))
{
hrRet = pstrmAttach->Seek(li, STREAM_SEEK_SET, NULL);
pgpAssert(SUCCEEDED(hrRet));
hrRet = pstrmAttach->Write(m_pFormat->szData, m_pFormat->dwSize, NULL);
pgpAssert(SUCCEEDED(hrRet));
hrRet = pstrmAttach->SetSize(uli);
pgpAssert(SUCCEEDED(hrRet));
hrRet = pstrmAttach->Commit(STGC_DEFAULT);
pgpAssert(SUCCEEDED(hrRet));
pstrmAttach->Release();
pstrmAttach = NULL;
}
hrRet = pAttach->SaveChanges(0);
pgpAssert(SUCCEEDED(hrRet));
}
hrRet = m_pMsg->SaveChanges(KEEP_OPEN_READWRITE);
pgpAssert(SUCCEEDED(hrRet));
if(NULL != lpBuffer)
{
hrRet = MAPIFreeBuffer(lpBuffer);
pgpAssert(S_OK == hrRet);
lpBuffer = NULL;
}
}
hrRet = m_pMsg->GetAttachmentTable(0, &ptableAttach);
pgpAssert(SUCCEEDED(hrRet) && (NULL != ptableAttach));
if(SUCCEEDED(hrRet) && (NULL != ptableAttach))
{
hrRet = HrQueryAllRows(ptableAttach, (SPropTagArray *)&tagaTable,
NULL, NULL, 0, &prAttach);
pgpAssert(SUCCEEDED(hrRet) && (NULL != prAttach));
if(SUCCEEDED(hrRet) && (NULL != prAttach))
{
if (m_pHead && prAttach->cRows)
{
#ifdef _DEBUG
ExchPluginTrace("\t CPGPMsgBackup(%#x) - Restoring %d attachments of message \n",
this, prAttach->cRows);
#endif
((CPGPexch *) m_pCPGPexch)->DecryptVerifyRestoreAttachment(NULL,
m_pMsg, prAttach, TRUE);
}
FreeProws(prAttach);
prAttach = NULL;
ptableAttach->Release();
ptableAttach = NULL;
hrRet = m_pMsg->SaveChanges(0);
pgpAssert(SUCCEEDED(hrRet));
}
}
return;
}
void CPGPMsgBackup::AddToAttachList(ULONG ulIndex, PGPMsgBackupList **ppHead,
PGPMsgBackupList **ppCurrent)
{
PGPMsgBackupList *pNew;
pNew = (PGPMsgBackupList *) PGPNewData(m_memMgr, sizeof(PGPMsgBackupList),
kPGPMemoryMgrFlags_Clear);
pNew->ulIndex = ulIndex;
if (*ppHead == NULL)
*ppHead = pNew;
if (ppCurrent != NULL)
{
if (*ppCurrent != NULL)
(*ppCurrent)->pNext = pNew;
*ppCurrent = pNew;
}
return;
}
PGPMsgBackupList *CPGPMsgBackup::FindAttachment(ULONG ulIndex)
{
PGPMsgBackupList *pFind = NULL;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - FindAttachment looking for attachment index=%d ",
this, ulIndex);
#endif
pFind = m_pHead;
while (pFind != NULL)
{
if (pFind->ulIndex == ulIndex)
break;
pFind = pFind->pNext;
}
#ifdef _DEBUG
ExchPluginTrace("returning %#x\n", pFind);
#endif
return pFind;
}
PGPOLEBackupList *CPGPMsgBackup::FindOLEAttachment(ULONG ulIndex,
WCHAR *pwcsName)
{
PGPMsgBackupList *pFind;
PGPOLEBackupList *pFindOLE = NULL;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - FindOLEAttachment looking for OLE attachment index=%d name = %S ",
this, ulIndex, pwcsName);
#endif
pFind = FindAttachment(ulIndex);
if (pFind != NULL)
{
pFindOLE = pFind->poleHead;
while (pFindOLE != NULL)
{
if (!wcscmp(pwcsName, pFindOLE->pwcsName))
break;
pFindOLE = pFindOLE->pNext;
}
}
return pFindOLE;
}
void CPGPMsgBackup::FreeAttachList(PGPMsgBackupList *pHead)
{
PGPMsgBackupList *pTemp;
PGPOLEBackupList *poleTemp;
#ifdef _DEBUG
ExchPluginTrace("CPGPMsgBackup(%#x) - FreeAttachList(%#x)\n", this, pHead);
#endif
while (pHead != NULL)
{
if (pHead->szName != NULL)
PGPFreeData(pHead->szName);
if (pHead->szLongName != NULL)
PGPFreeData(pHead->szLongName);
if (pHead->szDisplayName != NULL)
PGPFreeData(pHead->szDisplayName);
if (pHead->szData != NULL)
PGPFreeData(pHead->szData);
while (pHead->poleHead != NULL)
{
if (pHead->poleHead->pwcsName != NULL)
PGPFreeData(pHead->poleHead->pwcsName);
if (pHead->poleHead->szData != NULL)
PGPFreeData(pHead->poleHead->szData);
poleTemp = pHead->poleHead;
pHead->poleHead = pHead->poleHead->pNext;
PGPFreeData(poleTemp);
}
pTemp = pHead;
pHead = pHead->pNext;
PGPFreeData(pTemp);
}
return;
}
HRESULT CPGPMsgBackup::GetMsgBody(void *&pBuf, DWORD &dwSize)
{
HRESULT hrRet = S_OK;
pgpAssert(NULL != m_pEntryID);
//check state
pgpAssert(NULL != m_szMsg);
pgpAssert(0 < m_dwMsgSize);
if((NULL == m_szMsg) || (0 == m_dwMsgSize))
{
hrRet = E_FAIL;
goto cleanup;
}
//reset out params
pBuf = NULL;
//allocate space necessary
pgpAssert(NULL == pBuf);
pBuf = calloc(1, m_dwMsgSize);
pgpAssert(NULL != pBuf);
if(NULL == pBuf)
{
hrRet = E_OUTOFMEMORY;
goto cleanup;
}
dwSize = m_dwMsgSize;
hrRet = S_OK;
cleanup:
if(FAILED(hrRet))
{
if(NULL != pBuf)
{
free(pBuf);
pBuf = NULL;
}
}
return hrRet;
}
BOOL CPGPMsgBackup::InsertThisToBackupHash()
{
BOOL bRet = FALSE;
PBACKUPMSGINFO pbmiMsgInfo = NULL;
//should have the message entry id by now
pgpAssert(NULL != m_pEntryID);
pgpAssert(0 < m_ulEntryIDSize);
if((NULL == m_pEntryID) || (0 >= m_ulEntryIDSize))
goto cleanup;
//allocate BACKUPMSGINFO structure
pbmiMsgInfo = (PBACKUPMSGINFO)calloc(1, sizeof(BACKUPMSGINFO));
pgpAssert(NULL != pbmiMsgInfo);
if(NULL == pbmiMsgInfo)
goto cleanup;
//allocate for entry id
pbmiMsgInfo->lpEntryID = (LPENTRYID)calloc(1, m_ulEntryIDSize);
pgpAssert(NULL != pbmiMsgInfo->lpEntryID);
if(NULL == pbmiMsgInfo->lpEntryID)
goto cleanup;
//copy the size allocated
pbmiMsgInfo->m_ulEntryIDSize = m_ulEntryIDSize;
//copy the entry id
memcpy(pbmiMsgInfo->lpEntryID, m_pEntryID, m_ulEntryIDSize);
//copy the object pointer
pbmiMsgInfo->pBackupObj = this;
bRet = g_MsgBackupHash.Insert(pbmiMsgInfo);
pgpAssert(TRUE == bRet);
if(FALSE == bRet)
goto cleanup;
bRet = TRUE; //all success
cleanup:
//free stuff upon failure
if((FALSE == bRet) && (NULL != pbmiMsgInfo))
{
if(NULL != pbmiMsgInfo->lpEntryID)
{
pgpAssert(0 < pbmiMsgInfo->m_ulEntryIDSize);
free(pbmiMsgInfo->lpEntryID);
pbmiMsgInfo->lpEntryID = NULL;
pbmiMsgInfo->m_ulEntryIDSize = 0;
}
free(pbmiMsgInfo);
pbmiMsgInfo = NULL;
}
return bRet;
}
#ifdef _DEBUG
static void TraceNotification(LPNOTIFICATION lpNotifications)
{
switch(lpNotifications->ulEventType)
{
case fnevCriticalError:
ExchPluginTrace("ulEventType = fnevCriticalError\n");
break;
case fnevNewMail:
ExchPluginTrace("ulEventType = fnevNewMail\n");
break;
case fnevObjectCreated:
ExchPluginTrace("ulEventType = fnevObjectCreated\n");
break;
case fnevObjectDeleted:
ExchPluginTrace("ulEventType = fnevObjectDeleted\n");
break;
case fnevObjectModified:
ExchPluginTrace("ulEventType = fnevObjectModified\n");
break;
case fnevObjectMoved:
ExchPluginTrace("ulEventType = fnevObjectMoved\n");
break;
case fnevObjectCopied:
ExchPluginTrace("ulEventType = fnevObjectCopied\n");
break;
case fnevSearchComplete:
ExchPluginTrace("ulEventType = fnevSearchComplete\n");
break;
case fnevTableModified:
ExchPluginTrace("ulEventType = fnevTableModified\n");
break;
case fnevStatusObjectModified:
ExchPluginTrace("ulEventType = fnevStatusObjectModified\n");
break;
case fnevReservedForMapi:
ExchPluginTrace("ulEventType = fnevReservedForMapi\n");
break;
case fnevExtended:
ExchPluginTrace("ulEventType = fnevExtended\n");
break;
default:
ExchPluginTrace("ulEventType = unknown(%#x)\n",
lpNotifications->ulEventType);
break;
}
}
#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 + -