/* -*- 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 "IMsgServiceAdminS_impl.h"
#include "obj_utils.h"
#include "conv_utils.h"
#include "IMAPITableS_impl.h"
#include "IProfSectS_impl.h"
#include "IProviderAdminS_impl.h"

#include "templates.i"

#include <mapispi.h>

static inline ULONG native_flags(const ::BRUTUS::BDEFINE Flags)
{
	::BRUTUS::BDEFINE flags = Flags;
	ULONG retval = 0;

	if (!Flags)
		return 0;

	if (flags & ::BRUTUS::BRUTUS_MAPI_UNICODE) {
		retval |= MAPI_UNICODE;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_UNICODE);
	}
	if (flags & ::BRUTUS::BRUTUS_SERVICE_UI_ALWAYS) {
		retval |= SERVICE_UI_ALWAYS;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_SERVICE_UI_ALWAYS);
	}
	if (flags & ::BRUTUS::BRUTUS_MSG_SERVICE_UI_READ_ONLY) {
		retval |= MSG_SERVICE_UI_READ_ONLY;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MSG_SERVICE_UI_READ_ONLY);
	}
	if (flags & ::BRUTUS::BRUTUS_SERVICE_UI_ALLOWED) {
		retval |= SERVICE_UI_ALLOWED;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_SERVICE_UI_ALLOWED);
	}
	if (flags & ::BRUTUS::BRUTUS_SERVICE_UI_ALWAYS) {
		retval |= SERVICE_UI_ALWAYS;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_SERVICE_UI_ALWAYS);
	}
	if (flags & ::BRUTUS::BRUTUS_MAPI_DEFERRED_ERRORS) {
		retval |= MAPI_DEFERRED_ERRORS;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_DEFERRED_ERRORS);
	}
	if (flags & ::BRUTUS::BRUTUS_MAPI_MODIFY) {
		retval |= MAPI_MODIFY;
		FLAGS_OFF(::BRUTUS::BDEFINE, flags, ::BRUTUS::BRUTUS_MAPI_MODIFY);
	}

	if (flags) {
		char msg[128] = {0};
		sprintf_s(msg, sizeof(msg), "Unknown flag(s) from BRUTUS : %X", flags);
		BRUTUS_LOG_BUG(msg);
	}

	return retval;
}


BRUTUS_IMsgServiceAdmin_i::BRUTUS_IMsgServiceAdmin_i(LPSERVICEADMIN ServiceAdmin,
						     LPMAPISESSION MAPISession,
						     ::PortableServer::POA_ptr Poa)
	: service_admin_(ServiceAdmin),
	  mapi_session_(MAPISession),
	  poa_(::PortableServer::POA::_duplicate(Poa))
{
	mapi_session_->AddRef();
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::GetLastError(::BRUTUS::BRESULT ReturnCode,
							  ::BRUTUS::BDEFINE ulFlags,
							  ::BRUTUS::MAPIERROR_out lppMAPIError)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::GetLastError()");

	::BRUTUS::MAPIERROR_var error;
	try {
		error = new ::BRUTUS::MAPIERROR;
	}
	catch (std::bad_alloc &) {
		BRUTUS_LOG_ERR("No memory");
		throw ::CORBA::NO_MEMORY();
	}
	error->ulVersion = (::CORBA::ULong)0;
	error->ulLowLevelError = (::CORBA::ULong)0;
	error->ulContext = (::CORBA::ULong)0;

	HRESULT hr;
	if (!bresult_to_hresult(ReturnCode, hr)) {
		lppMAPIError = error._retn();
		BRUTUS_LOG_BUG("Could not convert BRESULT into HRESULT");
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	LPMAPIERROR mapi_error = NULL;
	unsigned long flags = native_flags(ulFlags);

	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->GetLastError(hr, flags, &mapi_error);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		MAPIFreeBuffer(mapi_error);
		lppMAPIError = error._retn();
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}
	if (!mapi_error)
		BRUTUS_LOG_INF("No applicable error information from MAPI");

	mapierror_mapi_to_brutus(mapi_error, error, true);

	lppMAPIError = error._retn();

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::GetLastError()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::GetMsgServiceTable(::BRUTUS::BDEFINE ulFlags,
								::BRUTUS::IMAPITable_out lppTable)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::GetMsgServiceTable()");

	unsigned long flags = native_flags(ulFlags);
	lppTable = ::BRUTUS::IMAPITable::_nil();
	LPMAPITABLE mapi_table = NULL;

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->GetMsgServiceTable(flags,
							&mapi_table);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	if (hr == S_OK)
		lppTable = create_object<BRUTUS_IMAPITable_i, ::BRUTUS::IMAPITable, LPMAPITABLE>
			(mapi_table, poa_.in(), mapi_session_);

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::GetMsgServiceTable()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::CreateMsgService(const char * lpszService,
							      const char * lpszDisplayName,
							      ::BRUTUS::BDEFINE ulFlags)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::CreateMsgService()");

	unsigned long flags = native_flags(ulFlags);
	FLAGS_OFF(ULONG, flags, SERVICE_UI_ALWAYS);

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->CreateMsgService((char*)lpszService,
						      (char*)lpszDisplayName,
						      0,
						      flags);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::CreateMsgService()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::DeleteMsgService(const char * lpUID)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::DeleteMsgService()");

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->DeleteMsgService(&u_id);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::DeleteMsgService()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::CopyMsgService(const char * lpUID,
							    const char * lpszDisplayName,
							    const char * lpInterfaceToCopy,
							    const char * lpInterfaceDst,
							    const ::BRUTUS::ENTRYID & lpObjectDst,
							    ::BRUTUS::BDEFINE ulFlags)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::CopyMsgService()");

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	GUID* i_id_to_copy;
	if (!guid_brutus_to_mapi(lpInterfaceToCopy, NULL, i_id_to_copy)) {
		BRUTUS_LOG_BUG("Could not convert ::BRUTUS::GUID into MAPI GUID");
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	GUID* i_id_dst;
	if (!guid_brutus_to_mapi(lpInterfaceDst, NULL, i_id_dst)) {
		BRUTUS_LOG_BUG("Could not convert ::BRUTUS::GUID into MAPI GUID");
		MAPIFreeBuffer(i_id_to_copy);
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	ENTRYID *entry_id = NULL;
	unsigned long entry_id_size;
	if (!entryid_brutus_to_mapi(&lpObjectDst, 0, entry_id_size, entry_id)) {
		BRUTUS_LOG_ERR("No memory");
		MAPIFreeBuffer(i_id_to_copy);
		MAPIFreeBuffer(i_id_dst);
		throw ::CORBA::NO_MEMORY();
	}
	LPUNKNOWN unk_dest_object = NULL;
	HRESULT hr;
	{
		unsigned long obj_type;
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = mapi_session_->OpenEntry(entry_id_size,
					      entry_id,
					      i_id_dst,
					      MAPI_MODIFY,
					      &obj_type,
					      &unk_dest_object);
	}
	::BRUTUS::BRESULT br;
	if (hr != S_OK) {
		if (!hresult_to_bresult(hr, br)) {
			BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
			br = ::BRUTUS::BRUTUS_INTERNAL_ERROR;
		}
		BRUTUS_LOG_BUG("Error opening object");
		if (unk_dest_object)
			unk_dest_object->Release();
		MAPIFreeBuffer(i_id_to_copy);
		MAPIFreeBuffer(i_id_dst);

		return br;
	}

	ULONG flags = native_flags(ulFlags);
	FLAGS_OFF(ULONG, flags, SERVICE_UI_ALWAYS);

	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->CopyMsgService(&u_id,
						    (char*)lpszDisplayName,
						    i_id_to_copy,
						    i_id_dst,
						    (void*)unk_dest_object,
						    0,
						    flags);
	}
	if (unk_dest_object)
		unk_dest_object->Release();
	MAPIFreeBuffer(i_id_to_copy);
	MAPIFreeBuffer(i_id_dst);

	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::CopyMsgService()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::RenameMsgService(const char * lpUID,
							      ::BRUTUS::BDEFINE ulFlags,
							      const char * lpszDisplayName)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::RenameMsgService()");

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	ULONG flags = native_flags(ulFlags);

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->RenameMsgService(&u_id,
						      flags,
						      (char*)lpszDisplayName);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::RenameMsgService()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::ConfigureMsgService(const char * lpUID,
								 ::BRUTUS::BDEFINE ulFlags,
								 const ::BRUTUS::seq_SPropValue & lpProps)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::ConfigureMsgService()");

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	ULONG flags = native_flags(ulFlags);
	FLAGS_OFF(ULONG, flags, SERVICE_UI_ALLOWED);
	FLAGS_OFF(ULONG, flags, SERVICE_UI_ALWAYS);
	FLAGS_OFF(ULONG, flags, MSG_SERVICE_UI_READ_ONLY);

	unsigned long count = 0;
	LPSPropValue mapi_props = NULL;
	if (!spropvalue_array_brutus_to_mapi(&lpProps, 0, count, mapi_props)) {
		MAPIFreeBuffer(mapi_props);
		BRUTUS_LOG_ERR("Could not convert Brutus seq_SPropValue to MAPI SPropValue");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->ConfigureMsgService(&u_id,
							 0,
							 flags,
							 count,
							 mapi_props);
	}
	MAPIFreeBuffer(mapi_props);

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::ConfigureMsgService()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::OpenProfileSection(const char * lpUID,
								const char * lpInterface,
								::BRUTUS::BDEFINE ulFlags,
								::BRUTUS::IProfSect_out lppProfSect)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::OpenProfileSection()");

	lppProfSect = ::BRUTUS::IProfSect::_nil();

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	GUID *i_id;
	if (!guid_brutus_to_mapi(lpInterface, NULL, i_id)) {
		BRUTUS_LOG_BUG("Could not convert ::BRUTUS::GUID into MAPI GUID");
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	unsigned long flags = native_flags(ulFlags);
	LPPROFSECT prof_sect = NULL;

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->OpenProfileSection(&u_id,
							i_id,
							flags,
							&prof_sect);
	}
	MAPIFreeBuffer(i_id);

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	if (hr == S_OK)
		lppProfSect = create_object<BRUTUS_IProfSect_i, ::BRUTUS::IProfSect, LPPROFSECT>
			(prof_sect, poa_.in(), mapi_session_);

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::OpenProfileSection()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::MsgServiceTransportOrder(const ::BRUTUS::seq_MAPIUID & lpUIDList,
								      ::BRUTUS::BDEFINE ulFlags)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::MsgServiceTransportOrder()");

	MAPIUID *u_ids;
	if (!mapiuid_array_brutus_to_mapi(&lpUIDList, 0, u_ids)) {
		BRUTUS_LOG_ERR("No memory");
		throw ::CORBA::NO_MEMORY();
	}

	unsigned long flags = native_flags(ulFlags);

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->MsgServiceTransportOrder(lpUIDList.length(),
							      u_ids,
							      flags);
	}
	MAPIFreeBuffer(u_ids);

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::MsgServiceTransportOrder()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::AdminProviders(const char * lpUID,
							    ::BRUTUS::BDEFINE ulFlags,
							    ::BRUTUS::IProviderAdmin_out lppProviderAdmin)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::AdminProviders()");

	MAPIUID u_id;
	mapiuid_brutus_to_mapi_no_alloc(lpUID, u_id);

	ULONG flags = native_flags(ulFlags);

	lppProviderAdmin = ::BRUTUS::IProviderAdmin::_nil();

	LPPROVIDERADMIN provider_admin = NULL;

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->AdminProviders(&u_id,
						    flags,
						    &provider_admin);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	if (hr == S_OK)
		lppProviderAdmin = create_object<BRUTUS_IProviderAdmin_i, ::BRUTUS::IProviderAdmin, LPPROVIDERADMIN>
			(provider_admin, poa_.in(), mapi_session_);

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::AdminProviders()");
	return br;
}

::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::SetPrimaryIdentity(const char * lpUID,
								::BRUTUS::BDEFINE ulFlags)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::SetPrimaryIdentity()");

	MAPIUID *u_id;
	if (!mapiuid_brutus_to_mapi(lpUID, 0, u_id)) {
		BRUTUS_LOG_BUG("Could not convert ::BRUTUS::MAPIUID into MAPI MAPIUID");
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	ULONG flags = native_flags(ulFlags);

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->SetPrimaryIdentity(u_id,
							flags);
	}
	MAPIFreeBuffer(u_id);

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::SetPrimaryIdentity()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::GetProviderTable(::BRUTUS::BDEFINE ulFlags,
							      ::BRUTUS::IMAPITable_out lppTable)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::GetProviderTable()");

	unsigned long flags = native_flags(ulFlags);
	lppTable = ::BRUTUS::IMAPITable::_nil();
	LPMAPITABLE mapi_table = NULL;

	HRESULT hr;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->GetProviderTable(flags,
						      &mapi_table);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	if (hr == S_OK)
		lppTable = create_object<BRUTUS_IMAPITable_i, ::BRUTUS::IMAPITable, LPMAPITABLE>
			(mapi_table, poa_.in(), mapi_session_);

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::GetProviderTable()");
	return br;
}


::BRUTUS::BRESULT BRUTUS_IMsgServiceAdmin_i::QueryInterface(const char *iid,
							    ::BRUTUS::IUnknown_out ppvObject)
{
	ppvObject = ::BRUTUS::IUnknown::_nil();

	GUID mapi_iid;
	if (!guid_brutus_to_mapi_no_alloc(iid, &mapi_iid)) {
		BRUTUS_LOG_BUG("Could not convert ::BRUTUS::GUID into MAPI GUID");
		return ::BRUTUS::BRUTUS_MAPI_E_INVALID_PARAMETER;
	}

	HRESULT hr;
	void *object = NULL;
	{
		ACE_Write_Guard<ACE_RW_Mutex> guard(mutex_);
		hr = service_admin_->QueryInterface(mapi_iid, &object);
	}

	::BRUTUS::BRESULT br;
	if (!hresult_to_bresult(hr, br)) {
		BRUTUS_LOG_BUG("Could not convert HRESULT into BRESULT");
		return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
	}

	if (hr == S_OK) {
		if (!create_brutus_object(iid, (LPUNKNOWN)object, poa_, ppvObject, mapi_session_)) {
			BRUTUS_LOG_BUG("Could not create brutus object.");
			((LPUNKNOWN)object)->Release();
			return ::BRUTUS::BRUTUS_INTERNAL_ERROR;
		}
	}

	return br;
}

void BRUTUS_IMsgServiceAdmin_i::Destroy(::CORBA::ULong InstanceID)
{
	BRUTUS_LOG_INF("Entering BRUTUS_IMsgServiceAdmin_i::Destroy()");

	::PortableServer::ObjectId_var oid;
	oid = poa_->servant_to_id(this);

	poa_->deactivate_object(oid);

	BRUTUS_LOG_INF("Leaving BRUTUS_IMsgServiceAdmin_i::Destroy()");
}
