/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2008 OMC Denmark ApS.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include "obj_utils.h"
#include "utils/macros.h"

// Type code (like "MAPI_STATUS") identified interfaces
#include "IMsgStoreS_impl.h"
#include "IAddrBookS_impl.h"
#include "IProfSectS_impl.h"
#include "IMAPIFolderS_impl.h"
#include "IABContainerS_impl.h"
#include "IMessageS_impl.h"
#include "IAttachS_impl.h"
#include "IDistListS_impl.h"
#include "IMAPIStatusS_impl.h"
#include "IMailUserS_impl.h"
#include "IMAPITableS_impl.h"

// the new ones.. (not identified by a type code)
#include "IMAPIPropS_impl.h"
#include "IMAPIContainerS_impl.h"
#include "IMAPIProgressS_impl.h"
#include "IProviderAdminS_impl.h"
#include "IMAPIControlS_impl.h"
#include "IProfAdminS_impl.h"
#include "IMAPISupportS_impl.h"
#include "IMSProviderS_impl.h"
#include "IABProviderS_impl.h"
#include "IXPProviderS_impl.h"
#include "IMSLogonS_impl.h"
#include "IABLogonS_impl.h"
#include "IXPLogonS_impl.h"
#include "ITnefS_impl.h"
#include "ISpoolerHookS_impl.h"
#include "IMsgServiceAdminS_impl.h"
#include "IMAPIFormContainerS_impl.h"
#include "IStreamS_impl.h"
#include "ITableDataS_impl.h"
#include "IPropDataS_impl.h"

// edkmdb Exchange Message Store interfaces
#include "IExchangeExportChangesS_impl.h"
#include "IExchangeFavoritesS_impl.h"
#include "IExchangeImportContentsChangesS_impl.h"
#include "IExchangeImportHierarchyChangesS_impl.h"
#include "IExchangeManageStoreS_impl.h"
#include "IExchangeModifyTableS_impl.h"
#include "IExchangeRuleActionS_impl.h"

// BRUTUS_IID_* GUIDs
#include "uidC.h"

#include "utils/macros.h"
#include "templates.i"

#include <mapiform.h>

