///
/// Copyright © 2003-2008 JetBrains s.r.o.
/// You may distribute under the terms of the GNU General Public License, as published by the Free Software Foundation, version 2 (see License.txt in the repository root folder).
///
#pragma unmanaged
#include "msgstore.h"
#include "msgstoresPreloaded.h"
#include "EntryID.h"
#include "EMAPIFolder.h"
#include "ETable.h"
#include "EMessage.h"
#include "ESPropValue.h"
#include "Guard.h"
#include "MAPISession.h"
#include "RCPtrDef.h"
#include "FormViewer.h"
#include "FormManager.h"
#include "AddrBook.h"
template RCPtr;
template RCPtr;
#ifdef EMAPI_MANAGED
#pragma managed
#endif
MsgStore::MsgStore( LPMDB pMDB, LPMAPISESSION lpMAPISession ) : MAPIProp( pMDB ), _ulConnection( 0 ), _pMDB( pMDB ), _pSession( lpMAPISession )
{
OutputDebugString( "MsgStore::MsgStore" );
_sink = NULL;
if ( pMDB == NULL )
{
Guard::ThrowArgumentNullException( "pMDB" );
}
if ( lpMAPISession == NULL )
{
Guard::ThrowArgumentNullException( "lpMAPISession" );
}
_pSession->AddRef();
}
MsgStore::~MsgStore()
{
try
{
Unadvise();
OutputDebugString( "MsgStore::~MsgStore" );
UlRelease( _pSession );
}
catch(...){}
}
AddrBookSPtr MsgStore::OpenAddressBook() const
{
return AddrBook::OpenAddressBook( _pSession );
}
void MsgStore::AddRecipient( const EMessageSPtr& eMessage, LPWSTR displayName, LPWSTR email,
LPSTR displayNameA, LPSTR emailA, int recType ) const
{
HRESULT hr = eMessage->AddRecipient( _pSession, displayName, email, displayNameA, emailA, true, recType );
if ( (int)MAPI_E_BAD_CHARWIDTH == hr )
{
eMessage->AddRecipient( _pSession, displayName, email, displayNameA, emailA, false, recType );
}
}
EMAPIFolderSPtr MsgStore::GetFolderForMessageCreation()
{
EMAPIFolderSPtr folder = OpenDefaultFolder( PR_IPM_DRAFTS_ENTRYID );
if ( folder.IsNull() )
{
folder = OpenOutbox();
}
return folder;
}
EMAPIFolderSPtr MsgStore::OpenDefaultFolder( int tag ) const
{
EMAPIFolderSPtr indox = GetReceiveFolder( "IPM.Note" );
if ( !indox.IsNull() )
{
ESPropValueSPtr entryID = indox->getSingleProp( tag );//PR_IPM_???_ENTRYID
if ( !entryID.IsNull() )
{
return OpenFolder( entryID );
}
}
return EMAPIFolderSPtr( NULL );
}
void MsgStore::DeleteMessage( const EntryIDSPtr& entryID, bool DeletedItems ) const
{
EMessageSPtr message = OpenMessage( entryID );
if ( message.IsNull() )
{
return;
}
ESPropValueSPtr folderID = message->getSingleProp( (int)PR_PARENT_ENTRYID );
if ( folderID.IsNull() )
{
return;
}
message.release();
EMAPIFolderSPtr folder = OpenFolder( folderID );
if ( !DeletedItems )
{
folder->DeleteMessage( entryID );
}
}
void MsgStore::DeleteFolder( const EntryIDSPtr& folderID, bool DeletedItems ) const
{
EMAPIFolderSPtr eFolder = OpenFolder( folderID );
if ( eFolder.IsNull() )
{
return;
}
ESPropValueSPtr parentID = eFolder->getSingleProp( (int)PR_PARENT_ENTRYID );
if ( parentID.IsNull() )
{
return;
}
eFolder.release();
EMAPIFolderSPtr folder = OpenFolder( parentID );
if ( !DeletedItems )
{
folder->DeleteFolder( folderID );
}
}
EMAPIFolderSPtr MsgStore::OpenFolder( const ESPropValueSPtr& folderID ) const
{
if ( folderID.IsNull() )
{
Guard::ThrowArgumentNullException( "folderID" );
}
LPMAPIFOLDER pFolder = NULL;
ULONG ulObjType;
HRESULT hr = _pMDB->OpenEntry( folderID->GetBinCB(), (LPENTRYID)folderID->GetBinLPBYTE(), 0, (int)TEST_MAPI_MODIFY, &ulObjType, (LPUNKNOWN*)&pFolder);
if ( hr == S_OK )
{
return TypeFactory::CreateEMAPIFolder( pFolder );
}
return EMAPIFolderSPtr( NULL );
}
EMAPIFolderSPtr MsgStore::GetReceiveFolder( LPSTR messageClass ) const
{
ULONG cbInboxEID;
LPENTRYID lpInboxEID = NULL;
HRESULT hRes = _pMDB->GetReceiveFolder( messageClass, 0, &cbInboxEID, (LPENTRYID *) &lpInboxEID, NULL );
if ( hRes == S_OK )
{
LPMAPIFOLDER lpFolder = NULL;
unsigned long ulObjectType = 0;
hRes = _pMDB->OpenEntry( cbInboxEID, (LPENTRYID)lpInboxEID, NULL, 0, &ulObjectType,
(LPUNKNOWN*)&lpFolder );
if ( hRes == S_OK )
{
return TypeFactory::CreateEMAPIFolder( lpFolder );
}
}
return EMAPIFolderSPtr( NULL );
}
MsgStoreSPtr MsgStore::OpenMsgStore( LPMAPISESSION pSession, const EntryIDSPtr& entryID )
{
if ( pSession == NULL )
{
Guard::ThrowArgumentNullException( "pSession" );
}
if ( entryID.IsNull() )
{
Guard::ThrowArgumentNullException( "entryID" );
}
LPMDB pMDB = NULL;
HRESULT hr = pSession->OpenMsgStore( 0, entryID->GetLength(), entryID->getLPENTRYID(), 0, (int)MDB_WRITE, &pMDB );
Guard::CheckHR( hr, MapiLastError(pSession) );
if ( hr == S_OK )
{
return TypeFactory::CreateMsgStore( pMDB, pSession );
}
return MsgStoreSPtr( NULL );
}
LPMDB MsgStore::GetRaw() const
{
return _pMDB;
}
//#define PR_TEST_LINE_SPEED PROP_TAG( PT_BINARY, 0x662B0102 )
void MsgStore::Advise( MsgStoreAdviseSink* sink )
{
Unadvise();
int flags = (int)fnevNewMail | (int)fnevObjectCreated | (int)fnevObjectMoved | (int)fnevObjectDeleted |
(int)fnevObjectModified | (int)fnevObjectCopied;
HRESULT hr = Guard::HrThisThreadAdviseSink( sink, &_sink );
Guard::CheckHR( hr );
_pMDB->Advise( 0, 0, flags, _sink, &_ulConnection );
ULONG cProps = 0;
const SizedSPropTagArray( 1, atProps ) = { 1, 0x662B0102 };
LPSPropValue pPropValue = 0;
hr = _pMDB->GetProps( (LPSPropTagArray)&atProps, 0, &cProps, &pPropValue );
MAPIBuffer mapiBuffer( hr, pPropValue );
}
void MsgStore::Unadvise()
{
_pMDB->Unadvise( _ulConnection );
}
ETableSPtr MsgStore::GetReceiveFolderTable() const
{
LPMAPITABLE table = NULL;
HRESULT hr = _pMDB->GetReceiveFolderTable( 0, &table );
if ( hr == S_OK )
{
return TypeFactory::CreateETable( table );
}
return ETableSPtr( NULL );
}
EMAPIFolderSPtr MsgStore::GetRootFolder() const
{
const SizedSPropTagArray( 2, atProps ) = { 2, (int)PR_DISPLAY_NAME, (int)PR_IPM_SUBTREE_ENTRYID };
unsigned long ulCount = 0;
LPSPropValue pVal = 0;
HRESULT hr = _pMDB->GetProps( (LPSPropTagArray)&atProps, 0, &ulCount, &pVal );
MAPIBuffer mapiBuffer( hr, pVal );
if ( SUCCEEDED( hr ) )
{
LPMAPIFOLDER pFolder = 0;
unsigned long ulObjType = 0;
hr = _pMDB->OpenEntry( pVal[1].Value.bin.cb, (LPENTRYID)pVal[1].Value.bin.lpb, 0, (int)TEST_MAPI_MODIFY, &ulObjType,
(LPUNKNOWN*)&pFolder);
if ( SUCCEEDED( hr ) )
{
return TypeFactory::CreateEMAPIFolder( pFolder );
}
}
return EMAPIFolderSPtr( NULL );
}
LPUNKNOWN MsgStore::OpenEntry( const EntryIDSPtr& entryID ) const
{
LPUNKNOWN pMAPIObject = NULL;
unsigned long ulObjectType = 0;
HRESULT hr = _pMDB->OpenEntry( entryID->GetLength(), entryID->getLPENTRYID(), NULL, (int)MAPI_MODIFY,
&ulObjectType, &pMAPIObject );
if ( hr == S_OK && pMAPIObject != NULL )
{
return pMAPIObject;
}
return NULL;
}
EMessageSPtr MsgStore::OpenMessage( const EntryIDSPtr& entryID ) const
{
LPMESSAGE lpMessage = (LPMESSAGE)OpenEntry( entryID );
if ( NULL != lpMessage )
{
return TypeFactory::CreateEMessage( lpMessage );
}
return EMessageSPtr( NULL );
}
EMAPIFolderSPtr MsgStore::OpenFolder( const EntryIDSPtr& entryID ) const
{
LPMAPIFOLDER lpFolder = (LPMAPIFOLDER)OpenEntry( entryID );
if ( NULL != lpFolder )
{
return TypeFactory::CreateEMAPIFolder( lpFolder );
}
return EMAPIFolderSPtr( NULL );
}
EMAPIFolderSPtr MsgStore::OpenOutbox() const
{
ESPropValueSPtr entryID = getSingleProp( (int)PR_IPM_OUTBOX_ENTRYID );
if ( !entryID.IsNull() )
{
LPMAPIFOLDER pOutbox = NULL;
unsigned long ulObjectType = 0;
HRESULT hr = _pMDB->OpenEntry( entryID->GetBinCB(), (LPENTRYID)entryID->GetBinLPBYTE(),
0, (int)TEST_MAPI_MODIFY, &ulObjectType, (LPUNKNOWN*)&pOutbox );
if ( SUCCEEDED( hr ) )
{
return TypeFactory::CreateEMAPIFolder( pOutbox );
}
}
return EMAPIFolderSPtr( NULL );
}
void MsgStore::OpenForm( const EMessageSPtr& message, int verbID )
{
ESPropValueSPtr propStatus = message->GetStatus();
if ( propStatus.IsNull() ) return;
EMAPIFolderSPtr outbox = OpenOutbox();
MsgStoreSPtr msgStore( this );
FormViewer* lpMAPIFormViewer =
new FormViewer( msgStore, _pSession, outbox, message, verbID );
LPMAPIMESSAGESITE lpMAPIMessageSite = 0;
LPMAPIVIEWCONTEXT lpMAPIViewContext = 0;
HRESULT hr = lpMAPIFormViewer->QueryInterface( IID_IMAPIMessageSite, (LPVOID*)&lpMAPIMessageSite );
hr = lpMAPIFormViewer->QueryInterface( IID_IMAPIViewContext, (LPVOID*)&lpMAPIViewContext );
FormManagerSPtr frmManager = FormManager::GetFormManager( _pSession );
MAPIFormSPtr form =
frmManager->LoadForm( propStatus, lpMAPIMessageSite, lpMAPIViewContext, message );
PersistMessageSPtr persistMessage = form->GetPersistMessage();
persistMessage->Save( message );
//persistMessage->Load( lpMAPIMessageSite, message, propStatus );
//form->SetViewContext( lpMAPIViewContext );
lpMAPIFormViewer->SetPersist( persistMessage );
lpMAPIFormViewer->SetForm( form );
form->DoVerb( verbID, lpMAPIViewContext );
UlRelease( lpMAPIViewContext );
UlRelease( lpMAPIMessageSite );
UlRelease( lpMAPIFormViewer );
}
bool MsgStore::ActionMessage( const EntryIDSPtr& entryID, int verbID, EMessageSPtr& message, const MsgStoreSPtr& defMsgStore )
{
if ( message.IsNull() )
{
message = OpenMessage( entryID );
}
if ( message.IsNull() )
{
return false;
}
ESPropValueSPtr propStatus = message->GetStatus();
if ( propStatus.IsNull() )
{
return false;
}
EMAPIFolderSPtr folder = defMsgStore->GetFolderForMessageCreation();
if ( folder.IsNull() )
{
return false;
}
MsgStoreSPtr param( this );
FormViewer* lpMAPIFormViewer = new FormViewer( param, _pSession, folder, message, verbID );
LPMAPIMESSAGESITE lpMAPIMessageSite = 0;
LPMAPIVIEWCONTEXT lpMAPIViewContext = 0;
HRESULT hr = lpMAPIFormViewer->QueryInterface(IID_IMAPIMessageSite,(LPVOID*)&lpMAPIMessageSite);
hr = lpMAPIFormViewer->QueryInterface(IID_IMAPIViewContext,(LPVOID*)&lpMAPIViewContext);
FormManagerSPtr frmManager = FormManager::GetFormManager( _pSession );
MAPIFormSPtr form =
frmManager->LoadForm( propStatus, lpMAPIMessageSite, lpMAPIViewContext, message );
hr = lpMAPIFormViewer->SetForm( form );
form->DoVerb( verbID, lpMAPIViewContext );
UlRelease( lpMAPIViewContext );
UlRelease( lpMAPIMessageSite );
UlRelease( lpMAPIFormViewer );
return true;
}