///
/// 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 "EMAPIFolder.h"
#include "EntryID.h"
#include "Messages.h"
#include "ETable.h"
#include "EMessage.h"
#include "ESPropValue.h"
#include "Guard.h"
#include "RCPtrDef.h"
template RCPtr;
template RCPtr;
EMAPIFolder::EMAPIFolder( LPMAPIFOLDER lpFolder ) : MAPIProp( lpFolder )
{
if ( lpFolder == NULL )
{
Guard::ThrowArgumentNullException( "lpFolder" );
}
_lpFolder = lpFolder;
}
EMAPIFolder::~EMAPIFolder()
{
_lpFolder = NULL;
}
void EMAPIFolder::Empty( ) const
{
HRESULT hr = _lpFolder->EmptyFolder( 0, NULL, 0 );
if ( hr != MAPI_W_PARTIAL_COMPLETION )
{
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
}
void EMAPIFolder::SetReadFlags( const EntryIDSPtr& entry, bool unread ) const
{
SBinary binary;
ENTRYLIST eidMsg;
LPENTRYLIST lpEIDMsg = NULL;
if ( !entry.IsNull() )
{
binary.cb = entry->GetLength();
binary.lpb = (LPBYTE)entry->getLPENTRYID();
eidMsg.cValues = 1;
eidMsg.lpbin = &binary;
lpEIDMsg = &eidMsg;
}
HRESULT hr = _lpFolder->SetReadFlags( lpEIDMsg, NULL, NULL, unread ? CLEAR_READ_FLAG : 0 );
if ( hr != MAPI_W_PARTIAL_COMPLETION )
{
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
}
EMAPIFolderSPtr EMAPIFolder::CreateSubFolder( LPSTR folderName ) const
{
LPMAPIFOLDER lpFolder = NULL;
HRESULT hr =
_lpFolder->CreateFolder( (int)FOLDER_GENERIC, folderName, "Created by Omea", NULL, (int)OPEN_IF_EXISTS, &lpFolder );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
if ( hr == S_OK )
{
return TypeFactory::CreateEMAPIFolder( lpFolder );
}
return EMAPIFolderSPtr( NULL );
}
void EMAPIFolder::SetMessageStatus( const EntryIDSPtr& msgEntryID, int newStatus, int newStatusMask ) const
{
ULONG oldStatus = 0;
HRESULT hr = _lpFolder->SetMessageStatus( msgEntryID->GetLength(), msgEntryID->getLPENTRYID(), newStatus, newStatusMask, &oldStatus );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
int EMAPIFolder::GetMessageStatus( const EntryIDSPtr& msgEntryID ) const
{
ULONG status = 0;
HRESULT hr = _lpFolder->GetMessageStatus( msgEntryID->GetLength(), msgEntryID->getLPENTRYID(), 0, &status );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
return status;
}
MessagesSPtr EMAPIFolder::GetMessages() const
{
return TypeFactory::CreateMessages( _lpFolder );
}
ETableSPtr EMAPIFolder::GetTable() const
{
LPMAPITABLE lpTable = NULL;
HRESULT hr = _lpFolder->GetContentsTable( 0, &lpTable );
if ( hr == S_OK )
{
return TypeFactory::CreateETable( lpTable );
}
return ETableSPtr( NULL );
}
int EMAPIFolder::GetMailCount() const
{
ESPropValueSPtr prop = getSingleProp( (int)PR_CONTENT_COUNT );
if ( !prop.IsNull() )
{
return prop->GetLong();
}
return 0;
}
LPMAPIFOLDER EMAPIFolder::GetRaw() const
{
return _lpFolder;
}
void EMAPIFolder::DeleteMessage( SBinary* pEntryId ) const
{
ENTRYLIST eidMsg;
eidMsg.cValues = 1;
eidMsg.lpbin = pEntryId;
HRESULT hr = _lpFolder->DeleteMessages( &eidMsg, NULL, NULL, 0 );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
void EMAPIFolder::DeleteMessage( const EntryIDSPtr& entry ) const
{
SBinary binary;
binary.cb = entry->GetLength();
binary.lpb = (LPBYTE)entry->getLPENTRYID();
DeleteMessage( &binary );
}
void EMAPIFolder::DeleteMessage( const ESPropValueSPtr& entry ) const
{
SBinary binary;
binary.cb = entry->GetBinCB();
binary.lpb = (LPBYTE)entry->GetBinLPBYTE();
DeleteMessage( &binary );
}
void EMAPIFolder::DeleteFolder( const EntryIDSPtr& entry ) const
{
HRESULT hr = _lpFolder->DeleteFolder( entry->GetLength(), entry->getLPENTRYID(),
0, NULL, (int)( DEL_FOLDERS | DEL_MESSAGES ) );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
EMessageSPtr EMAPIFolder::OpenMessage( const EntryIDSPtr& entryID ) const
{
if ( entryID.IsNull() || entryID->getLPENTRYID() == NULL || entryID->GetLength() == 0 )
{
Guard::ThrowArgumentNullException( "entryID" );
}
LPMESSAGE lpMessage = NULL;
ULONG objectType = 0;
HRESULT hr =
_lpFolder->OpenEntry( entryID->GetLength(), entryID->getLPENTRYID(),
NULL, (int)TEST_MAPI_MODIFY, &objectType, (LPUNKNOWN*)&lpMessage );
if ( hr == S_OK )
{
return TypeFactory::CreateEMessage( lpMessage );
}
if ( hr != (int)MAPI_E_NOT_FOUND && hr != (int)MAPI_E_INVALID_ENTRYID )
{
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
return EMessageSPtr( NULL );
}
void EMAPIFolder::CopyMessage( SBinary* pEntryId, LPVOID pFolderDestination, int flags ) const
{
ENTRYLIST eidMsg;
eidMsg.cValues = 1;
eidMsg.lpbin = pEntryId;
HRESULT hr = _lpFolder->CopyMessages( &eidMsg, &IID_IMAPIFolder, pFolderDestination, NULL, NULL,
flags );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
void EMAPIFolder::CopyMessage( const EntryIDSPtr& entry, const EMAPIFolderSPtr& destFolder, int flags ) const
{
CopyMessage( entry, destFolder->_lpFolder, flags );
}
void EMAPIFolder::CopyMessage( const ESPropValueSPtr& entry, LPVOID pFolderDestination, int flags ) const
{
SBinary binary;
binary.cb = entry->GetBinCB();
binary.lpb = entry->GetBinLPBYTE();
CopyMessage( &binary, pFolderDestination, flags );
}
void EMAPIFolder::CopyMessage( const EntryIDSPtr& entry, LPVOID pFolderDestination, int flags ) const
{
SBinary binary;
binary.cb = entry->GetLength();
binary.lpb = (LPBYTE)entry->getLPENTRYID();
CopyMessage( &binary, pFolderDestination, flags );
}
EMessageSPtr EMAPIFolder::CreateMessage() const
{
LPMESSAGE lpMessage = NULL;
HRESULT hr = _lpFolder->CreateMessage( NULL, 0, &lpMessage );
if ( SUCCEEDED( hr ) )
{
return TypeFactory::CreateEMessage( lpMessage );
}
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
return EMessageSPtr( NULL );
}
EMAPIFoldersSPtr EMAPIFolder::GetFolders() const
{
LPMAPITABLE pTable = NULL;
HRESULT hr = _lpFolder->GetHierarchyTable( 0, &pTable );
if ( hr == S_OK )
{
/*
//IMAP and HotMail MAPIFolders must be extra addreffed
//There should be investigation why
ESPropValueSPtr prop = getSingleProp( (int)PR_CONTAINER_CLASS );
if ( !prop.IsNull() && prop->GetLPSTR() != NULL )
{
LPSTR containerClass = prop->GetLPSTR();
if ( strcmp( containerClass, "IPF.Imap" ) == 0 || strcmp( containerClass, "IPF.Dav" ) == 0 )
{
_lpFolder->AddRef();
}
}
*/
return TypeFactory::CreateEMAPIFolders( _lpFolder, pTable );
}
//0x8004DF0A - error code was thrown I can't find what does it mean
//it is attempt to get folders for deleted info store
if ( hr != 0x8004DF0A )
{
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
return EMAPIFoldersSPtr( NULL );
}
void EMAPIFolder::CopyFolder( const EntryIDSPtr& entry, const EMAPIFolderSPtr& destFolder, int flags ) const
{
HRESULT hr =
_lpFolder->CopyFolder( entry->GetLength(), entry->getLPENTRYID(),
&IID_IMAPIFolder, (LPVOID)destFolder->GetRaw(), NULL, 0, NULL, flags );
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
EMAPIFolders::EMAPIFolders( LPMAPIFOLDER lpFolder, LPMAPITABLE pTable ) : _count( 0 ), _pRows( NULL )
{
if ( lpFolder == NULL )
{
Guard::ThrowArgumentNullException( "lpFolder" );
}
if ( pTable == NULL )
{
Guard::ThrowArgumentNullException( "pTable" );
}
_lpFolder = lpFolder;
_lpFolder->AddRef();
_pTable = pTable;
const SizedSPropTagArray( 2, atProps ) = { 2, (int)PR_DISPLAY_NAME, (int)PR_ENTRYID };
HRESULT hr = HrQueryAllRows( _pTable, (LPSPropTagArray)&atProps, 0, 0, 0, &_pRows );
if ( hr == S_OK )
{
_count = _pRows->cRows;
}
}
EMAPIFolders::~EMAPIFolders()
{
try
{
if ( _pRows != NULL )
{
FreeProws( _pRows );
}
if ( _pTable != NULL )
{
UlRelease( _pTable );
}
if ( _lpFolder != NULL )
{
UlRelease( _lpFolder );
}
}
catch(...){}
}
int EMAPIFolders::GetCount() const
{
return _count;
}
LPSPropValue EMAPIFolders::GetProp( int index, int rowNum ) const
{
LPSPropValue lpsPropVal = &(_pRows->aRow[rowNum].lpProps[index]);
if ( lpsPropVal != NULL && lpsPropVal->Value.err != (int)MAPI_E_NOT_FOUND )
{
return lpsPropVal;
}
return NULL;
}
EMAPIFolderSPtr EMAPIFolders::GetFolder( int rowNum ) const
{
LPSPropValue pVal = _pRows->aRow[rowNum].lpProps;
LPMAPIFOLDER lpMAPIFolder = NULL;
ULONG objectType = 0;
HRESULT hr = _lpFolder->OpenEntry( pVal[1].Value.bin.cb, (LPENTRYID)pVal[1].Value.bin.lpb,
0, 0, &objectType, (LPUNKNOWN*)&lpMAPIFolder );
if ( SUCCEEDED( hr )&& lpMAPIFolder != NULL )
{
return TypeFactory::CreateEMAPIFolder( lpMAPIFolder );
}
if ( hr != (int)MAPI_E_INVALID_ENTRYID )
{
Guard::CheckHR( hr, MapiLastError(_lpFolder) );
}
return EMAPIFolderSPtr( NULL );
}