bool create_brutus_object(const char *ObjID,
			  LPUNKNOWN Mapi_Object,
			  PortableServer::POA_ptr Poa,
			  BRUTUS::IUnknown_out Brutus_Object,
			  LPMAPISESSION Mapi_Session)
{
	Brutus_Object = BRUTUS::IUnknown::_nil();
	if (!Mapi_Object)
		return false;

	if (!Mapi_Session)
		BRUTUS_LOG_INF("Invoked with NIL Mapi_Session");

	try {
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMsgStore)) {
			Brutus_Object = create_object<BRUTUS_IMsgStore_i, BRUTUS::IMsgStore, LPMDB>
				((LPMDB)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPITable)) {
			Brutus_Object = create_object<BRUTUS_IMAPITable_i, BRUTUS::IMAPITable, LPMAPITABLE>
				((LPMAPITABLE)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IAddrBook)) {
			Brutus_Object = create_object<BRUTUS_IAddrBook_i, BRUTUS::IAddrBook, LPADRBOOK>
				((LPADRBOOK)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFolder)) {
			Brutus_Object = create_object<BRUTUS_IMAPIFolder_i, BRUTUS::IMAPIFolder, LPMAPIFOLDER>
				((LPMAPIFOLDER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IABContainer)) {
			Brutus_Object = create_object<BRUTUS_IABContainer_i, BRUTUS::IABContainer, LPABCONT>
				((LPABCONT)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMessage)) {
			Brutus_Object = create_object<BRUTUS_IMessage_i, BRUTUS::IMessage, LPMESSAGE>
				((LPMESSAGE)Mapi_Object, Poa, Mapi_Session);


			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMailUser)) {
			Brutus_Object = create_object<BRUTUS_IMailUser_i, BRUTUS::IMailUser, LPMAILUSER>
				((LPMAILUSER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IAttachment)) {
			Brutus_Object = create_object<BRUTUS_IAttach_i, BRUTUS::IAttach, LPATTACH>
				((LPATTACH)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IDistList)) {
			Brutus_Object = create_object<BRUTUS_IDistList_i, BRUTUS::IDistList, LPDISTLIST>
				((LPDISTLIST)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IProfSect)) {
			Brutus_Object = create_object<BRUTUS_IProfSect_i, BRUTUS::IProfSect, LPPROFSECT>
				((LPPROFSECT)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIStatus)) {
			Brutus_Object = create_object<BRUTUS_IMAPIStatus_i, BRUTUS::IMAPIStatus, LPMAPISTATUS>
				((LPMAPISTATUS)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IStream)) {
			Brutus_Object = create_object<BRUTUS_IStream_i, BRUTUS::IStream, LPSTREAM>
				((LPSTREAM)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIPropData)) {
			Brutus_Object = create_object<BRUTUS_IPropData_i, BRUTUS::IPropData, LPPROPDATA>
				((LPPROPDATA)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPITableData)) {
			Brutus_Object = create_object<BRUTUS_ITableData_i, BRUTUS::ITableData, LPTABLEDATA>
				((LPTABLEDATA)Mapi_Object, Poa, Mapi_Session);

			return true;
		}

		// check these out..
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIProp)) {
			Brutus_Object = create_object<BRUTUS_IMAPIProp_i, BRUTUS::IMAPIProp, LPMAPIPROP>
				((LPMAPIPROP)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIContainer)) {
			Brutus_Object = create_object<BRUTUS_IMAPIContainer_i, BRUTUS::IMAPIContainer, LPMAPICONTAINER>
				((LPMAPICONTAINER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIProgress)) {
			Brutus_Object = create_object<BRUTUS_IMAPIProgress_i, BRUTUS::IMAPIProgress, LPMAPIPROGRESS>
				((LPMAPIPROGRESS)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IProviderAdmin)) {
			Brutus_Object = create_object<BRUTUS_IProviderAdmin_i, BRUTUS::IProviderAdmin, LPPROVIDERADMIN>
				((LPPROVIDERADMIN)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIControl)) {
			Brutus_Object = create_object<BRUTUS_IMAPIControl_i, BRUTUS::IMAPIControl, LPMAPICONTROL>
				((LPMAPICONTROL)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IProfAdmin)) {
			Brutus_Object = create_object<BRUTUS_IProfAdmin_i, BRUTUS::IProfAdmin, IProfAdmin*>
				((IProfAdmin*)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMsgServiceAdmin)) {
			Brutus_Object = create_object<BRUTUS_IMsgServiceAdmin_i, BRUTUS::IMsgServiceAdmin, IMsgServiceAdmin*>
				((IMsgServiceAdmin*)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIStatus)) {
			Brutus_Object = create_object<BRUTUS_IMAPIStatus_i, BRUTUS::IMAPIStatus, IMAPIStatus*>
				((IMAPIStatus*)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPISup)) {
			Brutus_Object = create_object<BRUTUS_IMAPISupport_i, BRUTUS::IMAPISupport, LPMAPISUP>
				((LPMAPISUP)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMSProvider)) {
			Brutus_Object = create_object<BRUTUS_IMSProvider_i, BRUTUS::IMSProvider, LPMSPROVIDER>
				((LPMSPROVIDER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IABProvider)) {
			Brutus_Object = create_object<BRUTUS_IABProvider_i, BRUTUS::IABProvider, LPABPROVIDER>
				((LPABPROVIDER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IXPProvider)) {
			Brutus_Object = create_object<BRUTUS_IXPProvider_i, BRUTUS::IXPProvider, LPXPPROVIDER>
				((LPXPPROVIDER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMSLogon)) {
			Brutus_Object = create_object<BRUTUS_IMSLogon_i, BRUTUS::IMSLogon, LPMSLOGON>
				((LPMSLOGON)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IABLogon)) {
			Brutus_Object = create_object<BRUTUS_IABLogon_i, BRUTUS::IABLogon, LPABLOGON>
				((LPABLOGON)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IXPLogon)) {
			Brutus_Object = create_object<BRUTUS_IXPLogon_i, BRUTUS::IXPLogon, LPXPLOGON>
				((LPXPLOGON)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_ITNEF)) {
			Brutus_Object = create_object<BRUTUS_ITnef_i, BRUTUS::ITnef, LPITNEF>
				((LPITNEF)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_ISpoolerHook)) {
			Brutus_Object = create_object<BRUTUS_ISpoolerHook_i, BRUTUS::ISpoolerHook, LPSPOOLERHOOK>
				((LPSPOOLERHOOK)Mapi_Object, Poa, Mapi_Session);

			return true;
		}

		// edkmdb interfaces
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeExportChanges)) {
			Brutus_Object = create_object<BRUTUS_IExchangeExportChanges_i, BRUTUS::IExchangeExportChanges, LPEXCHANGEEXPORTCHANGES>
				((LPEXCHANGEEXPORTCHANGES)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeFavorites)) {
			Brutus_Object = create_object<BRUTUS_IExchangeFavorites_i, BRUTUS::IExchangeFavorites, LPEXCHANGEFAVORITES>
				((LPEXCHANGEFAVORITES)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeImportContentsChanges)) {
			Brutus_Object = create_object<BRUTUS_IExchangeImportContentsChanges_i, BRUTUS::IExchangeImportContentsChanges, LPEXCHANGEIMPORTCONTENTSCHANGES>
				((LPEXCHANGEIMPORTCONTENTSCHANGES)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeImportHierarchyChanges)) {
			Brutus_Object = create_object<BRUTUS_IExchangeImportHierarchyChanges_i, BRUTUS::IExchangeImportHierarchyChanges, LPEXCHANGEIMPORTHIERARCHYCHANGES>
				((LPEXCHANGEIMPORTHIERARCHYCHANGES)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeManageStore)) {
			Brutus_Object = create_object<BRUTUS_IExchangeManageStore_i, BRUTUS::IExchangeManageStore, LPEXCHANGEMANAGESTORE>
				((LPEXCHANGEMANAGESTORE)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeModifyTable)) {
			Brutus_Object = create_object<BRUTUS_IExchangeModifyTable_i, BRUTUS::IExchangeModifyTable, LPEXCHANGEMODIFYTABLE>
				((LPEXCHANGEMODIFYTABLE)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IExchangeRuleAction)) {
			Brutus_Object = create_object<BRUTUS_IExchangeRuleAction_i, BRUTUS::IExchangeRuleAction, LPEXCHANGERULEACTION>
				((LPEXCHANGERULEACTION)Mapi_Object, Poa, Mapi_Session);

			return true;
		}

		// Form interfaces
		if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormContainer)) {
			Brutus_Object = create_object<BRUTUS_IMAPIFormContainer_i, BRUTUS::IMAPIFormContainer, LPMAPIFORMCONTAINER>
				((LPMAPIFORMCONTAINER)Mapi_Object, Poa, Mapi_Session);

			return true;
		}
		/*
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIMessageSite)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIMessageSite_i, BRUTUS::IMAPIMessageSite, IMAPIMessageSite*>
		  ((IMAPIMessageSite*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIViewContext)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIViewContext_i, BRUTUS::IMAPIViewContext, IMAPIViewContext*>
		  ((IMAPIViewContext*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormMgr)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIFormMgr_i, BRUTUS::IMAPIFormMgr, IMAPIFormMgr*>
		  ((IMAPIFormMgr*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IEnumMAPIFormProp)) {
		  Brutus_Object = create_object<BRUTUS_IEnumMAPIFormProp_i, BRUTUS::IEnumMAPIFormProp, IEnumMAPIFormProp*>
		  ((IEnumMAPIFormProp*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormInfo)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIFormInfo_i, BRUTUS::IMAPIFormInfo, IMAPIFormInfo*>
		  ((IMAPIFormInfo*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIForm)) {
		  Brutus_Object = create_object<BRUTUSIMAPIForm__i, BRUTUS::IMAPIForm, IMAPIForm*>
		  ((IMAPIForm*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IPersistMessage)) {
		  Brutus_Object = create_object<BRUTUS_IPersistMessage_i, BRUTUS::IPersistMessage, IPersistMessage*>
		  ((IPersistMessage*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIViewAdviseSink)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIViewAdviseSink_i, BRUTUS::IMAPIViewAdviseSink, IMAPIViewAdviseSink*>
		  ((IMAPIViewAdviseSink*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormFactory)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIFormFactory_i, BRUTUS::IMAPIFormFactory, IMAPIFormFactory*>
		  ((IMAPIFormFactory*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormAdviseSink)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIFormAdviseSink_i, BRUTUS::IMAPIFormAdviseSink, IMAPIFormAdviseSink*>
		  ((IMAPIFormAdviseSink*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }

		  // Misc. other undocumented interfaces.
		  // Only here to ease an eventual later implementation..
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPISpoolerService)) {
		  Brutus_Object = create_object<BRUTUS_IMAPISpoolerService_i, BRUTUS::IMAPISpoolerService, IMAPISpoolerService*>
		  ((IMAPISpoolerService*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPISpoolerInit)) {
		  Brutus_Object = create_object<BRUTUS_IMAPISpoolerInit_i, BRUTUS::IMAPISpoolerInit, IMAPISpoolerInit*>
		  ((IMAPISpoolerInit*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPISpoolerSession)) {
		  Brutus_Object = create_object<BRUTUS_IMAPISpoolerSession_i, BRUTUS::IMAPISpoolerSession, IMAPISpoolerSession*>
		  ((IMAPISpoolerSession*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IStreamDocfile)) {
		  Brutus_Object = create_object<BRUTUS_IStreamDocfile_i, BRUTUS::IStreamDocfile, IStreamDocfile*>
		  ((IStreamDocfile*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		  if (!strcmp(ObjID, BRUTUS::BRUTUS_IID_IMAPIFormProp)) {
		  Brutus_Object = create_object<BRUTUS_IMAPIFormProp_i, BRUTUS::IMAPIFormProp, IMAPIFormProp*>
		  ((IMAPIFormProp*)Mapi_Object, Poa, Mapi_Session);

		  return true;
		  }
		*/
	}
	catch (...) {
		char msg[256] = {0};
		sprintf_s(msg, sizeof(msg), "Exception caught - MAPI interface : %s", ObjID);
		BRUTUS_LOG_BUG(msg);
		return false;
	}

	{
		char msg[256] = {0};
		sprintf_s(msg, sizeof(msg), "Unknown or unsupported MAPI interface : %s", ObjID);
		BRUTUS_LOG_BUG(msg);
		return false;
	}
}


