You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1930 lines
56 KiB
1930 lines
56 KiB
#include "pch.hxx"
|
|
#include "msgsite.h"
|
|
#include "secutil.h"
|
|
#include "mailutil.h"
|
|
#include "conman.h"
|
|
#include "newfldr.h"
|
|
#include "storutil.h"
|
|
#include "msoeobj.h"
|
|
#include "regutil.h"
|
|
#include "mapiutil.h"
|
|
#include "browser.h"
|
|
#include "receipts.h"
|
|
#include "shlwapip.h"
|
|
#include "msoert.h"
|
|
|
|
// ****************************************
|
|
COEMsgSite::COEMsgSite()
|
|
{
|
|
m_pMsg = NULL;
|
|
m_pOrigMsg = NULL;
|
|
m_pStoreCB = NULL;
|
|
m_pMsgTable = NULL;
|
|
m_pListSelect = NULL;
|
|
m_pCBMsgFolder = NULL;
|
|
|
|
m_fCBCopy = FALSE;
|
|
m_fCBSavedInDrafts = FALSE;
|
|
m_fCBSaveInFolderAndDelOrig = FALSE;
|
|
|
|
m_fGotNewID = FALSE;
|
|
m_fHeaderOnly = FALSE;
|
|
m_fValidMessage = FALSE;
|
|
m_fNeedToLoadMsg = TRUE;
|
|
m_fHaveCBMessageID = TRUE;
|
|
m_fThreadingEnabled = FALSE;
|
|
m_fReloadMessageFlag = TRUE;
|
|
|
|
m_dwArfFlags = 0;
|
|
m_dwMSAction = MSA_IDLE;
|
|
m_dwCMFState = CMF_UNINITED;
|
|
m_dwOrigFolderIsImap = OFIMAP_UNDEFINED;
|
|
|
|
m_cRef = 1;
|
|
|
|
m_FolderID = FOLDERID_INVALID;
|
|
m_CBFolderID = FOLDERID_INVALID;
|
|
|
|
m_MessageID = 0;
|
|
m_CBMessageID = 0;
|
|
m_NewMessageID = 0;
|
|
|
|
*m_rgwchFileName = 0;
|
|
|
|
m_pFolderReleaseOnComplete = NULL;
|
|
|
|
m_dwMDNFlags = 0;
|
|
|
|
if (!!DwGetOption(OPT_MDN_SEND_REQUEST))
|
|
m_dwMDNFlags |= MDN_REQUEST;
|
|
|
|
}
|
|
|
|
// ****************************************
|
|
COEMsgSite::~COEMsgSite()
|
|
{
|
|
Assert(!m_pMsg);
|
|
Assert(!m_pOrigMsg);
|
|
Assert(!m_pMsgTable);
|
|
Assert(!m_pStoreCB);
|
|
Assert(!m_pListSelect);
|
|
AssertSz(!m_pCBMsgFolder, "Who missed freeing this?");
|
|
|
|
ReleaseObj(m_pFolderReleaseOnComplete);
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::QueryInterface(REFIID riid, LPVOID FAR *lplpObj)
|
|
{
|
|
if(!lplpObj)
|
|
return E_INVALIDARG;
|
|
|
|
*lplpObj = NULL;
|
|
|
|
if (IsEqualIID(riid, IID_IUnknown))
|
|
*lplpObj = (LPVOID)this;
|
|
else
|
|
return E_NOINTERFACE;
|
|
|
|
AddRef();
|
|
return NOERROR;
|
|
}
|
|
|
|
// ****************************************
|
|
ULONG COEMsgSite::AddRef()
|
|
{
|
|
return ++m_cRef;
|
|
}
|
|
|
|
// ****************************************
|
|
ULONG COEMsgSite::Release()
|
|
{
|
|
if(--m_cRef==0)
|
|
{
|
|
delete this;
|
|
return 0;
|
|
}
|
|
return m_cRef;
|
|
}
|
|
|
|
// ****************************************
|
|
BOOL COEMsgSite::ThreadingEnabled(void)
|
|
{
|
|
BOOL fEnabled = FALSE;
|
|
FOLDERSORTINFO SortInfo;
|
|
|
|
Assert(OEMSIT_MSG_TABLE == m_dwInitType);
|
|
|
|
if (SUCCEEDED(m_pMsgTable->GetSortInfo(&SortInfo)))
|
|
fEnabled = SortInfo.fThreaded;
|
|
|
|
return fEnabled;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::Init(INIT_MSGSITE_STRUCT *pInitStruct)
|
|
{
|
|
// WARNING!!! pStoreCB will not have been setup by this point.
|
|
// Use it in this function only if you are sure things will work.
|
|
// For instance, the hwnd will not get setup yet so GetCallbackHwnd
|
|
// will not work appropriatly.
|
|
|
|
Assert(pInitStruct);
|
|
|
|
HRESULT hr = S_OK;
|
|
m_dwInitType = pInitStruct->dwInitType;
|
|
m_fValidMessage = TRUE;
|
|
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
{
|
|
Assert (m_pMsgTable==NULL);
|
|
|
|
ReplaceInterface(m_pMsgTable, pInitStruct->initTable.pMsgTable);
|
|
if (m_pMsgTable)
|
|
m_pMsgTable->ConnectionAddRef();
|
|
|
|
ReplaceInterface(m_pListSelect, pInitStruct->initTable.pListSelect);
|
|
hr = m_pMsgTable->GetRowMessageId(pInitStruct->initTable.rowIndex, &m_MessageID);
|
|
if (FAILED(hr))
|
|
break;
|
|
|
|
m_FolderID = pInitStruct->folderID;
|
|
m_fThreadingEnabled = ThreadingEnabled();
|
|
break;
|
|
}
|
|
|
|
case OEMSIT_STORE:
|
|
AssertSz(FALSE, "Can't init using the store...");
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
|
|
case OEMSIT_FAT:
|
|
StrCpyNW(m_rgwchFileName, pInitStruct->pwszFile, ARRAYSIZE(m_rgwchFileName));
|
|
break;
|
|
|
|
case OEMSIT_MSG:
|
|
m_FolderID = pInitStruct->folderID;
|
|
ReplaceInterface(m_pMsg, pInitStruct->pMsg);
|
|
break;
|
|
|
|
case OEMSIT_VIRGIN:
|
|
m_FolderID = pInitStruct->folderID;
|
|
break;
|
|
|
|
default:
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
/* ~~~ Took this out of mailnote.cpp HrInit(pcni) code. How do we get this to work???
|
|
~~~ It is suppose to notify us if a folder has been deleted. In that case, we would
|
|
~~~ need to convert the msgSite to a msg based msgsite.
|
|
if (m_pMsgTable)
|
|
m_pMsgTable->Advise(GetCallbackHwnd());
|
|
if (FAILED(hr = CreateNotify(&m_pFldrDelNotify)) ||
|
|
FAILED(hr = m_pFldrDelNotify->Initialize((TCHAR *)c_szFolderDelNotify)) ||
|
|
FAILED(hr = m_pFldrDelNotify->Register(GetCallbackHwnd(), g_hwndInit, FALSE)))
|
|
goto error;
|
|
*/
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetStatusFlags(DWORD *pdwFlags)
|
|
{
|
|
DWORD dwNewFlags = OEMSF_CAN_COPY | OEMSF_CAN_SAVE;
|
|
|
|
if (!!(m_dwMDNFlags & MDN_REQUEST))
|
|
{
|
|
dwNewFlags |= OEMSF_MDN_REQUEST;
|
|
}
|
|
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
case OEMSIT_STORE:
|
|
{
|
|
FOLDERTYPE folderType = GetFolderType(m_FolderID);
|
|
dwNewFlags |= OEMSF_CAN_MARK | OEMSF_FROM_STORE;
|
|
|
|
// GetMessageFlags is fairly intensive to be called as often as GetStatusFlags
|
|
// is called. Since this flag really only matters at load time, we will only go
|
|
// and get the value after a load from store. Otherwise, we will use the
|
|
// cached value from m_fSecUI.
|
|
if (m_fReloadMessageFlag)
|
|
{
|
|
m_dwArfFlags = 0;
|
|
|
|
GetMessageFlags(&m_dwArfFlags);
|
|
m_fReloadMessageFlag = FALSE;
|
|
}
|
|
|
|
if (0 == (m_dwArfFlags & ARF_READ))
|
|
dwNewFlags |= OEMSF_UNREAD;
|
|
|
|
// If we came from a store and we are a new folder, then can't delete
|
|
if (FOLDER_NEWS != folderType)
|
|
{
|
|
dwNewFlags |= OEMSF_CAN_MOVE;
|
|
if (0 == (m_dwArfFlags & ARF_ENDANGERED))
|
|
dwNewFlags |= OEMSF_CAN_DELETE;
|
|
|
|
if ((FOLDER_HTTPMAIL == folderType) || (FOLDER_IMAP == folderType))
|
|
dwNewFlags |= OEMSF_RULESNOTENABLED;
|
|
}
|
|
|
|
if (OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
dwNewFlags |= OEMSF_CAN_NEXT|OEMSF_CAN_PREV;
|
|
|
|
if (m_fThreadingEnabled)
|
|
dwNewFlags |= OEMSF_THREADING_ENABLED;
|
|
}
|
|
|
|
if (m_dwArfFlags & ARF_UNSENT)
|
|
{
|
|
// If we are table based, need to do extra checking for IMAP message in find folder
|
|
if (OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
if (OFIMAP_UNDEFINED == m_dwOrigFolderIsImap)
|
|
{
|
|
FOLDERINFO fi;
|
|
if (SUCCEEDED(g_pStore->GetFolderInfo(m_FolderID, &fi)))
|
|
{
|
|
// If is a find folder, check to see if message is IMAP
|
|
if (FOLDER_FINDRESULTS & (fi.dwFlags))
|
|
{
|
|
// Get original folder for this message (ie, not the find folder)
|
|
IMessageFolder *pMsgFolder = NULL;
|
|
if (SUCCEEDED(g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &pMsgFolder)))
|
|
{
|
|
// If original folder type is IMAP, then don't set unsent flag
|
|
FOLDERID folderID;
|
|
if (SUCCEEDED(pMsgFolder->GetMessageFolderId(m_MessageID, &folderID)))
|
|
{
|
|
FOLDERTYPE origFolderType = GetFolderType(folderID);
|
|
if (FOLDER_IMAP != origFolderType)
|
|
{
|
|
m_dwOrigFolderIsImap = OFIMAP_FALSE;
|
|
dwNewFlags |= OEMSF_UNSENT;
|
|
}
|
|
else
|
|
m_dwOrigFolderIsImap = OFIMAP_TRUE;
|
|
}
|
|
pMsgFolder->Release();
|
|
}
|
|
}
|
|
else
|
|
dwNewFlags |= OEMSF_UNSENT;
|
|
g_pStore->FreeRecord(&fi);
|
|
}
|
|
}
|
|
else
|
|
if (OFIMAP_FALSE == m_dwOrigFolderIsImap)
|
|
dwNewFlags |= OEMSF_UNSENT;
|
|
}
|
|
else
|
|
dwNewFlags |= OEMSF_UNSENT;
|
|
}
|
|
|
|
if (0 == (m_dwArfFlags & ARF_NOSECUI))
|
|
dwNewFlags |= OEMSF_SEC_UI_ENABLED;
|
|
|
|
if (m_dwArfFlags & ARF_NEWSMSG)
|
|
dwNewFlags |= OEMSF_BASEISNEWS;
|
|
|
|
break;
|
|
}
|
|
|
|
case OEMSIT_FAT:
|
|
{
|
|
LPWSTR pwszUnsent = NULL,
|
|
pwszExt = PathFindExtensionW(m_rgwchFileName);
|
|
|
|
dwNewFlags |= OEMSF_CAN_DELETE | OEMSF_CAN_MOVE | OEMSF_SEC_UI_ENABLED;
|
|
dwNewFlags |= OEMSF_FROM_FAT;
|
|
|
|
if (SUCCEEDED(MimeOleGetBodyPropW(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_XUNSENT), NOFLAGS, &pwszUnsent)))
|
|
{
|
|
if (FALSE == FIsEmptyW(pwszUnsent))
|
|
dwNewFlags |= OEMSF_UNSENT;
|
|
SafeMemFree(pwszUnsent);
|
|
}
|
|
|
|
if (0 == StrCmpW(pwszExt, c_wszNwsExt))
|
|
dwNewFlags |= OEMSF_BASEISNEWS;
|
|
break;
|
|
}
|
|
|
|
case OEMSIT_MSG:
|
|
dwNewFlags |= OEMSF_FROM_MSG;
|
|
break;
|
|
|
|
case OEMSIT_VIRGIN:
|
|
dwNewFlags |= OEMSF_VIRGIN | OEMSF_UNSENT;
|
|
break;
|
|
}
|
|
|
|
*pdwFlags = dwNewFlags;
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DeleteFromStore(DELETEMESSAGEFLAGS dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
|
|
AssertSz(!m_pCBMsgFolder, "Someone forgot to release this baby.");
|
|
|
|
Assert(m_pStoreCB);
|
|
|
|
hr = g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &m_pCBMsgFolder);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
MESSAGEIDLIST list;
|
|
FOLDERINFO fi;
|
|
|
|
list.cMsgs = 1;
|
|
list.prgidMsg = &m_MessageID;
|
|
|
|
hr = m_pCBMsgFolder->DeleteMessages(dwFlags, &list, NULL, m_pStoreCB);
|
|
if (E_PENDING != hr)
|
|
SafeRelease(m_pCBMsgFolder);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DeleteFromMsgTable(DELETEMESSAGEFLAGS dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
ROWINDEX iRow = -1,
|
|
iNewRow = -1;
|
|
|
|
AssertSz(m_pMsgTable, "How can you be OEMSIT_MSG_TABLE and not have a table");
|
|
|
|
m_fGotNewID = FALSE;
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
if (SUCCEEDED(m_pMsgTable->GetNextRow(iRow, GETNEXT_NEXT, ROWMSG_ALL, 0, &iNewRow)) &&
|
|
SUCCEEDED(m_pMsgTable->GetRowMessageId(iNewRow, &m_NewMessageID)))
|
|
m_fGotNewID = TRUE;
|
|
|
|
hr = m_pMsgTable->DeleteRows(dwFlags, 1, &iRow, FALSE, m_pStoreCB);
|
|
if (FAILED(hr) && (E_PENDING != hr))
|
|
AthMessageBoxW(GetCallbackHwnd(), MAKEINTRESOURCEW(idsAthenaMail), MAKEINTRESOURCEW(idsErrDeleteMsg), NULL, MB_OK);
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::Delete(DELETEMESSAGEFLAGS dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
|
|
m_dwMSAction = MSA_DELETE;
|
|
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
hr = DeleteFromMsgTable(dwFlags);
|
|
break;
|
|
|
|
case OEMSIT_STORE:
|
|
hr = DeleteFromStore(dwFlags);
|
|
m_fValidMessage = FALSE;
|
|
break;
|
|
|
|
case OEMSIT_FAT:
|
|
DeleteFileWrapW(m_rgwchFileName);
|
|
m_fValidMessage = FALSE;
|
|
m_dwMSAction = MSA_IDLE;
|
|
break;
|
|
|
|
// With these two, there is nothing to delete.
|
|
case OEMSIT_MSG:
|
|
case OEMSIT_VIRGIN:
|
|
hr = S_OK;
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, "Weren't prepared to handle this initType");
|
|
hr = E_UNEXPECTED;
|
|
break;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoNextPrev(BOOL fNext, DWORD dwFlags)
|
|
{
|
|
HRESULT hr;
|
|
if (OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
ROWMESSAGETYPE tyMsg;
|
|
ROWINDEX iRow = 0,
|
|
iNewRow = 0;
|
|
MESSAGEID idNewMark;
|
|
GETNEXTFLAGS dwNextFlags = 0;
|
|
GETNEXTTYPE tyDir = fNext?GETNEXT_NEXT:GETNEXT_PREVIOUS;
|
|
|
|
AssertSz(m_pMsgTable, "How can you be OEMSIT_MSG_TABLE and not have a table");
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
if (dwFlags&OENF_SKIPMAIL)
|
|
tyMsg = ROWMSG_MAIL;
|
|
else if (dwFlags&OENF_SKIPNEWS)
|
|
tyMsg = ROWMSG_NEWS;
|
|
else
|
|
tyMsg = ROWMSG_ALL;
|
|
|
|
if (dwFlags&OENF_UNREAD)
|
|
dwNextFlags |= GETNEXT_UNREAD;
|
|
|
|
if (dwFlags&OENF_THREAD)
|
|
dwNextFlags |= GETNEXT_THREAD;
|
|
|
|
hr = m_pMsgTable->GetNextRow(iRow, tyDir, tyMsg, dwNextFlags, &iNewRow);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = m_pMsgTable->GetRowMessageId(iNewRow, &idNewMark);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
if (m_pListSelect)
|
|
m_pListSelect->SetActiveRow(iNewRow);
|
|
|
|
m_MessageID = idNewMark;
|
|
m_fNeedToLoadMsg = TRUE;
|
|
}
|
|
else
|
|
hr = E_UNEXPECTED;
|
|
|
|
Exit:
|
|
AssertSz(E_PENDING != hr, "COEMsgSite::DoNextPrev not setup to handle E_PENDING.");
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoCopyMoveFromMsgToFldr(IMimeMessage *pMsg, BOOL fUnSent)
|
|
{
|
|
HRESULT hr = E_UNEXPECTED;
|
|
if (m_fCBCopy)
|
|
{
|
|
hr = m_pCBMsgFolder->SaveMessage(NULL, SAVE_MESSAGE_GENID, fUnSent?ARF_UNSENT:NOFLAGS, 0, pMsg, m_pStoreCB);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_dwCMFState = CMF_MSG_TO_FOLDER;
|
|
OnComplete(SOT_COPYMOVE_MESSAGE, S_OK);
|
|
}
|
|
}
|
|
else
|
|
AssertSz(FALSE, "Can't move a message based on a message. Only copy.");
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoCopyMoveFromStoreToFldr(BOOL fUnSent)
|
|
{
|
|
HRESULT hr;
|
|
MESSAGEID msgID = 0;
|
|
|
|
hr = SaveMessageInFolder(m_pStoreCB, m_pCBMsgFolder, m_pMsg, fUnSent?ARF_UNSENT:NOFLAGS, &msgID, TRUE);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_dwCMFState = CMF_STORE_TO_FOLDER;
|
|
OnComplete(SOT_COPYMOVE_MESSAGE, S_OK);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoCopyMoveFromTableToFldr(void)
|
|
{
|
|
HRESULT hr;
|
|
IMessageFolder *pSrcFolder = NULL;
|
|
MESSAGEIDLIST rMsgIDList;
|
|
LPMESSAGEINFO pMsgInfo;
|
|
ROWINDEX iRow, iNewRow;
|
|
MESSAGEID msgID;
|
|
FOLDERID folderID = 0;
|
|
|
|
Assert(m_pStoreCB);
|
|
|
|
m_fGotNewID = FALSE;
|
|
|
|
if (m_pFolderReleaseOnComplete != NULL)
|
|
return E_FAIL;
|
|
|
|
hr = g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &pSrcFolder);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// If we are moving, then we need to get the next item in the list
|
|
if (!m_fCBCopy && SUCCEEDED(m_pMsgTable->GetNextRow(iRow, GETNEXT_NEXT, ROWMSG_ALL, 0, &iNewRow)) &&
|
|
SUCCEEDED(m_pMsgTable->GetRowMessageId(iNewRow, &m_NewMessageID)))
|
|
m_fGotNewID = TRUE;
|
|
|
|
hr = m_pMsgTable->GetRow(iRow, &pMsgInfo);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
msgID = pMsgInfo->idMessage;
|
|
m_pMsgTable->ReleaseRow(pMsgInfo);
|
|
|
|
rMsgIDList.cAllocated = 0;
|
|
rMsgIDList.cMsgs = 1;
|
|
rMsgIDList.prgidMsg = &msgID;
|
|
|
|
if (SUCCEEDED(m_pCBMsgFolder->GetFolderId(&folderID)))
|
|
{
|
|
m_CBFolderID = folderID;
|
|
m_CBMessageID = msgID;
|
|
}
|
|
else
|
|
{
|
|
m_CBFolderID = FOLDERID_INVALID;
|
|
m_dwInitType = OEMSIT_MSG;
|
|
}
|
|
|
|
hr = pSrcFolder->CopyMessages(m_pCBMsgFolder, m_fCBCopy?0:COPY_MESSAGE_MOVE, &rMsgIDList, NULL, NULL, m_pStoreCB);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_dwCMFState = CMF_TABLE_TO_FOLDER;
|
|
OnComplete(SOT_COPYMOVE_MESSAGE, S_OK);
|
|
}
|
|
|
|
if (hr == E_PENDING)
|
|
{
|
|
ReplaceInterface(m_pFolderReleaseOnComplete, pSrcFolder);
|
|
SafeRelease(pSrcFolder);
|
|
}
|
|
|
|
Exit:
|
|
ReleaseObj(pSrcFolder);
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoCopyMoveFromFATToFldr(BOOL fUnSent)
|
|
{
|
|
IMimeMessage *pMsg = NULL;
|
|
HRESULT hr = S_OK;
|
|
|
|
// Need original message, because m_pMsg is without security...
|
|
hr = HrCreateMessage(&pMsg);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
hr = HrLoadMsgFromFileW(pMsg, m_rgwchFileName);
|
|
|
|
hr = SaveMessageInFolder(m_pStoreCB, m_pCBMsgFolder, pMsg, fUnSent?ARF_UNSENT:NOFLAGS, &m_CBMessageID, TRUE);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_fHaveCBMessageID = TRUE;
|
|
m_dwCMFState = CMF_FAT_TO_FOLDER;
|
|
OnComplete(SOT_COPYMOVE_MESSAGE, S_OK);
|
|
}
|
|
|
|
SafeRelease(pMsg);
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::DoCopyMoveToFolder(BOOL fCopy, IMimeMessage *pMsg, BOOL fUnSent)
|
|
{
|
|
HRESULT hr;
|
|
FOLDERID newFolderID;
|
|
|
|
Assert(m_pStoreCB);
|
|
|
|
AssertSz(NULL == m_pCBMsgFolder, "Someone forgot to release the folder");
|
|
|
|
m_fCBCopy = fCopy;
|
|
m_dwMSAction = MSA_COPYMOVE;
|
|
|
|
hr = SelectFolderDialog(GetCallbackHwnd(), SFD_SELECTFOLDER, m_FolderID,
|
|
FD_DISABLESERVERS | TREEVIEW_NONEWS |
|
|
(m_fCBCopy?FD_COPYFLAGS:FD_MOVEFLAGS),
|
|
MAKEINTRESOURCE(m_fCBCopy?idsCopy:idsMove),
|
|
MAKEINTRESOURCE(m_fCBCopy?idsCopyCaption:idsMoveCaption),
|
|
&newFolderID);
|
|
|
|
// Only want to do the copy if:
|
|
// 1- The new folder is not invalid
|
|
// 2- Can open the needed folder
|
|
if (SUCCEEDED(hr) && (newFolderID != FOLDERID_INVALID) &&
|
|
SUCCEEDED(hr = g_pStore->OpenFolder(newFolderID, NULL, NOFLAGS, &m_pCBMsgFolder)))
|
|
{
|
|
if (pMsg)
|
|
hr = DoCopyMoveFromMsgToFldr(pMsg, fUnSent);
|
|
else
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
hr = DoCopyMoveFromTableToFldr();
|
|
break;
|
|
|
|
case OEMSIT_STORE:
|
|
hr = DoCopyMoveFromStoreToFldr(fUnSent);
|
|
break;
|
|
|
|
case OEMSIT_FAT:
|
|
hr = DoCopyMoveFromFATToFldr(fUnSent);
|
|
break;
|
|
|
|
case OEMSIT_VIRGIN:
|
|
case OEMSIT_MSG:
|
|
hr = DoCopyMoveFromMsgToFldr(m_pMsg, fUnSent);
|
|
break;
|
|
}
|
|
if (E_PENDING != hr)
|
|
SafeRelease(m_pCBMsgFolder);
|
|
}
|
|
|
|
if (FAILED(hr) && (E_PENDING != hr) && (hrUserCancel != hr))
|
|
AthErrorMessageW(GetCallbackHwnd(), MAKEINTRESOURCEW(idsAthenaNews), MAKEINTRESOURCEW(idsCantSaveMsg), hr);
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::Save(IMimeMessage *pMsg, DWORD dwFlags, IImnAccount *pAcct)
|
|
{
|
|
HRESULT hr;
|
|
WORD wMessageFlags = 0;
|
|
ACCTTYPE acctType = ACCT_MAIL;
|
|
|
|
AssertSz(!m_pCBMsgFolder, "Someone forgot to release this baby.");
|
|
|
|
m_fCBSaveInFolderAndDelOrig = !!(dwFlags & OESF_SAVE_IN_ORIG_FOLDER);
|
|
m_fCBSavedInDrafts = FALSE;
|
|
|
|
m_dwMSAction = MSA_SAVE;
|
|
|
|
pAcct->GetAccountType(&acctType);
|
|
if (ACCT_NEWS == acctType)
|
|
wMessageFlags |= ARF_NEWSMSG;
|
|
|
|
if (dwFlags & OESF_UNSENT)
|
|
wMessageFlags |= ARF_UNSENT;
|
|
if (dwFlags & OESF_READ)
|
|
wMessageFlags |= ARF_READ;
|
|
|
|
// Decide if want to save to drafts or some other folder
|
|
if ((OEMSIT_MSG_TABLE == m_dwInitType) && m_fCBSaveInFolderAndDelOrig)
|
|
{
|
|
m_CBFolderID = m_FolderID;
|
|
hr = g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &m_pCBMsgFolder);
|
|
}
|
|
else
|
|
{
|
|
FOLDERID idStore;
|
|
|
|
m_fCBSavedInDrafts = TRUE;
|
|
|
|
// Find store ID of account in the header
|
|
// If have problems getting the special folder on the server, then use
|
|
// the local store drafts.
|
|
if (dwFlags & OESF_FORCE_LOCAL_DRAFT)
|
|
idStore = FOLDERID_LOCAL_STORE;
|
|
else
|
|
{
|
|
IImnAccount *pSaveAcct = NULL;
|
|
|
|
if (ACCT_NEWS == acctType)
|
|
GetDefaultAccount(ACCT_MAIL, &pSaveAcct);
|
|
else
|
|
ReplaceInterface(pSaveAcct, pAcct);
|
|
|
|
if (pSaveAcct)
|
|
{
|
|
DWORD dw = 0;
|
|
CHAR szAcctId[CCHMAX_ACCOUNT_NAME];
|
|
|
|
hr = pSaveAcct->GetPropSz(AP_ACCOUNT_ID, szAcctId, ARRAYSIZE(szAcctId));
|
|
if (SUCCEEDED(hr))
|
|
hr = g_pStore->FindServerId(szAcctId, &idStore);
|
|
|
|
pSaveAcct->Release();
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
|
|
if (FAILED(hr))
|
|
idStore = FOLDERID_LOCAL_STORE;
|
|
}
|
|
|
|
hr = g_pStore->OpenSpecialFolder(idStore, NULL, FOLDER_DRAFT, &m_pCBMsgFolder);
|
|
|
|
// If failed opening special folder and we weren't trying local folders, try
|
|
// using local folders now.
|
|
if (FAILED(hr) && (idStore != FOLDERID_LOCAL_STORE))
|
|
hr = g_pStore->OpenSpecialFolder(FOLDERID_LOCAL_STORE, NULL, FOLDER_DRAFT, &m_pCBMsgFolder);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_CBFolderID = FOLDERID_INVALID;
|
|
m_pCBMsgFolder->GetFolderId(&m_CBFolderID);
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
m_CBMessageID = m_MessageID;
|
|
|
|
// Save message to the folder
|
|
hr = SaveMessageInFolder(m_pStoreCB, m_pCBMsgFolder, pMsg, wMessageFlags, &m_CBMessageID, TRUE);
|
|
if (SUCCEEDED(hr))
|
|
m_fHaveCBMessageID = TRUE;
|
|
else if (E_PENDING == hr)
|
|
{
|
|
ReplaceInterface(m_pMsg, pMsg);
|
|
m_fHaveCBMessageID = FALSE;
|
|
}
|
|
|
|
Exit:
|
|
if (E_PENDING != hr)
|
|
SafeRelease(m_pCBMsgFolder);
|
|
if (FAILED(hr) && (hrUserCancel != hr) && (E_PENDING != hr))
|
|
{
|
|
int idsErr = ((MIME_E_URL_NOTFOUND == hr) ? idsErrSaveDownloadFail : idsCantSaveMsg);
|
|
|
|
AthMessageBoxW(GetCallbackHwnd(), MAKEINTRESOURCEW(idsAthena), MAKEINTRESOURCEW(idsCantSaveMsg), NULL, MB_OK);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
// Use to split this function into one for news and one for mail. Don't think that
|
|
// we need to do that anymore. If there is any difference, that should probably
|
|
// be moved into the message mangling phase. I can't see anything else that would
|
|
// be different.
|
|
#ifdef SMIME_V3
|
|
HRESULT COEMsgSite::SendMsg(IMimeMessage *pMsg, BOOL fSendImmediately, BOOL fMail, IHeaderSite *pHeaderSite)
|
|
#else
|
|
HRESULT COEMsgSite::SendMsg(IMimeMessage *pMsg, BOOL fSendImmediately, BOOL fMail)
|
|
#endif // SMIME_V3
|
|
{
|
|
HRESULT hr;
|
|
|
|
// Figure out whether we need to request for MDNs. Doing it here skips processing it in smapi.
|
|
if (fMail &&
|
|
(!!(m_dwMDNFlags & MDN_REQUEST)) &&
|
|
(!IsMDN(pMsg)))
|
|
{
|
|
LPWSTR pwsz = NULL;
|
|
|
|
if (SUCCEEDED(MimeOleGetBodyPropW(pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_FROM), NOFLAGS, &pwsz)))
|
|
{
|
|
MimeOleSetBodyPropW(pMsg, HBODY_ROOT, STR_HDR_DISP_NOTIFICATION_TO, NOFLAGS, pwsz);
|
|
|
|
MemFree(pwsz);
|
|
}
|
|
}
|
|
|
|
// Account should already be setup in the message by this time.
|
|
if (IsSecure(pMsg))
|
|
#ifdef SMIME_V3
|
|
hr = SendSecureMailToOutBox(m_pStoreCB, pMsg, fSendImmediately, FALSE, fMail, pHeaderSite);
|
|
#else
|
|
hr = SendSecureMailToOutBox(m_pStoreCB, pMsg, fSendImmediately, FALSE, fMail);
|
|
#endif // SMIME_V3
|
|
else
|
|
hr = SendMailToOutBox(m_pStoreCB, pMsg, fSendImmediately, FALSE, fMail);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
BOOL COEMsgSite::NeedToSendNews(IMimePropertySet *pPropSet)
|
|
{
|
|
MIMEPROPINFO mimePropInfo;
|
|
|
|
AssertSz(pPropSet, "A property set needs to be passed in.");
|
|
|
|
if (SUCCEEDED(pPropSet->GetPropInfo(PIDTOSTR(PID_HDR_NEWSGROUPS), &mimePropInfo)))
|
|
return TRUE;
|
|
|
|
if (SUCCEEDED(pPropSet->GetPropInfo(PIDTOSTR(PID_HDR_FOLLOWUPTO), &mimePropInfo)))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// ****************************************
|
|
BOOL COEMsgSite::NeedToSendMail(IMimePropertySet *pPropSet)
|
|
{
|
|
MIMEPROPINFO mimePropInfo;
|
|
|
|
AssertSz(pPropSet, "A property set needs to be passed in.");
|
|
|
|
if (SUCCEEDED(pPropSet->GetPropInfo(PIDTOSTR(PID_HDR_TO), &mimePropInfo)))
|
|
return TRUE;
|
|
|
|
if (SUCCEEDED(pPropSet->GetPropInfo(PIDTOSTR(PID_HDR_CC), &mimePropInfo)))
|
|
return TRUE;
|
|
|
|
if (SUCCEEDED(pPropSet->GetPropInfo(PIDTOSTR(PID_HDR_BCC), &mimePropInfo)))
|
|
return TRUE;
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::ClearHeaders(ULONG cNames, LPCSTR *prgszName, IMimePropertySet *pPropSet)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
for (ULONG i = 0; i < cNames; i++)
|
|
pPropSet->DeleteProp(*prgszName++);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
#ifdef SMIME_V3
|
|
HRESULT COEMsgSite::SendToOutbox(IMimeMessage *pMsg, BOOL fSendImmediate, IHeaderSite *pHeaderSite)
|
|
#else
|
|
HRESULT COEMsgSite::SendToOutbox(IMimeMessage *pMsg, BOOL fSendImmediate)
|
|
#endif // SMIME_V3
|
|
{
|
|
HRESULT hr;
|
|
BOOL fSendMail,
|
|
fSendNews,
|
|
fSendBoth;
|
|
IMimePropertySet *pPropSet = NULL,
|
|
*pTempPropSet = NULL;
|
|
PROPVARIANT var;
|
|
IImnAccount *pAccount = NULL;
|
|
ACCTTYPE acctType;
|
|
IMimeMessage *pTempMsg = NULL;
|
|
|
|
LPCSTR rgszMailOnlyHeaders[] =
|
|
{
|
|
PIDTOSTR(PID_HDR_TO),
|
|
PIDTOSTR(PID_HDR_CC),
|
|
PIDTOSTR(PID_HDR_BCC),
|
|
PIDTOSTR(PID_HDR_XPRI),
|
|
PIDTOSTR(PID_HDR_XMSPRI),
|
|
PIDTOSTR(PID_HDR_APPARTO),
|
|
PIDTOSTR(PID_HDR_COMMENT),
|
|
PIDTOSTR(PID_HDR_SENDER),
|
|
PIDTOSTR(PID_HDR_XMAILER),
|
|
PIDTOSTR(PID_HDR_RECEIVED),
|
|
PIDTOSTR(PID_HDR_DISP_NOTIFICATION_TO)
|
|
};
|
|
LPCSTR rgszNewsOnlyHeaders[] =
|
|
{
|
|
PIDTOSTR(PID_HDR_NEWSGROUPS),
|
|
PIDTOSTR(PID_HDR_PATH),
|
|
PIDTOSTR(PID_HDR_FOLLOWUPTO),
|
|
PIDTOSTR(PID_HDR_EXPIRES),
|
|
PIDTOSTR(PID_HDR_REFS),
|
|
PIDTOSTR(PID_HDR_DISTRIB),
|
|
PIDTOSTR(PID_HDR_ORG),
|
|
PIDTOSTR(PID_HDR_KEYWORDS),
|
|
PIDTOSTR(PID_HDR_SUMMARY),
|
|
PIDTOSTR(PID_HDR_APPROVED),
|
|
PIDTOSTR(PID_HDR_LINES),
|
|
PIDTOSTR(PID_HDR_XREF),
|
|
PIDTOSTR(PID_HDR_CONTROL)
|
|
};
|
|
|
|
// Common headers between mail and news that can be left where they are
|
|
// PID_HDR_FROM PID_HDR_DATE PID_HDR_SUBJECT PID_HDR_MESSAGEID
|
|
// PID_HDR_REPLYTO PID_HDR_CNTTYPE PID_HDR_CNTXFER PID_HDR_CNTDESC
|
|
// PID_HDR_CNTDISP PID_HDR_CNTBASE PID_HDR_CNTLOC PID_HDR_CNTID
|
|
// PID_HDR_MIMEVER PID_HDR_ENCODING PID_HDR_ENCRYPTED
|
|
|
|
m_dwMSAction = MSA_SEND;
|
|
|
|
hr = pMsg->BindToObject(HBODY_ROOT, IID_IMimePropertySet, (LPVOID *)&pPropSet);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
fSendMail = NeedToSendMail(pPropSet);
|
|
fSendNews = NeedToSendNews(pPropSet);
|
|
fSendBoth = fSendMail && fSendNews;
|
|
|
|
PropVariantInit(&var);
|
|
|
|
if((!fSendMail) && (!fSendNews))
|
|
{
|
|
hr = hrNoRecipients;
|
|
goto Exit;
|
|
}
|
|
|
|
var.vt = VT_LPSTR;
|
|
hr = pMsg->GetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, var.pszVal, &pAccount);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = pAccount->GetAccountType(&acctType);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
if (fSendBoth)
|
|
{
|
|
hr = HrDupeMsg(pMsg, &pTempMsg);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = pTempMsg->BindToObject(HBODY_ROOT, IID_IMimePropertySet, (LPVOID *)&pTempPropSet);
|
|
if(FAILED(hr))
|
|
return hr;
|
|
|
|
hr = ClearHeaders(ARRAYSIZE(rgszMailOnlyHeaders), rgszMailOnlyHeaders, pPropSet);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = ClearHeaders(ARRAYSIZE(rgszNewsOnlyHeaders), rgszNewsOnlyHeaders, pTempPropSet);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
|
|
// If going to do both news and mail, then must send news first. The spooler will
|
|
// block and say it is busy if we send mail first. If we send mail second, then
|
|
// the spooler has a special flag that says when you are done being busy, send
|
|
// any mail that you have in your outbox.
|
|
if (fSendNews)
|
|
{
|
|
if (ACCT_MAIL == acctType)
|
|
{
|
|
IImnAccount *pTempAccount = NULL;
|
|
if (SUCCEEDED(GetDefaultAccount(ACCT_NEWS, &pTempAccount)))
|
|
{
|
|
HrSetAccountByAccount(pMsg, pTempAccount);
|
|
pTempAccount->Release();
|
|
}
|
|
}
|
|
|
|
#ifdef SMIME_V3
|
|
hr = SendMsg(pMsg, fSendImmediate, FALSE, pHeaderSite);
|
|
#else
|
|
hr = SendMsg(pMsg, fSendImmediate, FALSE);
|
|
#endif // SMIME_V3
|
|
if (FAILED(hr) && (E_PENDING != hr))
|
|
goto Exit;
|
|
|
|
// Tell the user this is being sent to the server but might not appear
|
|
// right away.
|
|
if (fSendImmediate && !g_pConMan->IsGlobalOffline())
|
|
DoDontShowMeAgainDlg(GetCallbackHwnd(), c_szDSSendNews,
|
|
MAKEINTRESOURCE(idsPostNews),
|
|
MAKEINTRESOURCE(idsPostSentToServer),
|
|
MB_OK);
|
|
if (fSendBoth)
|
|
pMsg = pTempMsg;
|
|
}
|
|
|
|
if (fSendMail)
|
|
{
|
|
if (ACCT_NEWS == acctType)
|
|
{
|
|
//If we are not the smapi client forward it to whoever it is.
|
|
if (!FIsDefaultMailConfiged())
|
|
{
|
|
hr = NewsUtil_ReFwdByMapi(GetCallbackHwnd(), pMsg, MSGTYPE_CC);
|
|
goto Exit;
|
|
}
|
|
|
|
IImnAccount *pTempAccount = NULL;
|
|
if (SUCCEEDED(GetDefaultAccount(ACCT_MAIL, &pTempAccount)))
|
|
{
|
|
HrSetAccountByAccount(pMsg, pTempAccount);
|
|
pTempAccount->Release();
|
|
}
|
|
}
|
|
|
|
#ifdef SMIME_V3
|
|
hr = SendMsg(pMsg, fSendImmediate, TRUE, pHeaderSite);
|
|
#else
|
|
hr = SendMsg(pMsg, fSendImmediate, TRUE);
|
|
#endif // SMIME_V3
|
|
}
|
|
|
|
|
|
Exit:
|
|
SafeMemFree(var.pszVal);
|
|
ReleaseObj(pAccount);
|
|
ReleaseObj(pPropSet);
|
|
ReleaseObj(pTempPropSet);
|
|
ReleaseObj(pTempMsg);
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetLocation(LPWSTR rgwchLocation, DWORD cchSize)
|
|
{
|
|
FOLDERINFO fi;
|
|
LPWSTR pwszName = NULL;
|
|
HRESULT hr = S_OK;
|
|
BOOL fFreeFolder = FALSE;
|
|
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
case OEMSIT_STORE:
|
|
if (SUCCEEDED(g_pStore->GetFolderInfo(m_FolderID, &fi)))
|
|
{
|
|
Assert(fi.pszName);
|
|
fFreeFolder = TRUE;
|
|
|
|
IF_NULLEXIT(pwszName = PszToUnicode(CP_ACP, fi.pszName));
|
|
|
|
StrCpyNW(rgwchLocation, pwszName, cchSize);
|
|
}
|
|
else
|
|
*rgwchLocation = 0;
|
|
break;
|
|
|
|
case OEMSIT_FAT:
|
|
StrCpyNW(rgwchLocation, m_rgwchFileName, cchSize);
|
|
break;
|
|
|
|
case OEMSIT_MSG:
|
|
case OEMSIT_VIRGIN:
|
|
*rgwchLocation = 0;
|
|
break;
|
|
}
|
|
|
|
exit:
|
|
if (fFreeFolder)
|
|
g_pStore->FreeRecord(&fi);
|
|
|
|
MemFree(pwszName);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::MarkMessage(MARK_TYPE dwType, APPLYCHILDRENTYPE dwApplyType)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
if (OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (SUCCEEDED(hr))
|
|
hr = m_pMsgTable->Mark(&iRow, 1, dwApplyType, dwType, m_pStoreCB);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetMessageFlags(MESSAGEFLAGS *pdwFlags)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
*pdwFlags = 0;
|
|
|
|
if (!m_pMsgTable)
|
|
{
|
|
hr = E_FAIL;
|
|
goto Exit;
|
|
}
|
|
|
|
if (OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
LPMESSAGEINFO pMsgInfo;
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
hr = m_pMsgTable->GetRow(iRow, &pMsgInfo);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
*pdwFlags = pMsgInfo->dwFlags;
|
|
m_pMsgTable->ReleaseRow(pMsgInfo);
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetDefaultAccount(ACCTTYPE acctType, IImnAccount **ppAcct)
|
|
{
|
|
HRESULT hr = E_FAIL,
|
|
hr2;
|
|
LPMESSAGEINFO pMsgInfo = NULL;
|
|
ROWINDEX iRow;
|
|
DWORD dwFlags = 0;
|
|
|
|
Assert(ppAcct);
|
|
|
|
if(OEMSIT_MSG_TABLE == m_dwInitType)
|
|
{
|
|
if (ACCT_MAIL == acctType)
|
|
{
|
|
IF_FAILEXIT(GetMessageFlags(&dwFlags));
|
|
if (!!(dwFlags & ARF_NEWSMSG))
|
|
goto exit;
|
|
}
|
|
IF_FAILEXIT(hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow));
|
|
IF_FAILEXIT(hr = m_pMsgTable->GetRow(iRow, &pMsgInfo));
|
|
IF_FAILEXIT(hr = g_pAcctMan->FindAccount(AP_ACCOUNT_ID, pMsgInfo->pszAcctId, ppAcct));
|
|
}
|
|
|
|
exit:
|
|
if(FAILED(hr))
|
|
hr = g_pAcctMan->GetDefaultAccount(acctType, ppAcct);
|
|
|
|
if(pMsgInfo)
|
|
{
|
|
// We don't want to mask hr, so we'll just test an alternative HRESULT
|
|
hr2 = m_pMsgTable->ReleaseRow(pMsgInfo);
|
|
|
|
if(FAILED(hr2))
|
|
TraceResult(hr2);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::LoadMessageFromStore(void)
|
|
{
|
|
HRESULT hr;
|
|
IMessageFolder *pMsgFolder = NULL;
|
|
|
|
hr = g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &pMsgFolder);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IMimeMessage *pMsg = NULL;
|
|
//Can only get into this state in a drafts message, so don't need worry about security
|
|
hr = pMsgFolder->OpenMessage(m_MessageID, 0/* OPEN_MESSAGE_SECURE*/, &pMsg, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ReplaceInterface(m_pMsg, pMsg);
|
|
pMsg->Release();
|
|
}
|
|
pMsgFolder->Release();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::LoadMessageFromRow(IMimeMessage **ppMsg, ROWINDEX row)
|
|
{
|
|
HRESULT hr;
|
|
LPMESSAGEINFO pInfo;
|
|
|
|
AssertSz(!(*ppMsg), "We create a message in this function.");
|
|
|
|
hr = m_pMsgTable->GetRow(row, &pInfo);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_dwMSAction = MSA_GET_MESSAGE;
|
|
|
|
hr = CreateMessageFromInfo(pInfo, ppMsg, m_FolderID);
|
|
m_fHeaderOnly = TRUE;
|
|
|
|
// now we wait until the message has downloaded and reload in
|
|
// OnComplete
|
|
m_pMsgTable->ReleaseRow(pInfo);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::LoadMessageFromTable(BOOL fGetOriginal, HRESULT *phr)
|
|
{
|
|
IMimeMessage *pMsg = NULL;
|
|
BOOL fOffline=FALSE;
|
|
ROWINDEX rowIndex = 0;
|
|
HRESULT hr,
|
|
tempHr = S_OK;
|
|
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &rowIndex);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
m_fHeaderOnly = FALSE;
|
|
hr = m_pMsgTable->OpenMessage(rowIndex, (fGetOriginal ? OPEN_MESSAGE_SECURE : 0), &pMsg, m_pStoreCB);
|
|
if (FAILED(hr) || hr == STORE_S_ALREADYPENDING)
|
|
{
|
|
tempHr = hr;
|
|
hr = LoadMessageFromRow(&pMsg, rowIndex);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
switch (tempHr)
|
|
{
|
|
case E_NOT_ONLINE:
|
|
hr = HR_S_OFFLINE;
|
|
break;
|
|
|
|
case STORE_S_ALREADYPENDING:
|
|
case E_PENDING:
|
|
{
|
|
LPMESSAGEINFO pmiMsgInfo;
|
|
|
|
// Save the MsgID of msg we're trying to load. This way if user quickly loads
|
|
// several msgs into note, we won't re-enter MSA_IDLE until the desired msg loads
|
|
if (SUCCEEDED(m_pMsgTable->GetRow(rowIndex, &pmiMsgInfo)))
|
|
{
|
|
m_MessageID = pmiMsgInfo->idMessage;
|
|
m_pMsgTable->ReleaseRow(pmiMsgInfo);
|
|
}
|
|
else
|
|
m_MessageID = 0; // This means show the next msg we get!
|
|
|
|
tempHr = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
}
|
|
else
|
|
{
|
|
m_dwArfFlags = 0;
|
|
GetMessageFlags(&m_dwArfFlags);
|
|
}
|
|
|
|
*phr = tempHr;
|
|
ReplaceInterface(m_pMsg, pMsg);
|
|
|
|
Exit:
|
|
ReleaseObj(pMsg);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::LoadMessageFromFAT(BOOL fGetOriginal, HRESULT *phr)
|
|
{
|
|
IMimeMessage *pMsg = NULL;
|
|
HRESULT hr;
|
|
|
|
hr = HrCreateMessage(&pMsg);
|
|
if (FAILED(hr))
|
|
return hr;
|
|
|
|
//bobn: We need to make sure we know the default charset
|
|
HGetDefaultCharset(NULL);
|
|
|
|
hr = HrLoadMsgFromFileW(pMsg, m_rgwchFileName);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if(!fGetOriginal)
|
|
*phr = HandleSecurity(NULL, pMsg);
|
|
|
|
//if (SUCCEEDED(hr))
|
|
ReplaceInterface(m_pMsg, pMsg);
|
|
}
|
|
|
|
SafeRelease(pMsg);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetFolderID(FOLDERID *folderID)
|
|
{
|
|
Assert(folderID);
|
|
*folderID = m_FolderID;
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::SetAccountInfo(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
FOLDERINFO fi;
|
|
PROPVARIANT var;
|
|
|
|
// Check to see if need an account in the message.
|
|
var.vt = VT_LPSTR;
|
|
if (FAILED(m_pMsg->GetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var)) || !(var.pszVal))
|
|
{
|
|
if (FOLDERID_INVALID != m_FolderID)
|
|
{
|
|
hr = g_pStore->GetFolderInfo(m_FolderID, &fi);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Set account based upon the folder ID passed down
|
|
if (FOLDER_LOCAL != fi.tyFolder)
|
|
{
|
|
char szAcctId[CCHMAX_ACCOUNT_NAME];
|
|
IImnAccount *pAcct = NULL;
|
|
|
|
if (SUCCEEDED(GetFolderAccountId(&fi, szAcctId, ARRAYSIZE(szAcctId))) && SUCCEEDED(g_pAcctMan->FindAccount(AP_ACCOUNT_ID, szAcctId, &pAcct)))
|
|
{
|
|
HrSetAccountByAccount(m_pMsg, pAcct);
|
|
pAcct->Release();
|
|
}
|
|
|
|
// If not a server node, set the newgroup
|
|
if ((FOLDER_NEWS == fi.tyFolder) && (0 == (FOLDER_SERVER & fi.dwFlags)))
|
|
hr = MimeOleSetBodyPropA(m_pMsg, HBODY_ROOT, PIDTOSTR(PID_HDR_NEWSGROUPS), NOFLAGS, fi.pszName);
|
|
}
|
|
g_pStore->FreeRecord(&fi);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
SafeMemFree(var.pszVal);
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::CreateMsgWithAccountInfo(void)
|
|
{
|
|
HRESULT hr;
|
|
|
|
SafeRelease(m_pMsg);
|
|
hr = HrCreateMessage(&m_pMsg);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if(g_hDefaultCharsetForMail)
|
|
m_pMsg->SetCharset(g_hDefaultCharsetForMail, CSET_APPLY_ALL);
|
|
hr = SetAccountInfo();
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::GetMessage(IMimeMessage **ppMsg, BOOL *pfCompleteMsg, DWORD dwMessageFlags, HRESULT *phr)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fGetOriginal = (OEGM_ORIGINAL & dwMessageFlags);
|
|
|
|
if (!m_fValidMessage)
|
|
return E_FAIL;
|
|
|
|
*phr = S_OK;
|
|
if (m_fNeedToLoadMsg || fGetOriginal)
|
|
{
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
hr = LoadMessageFromTable(fGetOriginal, phr);
|
|
break;
|
|
|
|
case OEMSIT_STORE:
|
|
hr = LoadMessageFromStore();
|
|
break;
|
|
|
|
case OEMSIT_FAT:
|
|
hr = LoadMessageFromFAT(fGetOriginal, phr);
|
|
break;
|
|
|
|
case OEMSIT_MSG:
|
|
hr = SetAccountInfo();
|
|
break;
|
|
|
|
case OEMSIT_VIRGIN:
|
|
hr = CreateMsgWithAccountInfo();
|
|
break;
|
|
}
|
|
m_fNeedToLoadMsg = FALSE;
|
|
}
|
|
|
|
if (SUCCEEDED(hr) && !m_fHeaderOnly && (OEGM_AS_ATTACH &dwMessageFlags))
|
|
{
|
|
IMimeMessage *pMsgFwd = NULL;
|
|
PROPVARIANT var;
|
|
|
|
hr = HrCreateMessage(&pMsgFwd);
|
|
|
|
if (SUCCEEDED(hr))
|
|
hr = pMsgFwd->AttachObject(IID_IMimeMessage, (LPVOID)m_pMsg, NULL);
|
|
|
|
var.vt = VT_LPSTR;
|
|
if (SUCCEEDED(m_pMsg->GetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var)))
|
|
{
|
|
pMsgFwd->SetProp(PIDTOSTR(PID_ATT_ACCOUNTID), NOFLAGS, &var);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ReplaceInterface(m_pMsg, pMsgFwd);
|
|
pMsgFwd->Release();
|
|
m_dwInitType = OEMSIT_MSG;
|
|
}
|
|
}
|
|
|
|
if (fGetOriginal)
|
|
m_fReloadMessageFlag = TRUE;
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
ReplaceInterface((*ppMsg), m_pMsg);
|
|
*pfCompleteMsg = !m_fHeaderOnly;
|
|
|
|
m_fNeedToLoadMsg = !!m_fHeaderOnly;
|
|
|
|
if (!m_pMsg)
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
// *************************
|
|
BOOL COEMsgSite::FCanConnect()
|
|
{
|
|
IImnAccount *pAcct = NULL;
|
|
HRESULT hr;
|
|
BOOL fRet = TRUE;
|
|
|
|
hr = GetDefaultAccount(ACCT_MAIL, &pAcct);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = g_pConMan->CanConnect(pAcct);
|
|
pAcct->Release();
|
|
}
|
|
|
|
fRet = (S_OK == hr);
|
|
|
|
return(fRet);
|
|
}
|
|
|
|
// ****************************************
|
|
HWND COEMsgSite::GetCallbackHwnd()
|
|
{
|
|
HWND hwnd;
|
|
|
|
Assert(m_pStoreCB);
|
|
if (SUCCEEDED(m_pStoreCB->GetParentWindow(0, &hwnd)))
|
|
return hwnd;
|
|
return 0;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::Close(void)
|
|
{
|
|
SafeRelease(m_pMsg);
|
|
SafeRelease(m_pOrigMsg);
|
|
|
|
if (m_pMsgTable)
|
|
{
|
|
m_pMsgTable->ConnectionRelease();
|
|
m_pMsgTable->Release();
|
|
m_pMsgTable = NULL;
|
|
}
|
|
|
|
SafeRelease(m_pStoreCB);
|
|
SafeRelease(m_pListSelect);
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::SetStoreCallback(IStoreCallback *pStoreCB)
|
|
{
|
|
ReplaceInterface(m_pStoreCB, pStoreCB);
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::SwitchLanguage(HCHARSET hOldCharset, HCHARSET hNewCharset)
|
|
{
|
|
DWORD dwCodePage = 0;
|
|
INETCSETINFO CsetInfo;
|
|
BOOL fSaveLang = TRUE;
|
|
ROWINDEX iRow = 0;
|
|
HRESULT hr = S_OK;
|
|
|
|
if (OEMSIT_MSG_TABLE != m_dwInitType)
|
|
goto Exit;
|
|
|
|
if (FAILED(m_pMsgTable->GetRowIndex(m_MessageID, &iRow)))
|
|
goto Exit;
|
|
|
|
#if 0
|
|
if (SUCCEEDED(m_pMsgTable->GetLanguage(iRow, &dwCodePage)))
|
|
{
|
|
DWORD dwFlag ;
|
|
|
|
m_pMsg->GetFlags(&dwFlag);
|
|
|
|
// for tagged message only
|
|
if ((dwFlag & IMF_CSETTAGGED) && !dwCodePage )
|
|
fSaveLang = TRUE; // was !IntlCharsetMapLanguageCheck(hOldCharset, hNewCharset); We have
|
|
}
|
|
#endif
|
|
|
|
// save language change to message store
|
|
if (fSaveLang)
|
|
{
|
|
MimeOleGetCharsetInfo(hNewCharset, &CsetInfo);
|
|
dwCodePage = CsetInfo.cpiInternet;
|
|
|
|
// Get index again incase user changed row during dialog
|
|
if (FAILED(m_pMsgTable->GetRowIndex(m_MessageID, &iRow)))
|
|
goto Exit;
|
|
|
|
hr = m_pMsgTable->SetLanguage(1, &iRow, dwCodePage);
|
|
if (FAILED(hr))
|
|
AthMessageBoxW( GetCallbackHwnd(), MAKEINTRESOURCEW(idsAthena),
|
|
MAKEINTRESOURCEW((hr == hrIncomplete)?idsViewLangMimeDBBad:idsErrViewLanguage),
|
|
NULL, MB_OK|MB_ICONEXCLAMATION);
|
|
}
|
|
|
|
Exit:
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::OnComplete(STOREOPERATIONTYPE tyOperation, HRESULT hrComplete, STOREOPERATIONTYPE *ptyNewOp)
|
|
{
|
|
// Action wasn't inited in MsgSite
|
|
if (MSA_IDLE == m_dwMSAction)
|
|
return S_OK;
|
|
|
|
if (ptyNewOp)
|
|
*ptyNewOp = SOT_INVALID;
|
|
|
|
switch (tyOperation)
|
|
{
|
|
case SOT_GET_MESSAGE:
|
|
HandleGetMessage(hrComplete);
|
|
break;
|
|
|
|
case SOT_DELETING_MESSAGES:
|
|
HandleDelete(hrComplete);
|
|
break;
|
|
|
|
case SOT_PUT_MESSAGE:
|
|
HandlePut(hrComplete, ptyNewOp);
|
|
break;
|
|
|
|
case SOT_COPYMOVE_MESSAGE:
|
|
HandleCopyMove(hrComplete);
|
|
SafeRelease(m_pFolderReleaseOnComplete);
|
|
break;
|
|
|
|
#ifdef DEBUG
|
|
default:
|
|
AssertSz(!m_pCBMsgFolder, "How did we get here with a CBMsgFolder");
|
|
#endif
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
HRESULT COEMsgSite::UpdateCallbackInfo(LPSTOREOPERATIONINFO pOpInfo)
|
|
{
|
|
if (pOpInfo->idMessage != MESSAGEID_INVALID)
|
|
{
|
|
m_fHaveCBMessageID = TRUE;
|
|
m_CBMessageID = pOpInfo->idMessage;
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
// ****************************************
|
|
// Need to handle MSA_SAVE, MSA_SEND, MSA_COPYMOVE
|
|
void COEMsgSite::HandlePut(HRESULT hr, STOREOPERATIONTYPE *ptyNewOp)
|
|
{
|
|
// If is COPYMOVE, simply redirect to proper function
|
|
if (MSA_COPYMOVE == m_dwMSAction)
|
|
{
|
|
HandleCopyMove(hr);
|
|
if (ptyNewOp)
|
|
*ptyNewOp = SOT_PUT_MESSAGE;
|
|
return;
|
|
}
|
|
|
|
SafeRelease(m_pCBMsgFolder);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
switch (m_dwMSAction)
|
|
{
|
|
case MSA_SAVE:
|
|
{
|
|
// Decide whether need to delete old message or not
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
{
|
|
if (m_fCBSaveInFolderAndDelOrig)
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
hr = m_pMsgTable->GetRowIndex(m_MessageID, &iRow);
|
|
if (SUCCEEDED(hr))
|
|
hr = m_pMsgTable->DeleteRows(
|
|
DELETE_MESSAGE_NOTRASHCAN |
|
|
DELETE_MESSAGE_NOPROMPT |
|
|
DELETE_MESSAGE_MAYIGNORENOTRASH,
|
|
1, &iRow, FALSE, m_pStoreCB);
|
|
if (SUCCEEDED(hr))
|
|
OnComplete(SOT_DELETING_MESSAGES, S_OK);
|
|
else if ((E_PENDING == hr) && ptyNewOp)
|
|
*ptyNewOp = SOT_DELETING_MESSAGES;
|
|
}
|
|
else
|
|
{
|
|
|
|
m_dwInitType = OEMSIT_STORE;
|
|
m_fThreadingEnabled = FALSE;
|
|
m_FolderID = m_CBFolderID;
|
|
}
|
|
m_MessageID = m_CBMessageID;
|
|
if (!m_fHaveCBMessageID)
|
|
{
|
|
m_dwInitType = OEMSIT_MSG;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Always delete since our message was in drafts and is being saved to drafts
|
|
case OEMSIT_STORE:
|
|
{
|
|
hr = DeleteFromStore(
|
|
DELETE_MESSAGE_NOTRASHCAN |
|
|
DELETE_MESSAGE_NOPROMPT |
|
|
DELETE_MESSAGE_MAYIGNORENOTRASH);
|
|
if ((E_PENDING == hr) && ptyNewOp)
|
|
*ptyNewOp = SOT_DELETING_MESSAGES;
|
|
else if (SUCCEEDED(hr))
|
|
OnComplete(SOT_DELETING_MESSAGES, S_OK);
|
|
break;
|
|
}
|
|
|
|
case OEMSIT_FAT:
|
|
case OEMSIT_MSG:
|
|
case OEMSIT_VIRGIN:
|
|
// This folder id should always be drafts.
|
|
m_FolderID = m_CBFolderID;
|
|
if ((FOLDERID_INVALID != m_FolderID) && m_fHaveCBMessageID)
|
|
{
|
|
m_MessageID = m_CBMessageID;
|
|
m_dwInitType = OEMSIT_STORE;
|
|
m_fThreadingEnabled = FALSE;
|
|
}
|
|
else
|
|
m_dwInitType = OEMSIT_MSG;
|
|
|
|
break;
|
|
}
|
|
if (m_fCBSavedInDrafts)
|
|
DoDontShowMeAgainDlg(GetCallbackHwnd(), c_szDSSavedInSavedItems,
|
|
MAKEINTRESOURCE(idsSavedMessage),
|
|
MAKEINTRESOURCE(idsSavedInDrafts),
|
|
MB_OK);
|
|
|
|
break;
|
|
}
|
|
|
|
// Don't do anything with send. Just be happy that it worked.
|
|
case MSA_SEND:
|
|
break;
|
|
|
|
default:
|
|
AssertSz(FALSE, "Didn't expect to get PUT with other MsgSite action.");
|
|
}
|
|
|
|
|
|
Exit:
|
|
if (hr != E_PENDING)
|
|
m_dwMSAction = MSA_IDLE;
|
|
}
|
|
|
|
void COEMsgSite::HandleGetMessage(HRESULT hr)
|
|
{
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
HRESULT tempHr;
|
|
LoadMessageFromTable(TRUE, &tempHr);
|
|
AssertSz(SUCCEEDED(tempHr), "If hr succeeded, tempHr should have as well.");
|
|
|
|
m_fHeaderOnly = FALSE;
|
|
Notify(OEMSN_UPDATE_PREVIEW);
|
|
SetFocus(GetCallbackHwnd());
|
|
}
|
|
|
|
// Success or failure, we've loaded the target msg. Go to idle
|
|
m_dwMSAction = MSA_IDLE;
|
|
}
|
|
|
|
HRESULT COEMsgSite::Notify(DWORD dwNotifyID)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (dwNotifyID)
|
|
{
|
|
case OEMSN_UPDATE_PREVIEW:
|
|
{
|
|
if ((OEMSIT_MSG_TABLE == m_dwInitType) && (0 != m_MessageID))
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
if (SUCCEEDED(m_pMsgTable->GetRowIndex(m_MessageID, &iRow)))
|
|
m_pListSelect->SetActiveRow(iRow);
|
|
}
|
|
break;
|
|
}
|
|
|
|
case OEMSN_TOGGLE_READRCPT_REQ:
|
|
{
|
|
if (!!(m_dwMDNFlags & MDN_REQUEST))
|
|
{
|
|
m_dwMDNFlags = m_dwMDNFlags & (~MDN_REQUEST);
|
|
}
|
|
else
|
|
{
|
|
m_dwMDNFlags |= MDN_REQUEST;
|
|
}
|
|
break;
|
|
}
|
|
|
|
case OEMSN_PROCESS_READRCPT_REQ:
|
|
{
|
|
ROWINDEX rowIndex = 0;
|
|
|
|
if ((OEMSIT_MSG_TABLE == m_dwInitType) && (0 != m_MessageID))
|
|
{
|
|
|
|
IF_FAILEXIT(hr = m_pMsgTable->GetRowIndex(m_MessageID, &rowIndex));
|
|
|
|
if (!(m_dwArfFlags & ARF_READ))
|
|
{
|
|
IF_FAILEXIT(hr = ProcessReturnReceipts(m_pMsgTable, m_pStoreCB, rowIndex, READRECEIPT, m_FolderID, m_pMsg));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
exit:
|
|
|
|
return hr;
|
|
}
|
|
|
|
// ****************************************
|
|
// Need to handle MSA_DELETE, MSA_COPYMOVE, and MSA_SAVE
|
|
void COEMsgSite::HandleDelete(HRESULT hr)
|
|
{
|
|
AssertSz((MSA_DELETE == m_dwMSAction) || (MSA_COPYMOVE == m_dwMSAction) || (MSA_SAVE == m_dwMSAction),
|
|
"Didn't expect to get DELETE with other MsgSite action.");
|
|
|
|
SafeRelease(m_pCBMsgFolder);
|
|
|
|
// If came from COPYMOVE, then don't do anything here.
|
|
if (FAILED(hr))
|
|
goto exit;
|
|
|
|
if (MSA_COPYMOVE == m_dwMSAction)
|
|
{
|
|
m_FolderID = m_CBFolderID;
|
|
m_MessageID = m_CBMessageID;
|
|
}
|
|
else if (MSA_SAVE == m_dwMSAction)
|
|
{
|
|
m_FolderID = m_CBFolderID;
|
|
m_MessageID = m_CBMessageID;
|
|
if (m_pListSelect && (OEMSIT_MSG_TABLE == m_dwInitType))
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
if (SUCCEEDED(m_pMsgTable->GetRowIndex(m_MessageID, &iRow)))
|
|
m_pListSelect->SetActiveRow(iRow);
|
|
}
|
|
}
|
|
|
|
// Then this must be a straight delete
|
|
else
|
|
switch (m_dwInitType)
|
|
{
|
|
case OEMSIT_MSG_TABLE:
|
|
if (m_fGotNewID)
|
|
{
|
|
m_MessageID = m_NewMessageID;
|
|
m_fNeedToLoadMsg = TRUE;
|
|
if (m_pListSelect)
|
|
{
|
|
ROWINDEX iRow = 0;
|
|
if (SUCCEEDED(m_pMsgTable->GetRowIndex(m_MessageID, &iRow)))
|
|
m_pListSelect->SetActiveRow(iRow);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
m_fValidMessage = FALSE;
|
|
}
|
|
break;
|
|
|
|
// Do nothing if from store
|
|
case OEMSIT_STORE:
|
|
break;
|
|
|
|
}
|
|
|
|
exit:
|
|
|
|
// If doing copy move, I expect SOT_DELETING_MESSAGES to be called before SOT_COPYMOVE_MESSAGE
|
|
m_dwMSAction = MSA_IDLE;
|
|
}
|
|
|
|
// ****************************************
|
|
// Need to handle MSA_COPYMOVE
|
|
void COEMsgSite::HandleCopyMove(HRESULT hr)
|
|
{
|
|
|
|
AssertSz(MSA_COPYMOVE == m_dwMSAction, "Didn't expect to get COPYMOVE with other MsgSite action.");
|
|
|
|
SafeRelease(m_pCBMsgFolder);
|
|
|
|
if (FAILED(hr) || m_fCBCopy)
|
|
goto Exit;
|
|
|
|
switch (m_dwCMFState)
|
|
{
|
|
case CMF_MSG_TO_FOLDER:
|
|
// Don't need to worry about anything
|
|
break;
|
|
|
|
case CMF_TABLE_TO_FOLDER:
|
|
{
|
|
// If we are moving and there is a valid bookmark to go to, then set up the note to have the next message
|
|
if (m_fGotNewID)
|
|
{
|
|
m_MessageID = m_NewMessageID;
|
|
m_fNeedToLoadMsg = TRUE;
|
|
}
|
|
else
|
|
m_fValidMessage = FALSE;
|
|
break;
|
|
}
|
|
|
|
case CMF_STORE_TO_FOLDER:
|
|
{
|
|
FOLDERID folderID;
|
|
MESSAGEIDLIST rMsgIDList;
|
|
|
|
Assert(m_pStoreCB);
|
|
|
|
rMsgIDList.cAllocated = 0;
|
|
rMsgIDList.cMsgs = 1;
|
|
rMsgIDList.prgidMsg = &m_MessageID;
|
|
hr = g_pStore->OpenFolder(m_FolderID, NULL, NOFLAGS, &m_pCBMsgFolder);
|
|
if (FAILED(hr))
|
|
goto Exit;
|
|
|
|
// Don't really care if this works.
|
|
hr = m_pCBMsgFolder->DeleteMessages(
|
|
DELETE_MESSAGE_NOTRASHCAN |
|
|
DELETE_MESSAGE_NOPROMPT |
|
|
DELETE_MESSAGE_MAYIGNORENOTRASH,
|
|
&rMsgIDList, NULL, m_pStoreCB);
|
|
AssertSz(E_PENDING != hr, "Didn't expect E_PENDING here.")
|
|
if (SUCCEEDED(hr))
|
|
OnComplete(SOT_DELETING_MESSAGES, S_OK);
|
|
|
|
break;
|
|
}
|
|
|
|
case CMF_FAT_TO_FOLDER:
|
|
{
|
|
DeleteFileWrapW(m_rgwchFileName);
|
|
|
|
// Need to shut down the note.
|
|
m_fValidMessage = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Exit:
|
|
// I expect SOT_DELETING_MESSAGES to be called before SOT_COPYMOVE_MESSAGE
|
|
m_dwMSAction = MSA_IDLE;
|
|
m_dwCMFState = CMF_UNINITED;
|
|
}
|