STDMETHODIMP 
InterfaceSSLCertificate::Save()
{
   try
   {
      if (!m_pObject)
         return GetAccessDenied();

      if (!m_pAuthentication->GetIsServerAdmin())
         return m_pAuthentication->GetAccessDenied();
   
      if (HM::PersistentSSLCertificate::SaveObject(m_pObject))
      {
         // Add to parent collection
         AddToParentCollection();
      }
   
      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP 
InterfaceWhiteListAddress::Save()
{
   try
   {
      if (!object_)
         return GetAccessDenied();

      if (!authentication_->GetIsServerAdmin())
         return authentication_->GetAccessDenied();
   
      if (HM::PersistentWhiteListAddress::SaveObject(object_))
      {
         // Add to parent collection
         AddToParentCollection();
      }
   
      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP InterfaceAntiVirus::get_BlockedAttachments(IInterfaceBlockedAttachments **pVal)
{
   try
   {
      if (!GetIsServerAdmin())
         return GetAccessDenied();

      CComObject<InterfaceBlockedAttachments>* pInterface = new CComObject<InterfaceBlockedAttachments>;
      pInterface->SetAuthentication(authentication_);
   
      shared_ptr<HM::BlockedAttachments> pBlockedAttachments = HM::Configuration::Instance()->GetBlockedAttachments();
   
      pInterface->Attach(pBlockedAttachments);
      pInterface->AddRef();
   
      *pVal = pInterface;
   
      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP InterfaceAntiVirus::get_Action(eAntivirusAction *pVal)
{
   try
   {
      if (!GetIsServerAdmin())
         return GetAccessDenied();

      switch (antiVirusConfiguration_.AVAction())
      {
      case HM::AntiVirusConfiguration::ActionDelete:
         *pVal = hDeleteEmail;
         break;
      case HM::AntiVirusConfiguration::ActionStripAttachments:
         *pVal = hDeleteAttachments;
         break;
      }
   
      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP InterfaceDatabase::CreateExternalDatabase(eDBtype ServerType, BSTR ServerName, long lPort, BSTR DatabaseName, BSTR Username, BSTR Password)
{
   try
   {
      if (!config_)
         return GetAccessDenied();

      if (!GetIsServerAdmin())
         return GetAccessDenied();
   
      const HM::String sEmpty;
      const HM::String sServerName = ServerName;
      const HM::String sDatabaseName = DatabaseName;
      const HM::String sUsername = Username;
      const HM::String sPassword = Password;
   
      if (sDatabaseName.Find(_T(" ")) >= 0)
         return COMError::GenerateError("The database name may not contain spaces.");
   
      // Create a settings object for the connection ...
      std::shared_ptr<HM::DatabaseSettings> pSettings = std::shared_ptr<HM::DatabaseSettings>(
         new HM::DatabaseSettings(sServerName, sEmpty, sUsername, sPassword, sEmpty, sEmpty,(HM::DatabaseSettings::SQLDBType) ServerType, lPort));
   
      // Connect to the database serve   
      std::shared_ptr<HM::DALConnection> pConn = HM::DALConnectionFactory::CreateConnection(pSettings);
   
      HM::String sErrorMessage;
      if (pConn->Connect(sErrorMessage) != HM::DALConnection::Connected)
         return COMError::GenerateError(sErrorMessage);
   
      // Create the database
      HM::String sCreateDB = HM::SQLStatement::GetCreateDatabase(pSettings, sDatabaseName);
   
      if (!pConn->Execute(HM::SQLCommand(sCreateDB), sErrorMessage, 0, 0))
         return COMError::GenerateError(sErrorMessage);
   
      // Disconnect again.
      pConn->Disconnect();
   
      // Create a new settings object where we specify the database name as well.
      pSettings = std::shared_ptr<HM::DatabaseSettings>(
         new HM::DatabaseSettings(sServerName, sDatabaseName, sUsername, sPassword, sEmpty, sEmpty,(HM::DatabaseSettings::SQLDBType) ServerType, lPort));
   
      // Reconnect to the new database.
      pConn = HM::DALConnectionFactory::CreateConnection(pSettings);
      if (pConn->Connect(sErrorMessage) != HM::DALConnection::Connected)
         return COMError::GenerateError(sErrorMessage);
   
      // Run the scripts
      HM::SQLScriptRunner scriptRunner;
      if (!scriptRunner.ExecuteScript(pConn, pSettings->GetDefaultScript(), sErrorMessage))
         return COMError::GenerateError(sErrorMessage);
   
      ini_file_settings_->SetDatabaseDirectory("");
      ini_file_settings_->SetDatabaseType((HM::DatabaseSettings::SQLDBType) ServerType);
      ini_file_settings_->SetUsername(sUsername);
      ini_file_settings_->SetPassword(sPassword);
      ini_file_settings_->SetDatabasePort(lPort);
      ini_file_settings_->SetDatabaseServer(sServerName);
      ini_file_settings_->SetDatabaseName(sDatabaseName);
      ini_file_settings_->SetIsInternalDatabase(false);
   
      return S_OK;   
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP InterfaceDatabase::CreateInternalDatabase()
{
   try
   {
      if (!config_)
         return GetAccessDenied();

   	if (!GetIsServerAdmin())
         return GetAccessDenied();
   
      // Make sure we have the latest settings.
      ini_file_settings_->LoadSettings();
   
      HM::String sDirectory = ini_file_settings_->GetDatabaseDirectory();
      HM::String sDatabaseName = "hMailServer";
      HM::String sPassword = HM::PasswordGenerator::Generate();
   
      HM::String sErrorMessage;
      if (!HM::SQLCEConnection::CreateDatabase(sDirectory, sDatabaseName, sPassword, sErrorMessage))
         return COMError::GenerateError(sErrorMessage);
   
      HM::String sEmpty;
   
      // Create a settings object which we use to connect to the server.
      std::shared_ptr<HM::DatabaseSettings> pSettings = std::shared_ptr<HM::DatabaseSettings>(
         new HM::DatabaseSettings(sEmpty, sDatabaseName, sEmpty, sPassword, sDirectory, sEmpty, HM::DatabaseSettings::TypeMSSQLCompactEdition, 0));
   
      // Connect to the new database
      std::shared_ptr<HM::DALConnection> pConn = HM::DALConnectionFactory::CreateConnection(pSettings);
   
      if (pConn->Connect(sErrorMessage) != HM::DALConnection::Connected)
      {
         return COMError::GenerateError(sErrorMessage);
      }
   
      // Create the tables
      HM::SQLScriptRunner scriptRunner;
      if (!scriptRunner.ExecuteScript(pConn, pSettings->GetDefaultScript(), sErrorMessage))
      {
         return COMError::GenerateError(sErrorMessage);
      }
   
      ini_file_settings_->SetDatabaseDirectory(sDirectory);
      ini_file_settings_->SetDatabaseType(HM::DatabaseSettings::TypeMSSQLCompactEdition);
      ini_file_settings_->SetUsername("");
      ini_file_settings_->SetPassword(sPassword);
      ini_file_settings_->SetDatabasePort(0);
      ini_file_settings_->SetDatabaseServer("");
      ini_file_settings_->SetDatabaseName(sDatabaseName);
      ini_file_settings_->SetIsInternalDatabase(true);
   
      return S_OK;   
   }
   catch (_com_error &err)
   {
      _bstr_t bstrSource(err.Source());
      _bstr_t bstrDescription(err.Description());

      LPCSTR lpcSource = bstrSource;
      HM::String sErrSource = lpcSource;

      LPCSTR lpcDesc = bstrDescription;
      HM::String sErrDesc = lpcDesc;

      return COMError::GenerateGenericMessage();
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
STDMETHODIMP InterfaceMessages::DeleteByDBID(hyper lDBID)
{
   try
   {
      if (!messages_)
         return GetAccessDenied();

      std::shared_ptr<HM::Message> pMsg = messages_->GetItemByDBID(lDBID);

      if (!pMsg)
      {
         // No such message exists
         return DISP_E_BADINDEX;
      }

      // Expunge the mailbox. Will cause the message to be
      // deleted from disk and database.
      std::function<bool(int, std::shared_ptr<HM::Message>)> filter = [lDBID](int index, std::shared_ptr<HM::Message> message)
      {
         if (message->GetID() == lDBID)
         {
            return true;
         }

         return false;
      };

      messages_->DeleteMessages(filter);

      // If we're aren't browsing in the message cache already, 
      // we need to delete the message from the cache now. This
      // is needed if the messages are accessed using the
      // Account.Messages property. When messages are accessed
      // via Account.IMAPFolders, we access the message cache
      // directly, and when we don't need to remove message here.
      // (Since it was done like 10 lines up).

      __int64 iFolderID = messages_->GetFolderID();
      if (iFolderID == -1)
      {
         // We're not browsing the message cache.
         __int64 iAccountID = messages_->GetAccountID();


         std::vector<__int64> affectedMessages;
         affectedMessages.push_back(lDBID);

         // Notify clients that the message has been dropped.
         std::shared_ptr<HM::ChangeNotification> notification =
            std::shared_ptr<HM::ChangeNotification>(new HM::ChangeNotification(messages_->GetAccountID(), messages_->GetFolderID(), HM::ChangeNotification::NotificationMessageDeleted, affectedMessages));

         HM::Application::Instance()->GetNotificationServer()->SendNotification(notification);
      }

      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}
Example #8
0
STDMETHODIMP InterfaceMessage::Save()
{
   try
   {
      if (!m_pObject)
         return GetAccessDenied();

      // Check that the message has a valid date header.
      HM::String sDate = _GetMessageData()->GetSentTime();
      if (sDate.IsEmpty())
      {
         // Date was not specified. Specify it now.
         sDate = HM::Time::GetCurrentMimeDate();
         _GetMessageData()->SetSentTime(sDate);
      }
   
      shared_ptr<const HM::Account> account;
   
      if (m_pObject->GetAccountID() > 0)
      {
         account = HM::CacheContainer::Instance()->GetAccount(m_pObject->GetAccountID());
      }
   
      // Save the message to disk.
      const HM::String fileName = HM::PersistentMessage::GetFileName(account, m_pObject);
   
      if (!_GetMessageData()->Write(fileName))
      {
         return COMError::GenerateError("Unable to write to message file.");
      }
   
      // A message can be in a number of different states:
      // Case 1) New message which should be delivered -> Save in file and add to database
      // Case 2) New message which should be added to an existing IMAP folder -> Update message file and save to database// 
      // case 3) Existing message which is being delivered. -> Only update the message fil
      // Case 4) Existing message in IMAP folder which should just be re-saved -> Update message file
   
      HM::Message::State state = m_pObject->GetState();
   
      switch (state)
      {
      case HM::Message::Created:
         {
            // Handle new message. It can either be Case 1 or Case 2. If the message is already
            // connected to an account, it means that it should be stored in a specific IMAP folder
            if (m_pObject->GetFolderID() == 0 && m_pObject->GetAccountID() == 0)
            {
               // Case 1: The message should be delivered. Change the state to delivering
               m_pObject->SetState(HM::Message::Delivering);
   
               if (!HM::PersistentMessage::SaveObject(m_pObject))
               {
                  return COMError::GenerateError("Message could not be saved in database.");
               }
   
               HM::Application::Instance()->SubmitPendingEmail();
            }  
            else
            {
               // Case 2. It's a new message but it should be added to an existing IMAP folder.
               m_pObject->SetState(HM::Message::Delivered);
               return _SaveNewMessageToIMAPFolder();
            }
   
            break;
         }
      case HM::Message::Delivering:
         {
            // Handle message which is being delivered. Saving in database will be taken
            // care about by the delivery process. Since the file has already been updated
            // on disk, there's not more for us to do here.
            break;
         }
      case HM::Message::Delivered:
         {
            // The message has already been delivered. It's placed inside an account mailbox.
            // All we need to do is to update it in the database.
            if (!HM::PersistentMessage::SaveObject(m_pObject))
               return S_FALSE;
   
            break;
         }
      default:
         {
            // Unhandled case.
            return COMError::GenerateError("The message could not be saevd. It is in an unknown state.");
         }
      }
      
      return S_OK;
   }
   catch (...)
   {
      return COMError::GenerateGenericMessage();
   }
}