bool create_brutus_object(const unsigned long ObjType,
			  LPUNKNOWN Mapi_Object,
			  PortableServer::POA_ptr Poa,
			  BRUTUS::IUnknown_out Brutus_Object,
			  LPMAPISESSION Mapi_Session)
{
	Brutus_Object = BRUTUS::IUnknown::_nil();
	if (!Mapi_Object)
		return false;

	try {
		switch (ObjType) {
		case MAPI_STORE    : /* Message Store */
			Brutus_Object = create_object<BRUTUS_IMsgStore_i, BRUTUS::IMsgStore, LPMDB>
				((LPMDB)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_ADDRBOOK : /* Address Book */
			Brutus_Object = create_object<BRUTUS_IAddrBook_i, BRUTUS::IAddrBook, LPADRBOOK>
				((LPADRBOOK)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_FOLDER   : /* Folder */
			Brutus_Object = create_object<BRUTUS_IMAPIFolder_i, BRUTUS::IMAPIFolder, LPMAPIFOLDER>
				((LPMAPIFOLDER)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_ABCONT   : /* Address Book Container */
			Brutus_Object = create_object<BRUTUS_IABContainer_i, BRUTUS::IABContainer, LPABCONT>
				((LPABCONT)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_MESSAGE  : /* Message */
			Brutus_Object = create_object<BRUTUS_IMessage_i, BRUTUS::IMessage, LPMESSAGE>
				((LPMESSAGE)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_MAILUSER : /* Individual Recipient */
			Brutus_Object = create_object<BRUTUS_IMailUser_i, BRUTUS::IMailUser, LPMAILUSER>
				((LPMAILUSER)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_ATTACH   : /* Attachment */
			Brutus_Object = create_object<BRUTUS_IAttach_i, BRUTUS::IAttach, LPATTACH>
				((LPATTACH)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_DISTLIST : /* Distribution List Recipient */
			Brutus_Object = create_object<BRUTUS_IDistList_i, BRUTUS::IDistList, LPDISTLIST>
				((LPDISTLIST)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_PROFSECT : /* Profile Section */
			Brutus_Object = create_object<BRUTUS_IProfSect_i, BRUTUS::IProfSect, LPPROFSECT>
				((LPPROFSECT)Mapi_Object, Poa, Mapi_Session);

			break;
		case MAPI_STATUS   : /* Status Object */
			Brutus_Object = create_object<BRUTUS_IMAPIStatus_i, BRUTUS::IMAPIStatus, LPMAPISTATUS>
				((LPMAPISTATUS)Mapi_Object, Poa, Mapi_Session);

			break;
		default :
		{
			char msg[128] = {0};
			sprintf_s(msg, sizeof(msg), "Unknown or unsupported MAPI interface : %X", ObjType);
			BRUTUS_LOG_BUG(msg);
			return false;
		}
		}
	}
	catch (...) {
		char msg[128] = {0};
		sprintf_s(msg, sizeof(msg), "Exception caught - MAPI interface : %X", ObjType);
		BRUTUS_LOG_BUG(msg);
		return false;
	}

	return true;
}

// The last argument must be (GUID*)0
bool mapi_guid_is_one_of(const GUID *m_id,
			 const GUID* const id ...)
{
	bool retv;
	const GUID* arg;


	retv = MAPI_GUIDS_EQUAL(m_id, id);
	if (retv != true)
		return false;

	va_list id_list;
	va_start(id_list, id);
	for (;;) {
		arg = va_arg(id_list, const GUID* const);
		if (arg == 0)
			break;

		retv = retv && MAPI_GUIDS_EQUAL(m_id, arg);
		if (retv != true)
			break;
	}
	va_end(id_list);

	return retv;
}
