HRESULT GetShortcutFolder(LPMAPISESSION lpSession, LPTSTR lpszFolderName, LPTSTR lpszFolderComment, ULONG ulFlags, LPMAPIFOLDER* lppShortcutFolder) { HRESULT hr = hrSuccess; LPSPropValue lpPropValue = NULL; IMsgStore *lpMsgStore = NULL; IMAPIFolder *lpFolder = NULL; ULONG ulObjType = 0; hr = HrOpenDefaultStore(lpSession, &lpMsgStore); if(hr != hrSuccess) goto exit; // Get shortcut entryid hr = HrGetOneProp(lpMsgStore, PR_IPM_FAVORITES_ENTRYID, &lpPropValue); if(hr != hrSuccess) { if(hr == MAPI_E_NOT_FOUND && (ulFlags&MAPI_CREATE)) { // Propety not found, re-create the shortcut folder hr = CreateShortcutFolder(lpMsgStore, lpszFolderName, lpszFolderComment, ulFlags & MAPI_UNICODE, lppShortcutFolder); } goto exit; } // Open Shortcut folder hr = lpMsgStore->OpenEntry(lpPropValue->Value.bin.cb, (LPENTRYID)lpPropValue->Value.bin.lpb, &IID_IMAPIFolder, MAPI_BEST_ACCESS, &ulObjType, (LPUNKNOWN *)&lpFolder); if (hr != hrSuccess) { if(hr == MAPI_E_NOT_FOUND && (ulFlags&MAPI_CREATE)) { // Folder not found, re-create the shortcut folder hr = CreateShortcutFolder(lpMsgStore, lpszFolderName, lpszFolderComment, ulFlags & MAPI_UNICODE, lppShortcutFolder); } goto exit; } hr = lpFolder->QueryInterface(IID_IMAPIFolder, (void**)lppShortcutFolder); if (hr != hrSuccess) goto exit; exit: if (lpPropValue) MAPIFreeBuffer(lpPropValue); if(lpFolder) lpFolder->Release(); if(lpMsgStore) lpMsgStore->Release(); return hr; }
/** * Opens the IECSpooler object on an admin session. * * @param[in] lpAdminSession MAPI Session of the Zarafa SYSTEM user * @param[out] lppSpooler IECSpooler is a Zarafa interface to the outgoing queue functions. * @return HRESULT */ HRESULT GetAdminSpooler(IMAPISession *lpAdminSession, IECSpooler **lppSpooler) { HRESULT hr = hrSuccess; IECSpooler *lpSpooler = NULL; IMsgStore *lpMDB = NULL; SPropValue *lpsProp = NULL; hr = HrOpenDefaultStore(lpAdminSession, &lpMDB); if (hr != hrSuccess) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Unable to open default store for system account. Error 0x%08X", hr); goto exit; } hr = HrGetOneProp(lpMDB, PR_EC_OBJECT, &lpsProp); if (hr != hrSuccess) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Unable to get Zarafa internal object"); goto exit; } hr = ((IECUnknown *)lpsProp->Value.lpszA)->QueryInterface(IID_IECSpooler, (void **)&lpSpooler); if (hr != hrSuccess) { g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Spooler interface not supported"); goto exit; } *lppSpooler = lpSpooler; exit: if (lpMDB) lpMDB->Release(); if (lpsProp) MAPIFreeBuffer(lpsProp); return hr; }
/** * Cleans finished messages. Normally only prints a logmessage. If the * mailer completely failed (eg. segfault), this function will try to * remove the faulty mail from the queue. * * @param[in] lpAdminSession MAPI session of the Zarafa SYSTEM user * @param[in] lpSpooler IECSpooler object * @return HRESULT */ HRESULT CleanFinishedMessages(IMAPISession *lpAdminSession, IECSpooler *lpSpooler) { HRESULT hr = hrSuccess; map<pid_t, int>::iterator i, iDel; SendData sSendData; bool bErrorMail; map<pid_t, int> finished; // exit status of finished processes int status; // error message creation IAddrBook *lpAddrBook = NULL; ECSender *lpMailer = NULL; LPECUSER lpUserAdmin = NULL; // user error message, release after using IMsgStore *lpUserStore = NULL; IMessage *lpMessage = NULL; pthread_mutex_lock(&hMutexFinished); if (mapFinished.empty()) { pthread_mutex_unlock(&hMutexFinished); return hr; } // copy map contents and clear it, so hMutexFinished can be unlocked again asap finished = mapFinished; mapFinished.clear(); pthread_mutex_unlock(&hMutexFinished); g_lpLogger->Log(EC_LOGLEVEL_DEBUG, "Cleaning %d messages from queue", (int)finished.size()); // process finished entries for (i = finished.begin(); i != finished.end(); i++) { sSendData = mapSendData[i->first]; /* Find exit status, and decide to remove mail from queue or not */ status = i->second; bErrorMail = false; #ifdef WEXITSTATUS if(WIFEXITED(status)) { /* Child exited by itself */ if (WEXITSTATUS(status) == EXIT_WAIT) { // timed message, try again later g_lpLogger->Log(EC_LOGLEVEL_INFO, "Message for user %ls will be tried again later", sSendData.strUsername.c_str()); } else if (WEXITSTATUS(status) == EXIT_OK || WEXITSTATUS(status) == EXIT_FAILED) { // message was sent, or the user already received an error mail. g_lpLogger->Log(EC_LOGLEVEL_INFO, "Processed message for user %ls", sSendData.strUsername.c_str()); } else { // message was not sent, and could not be removed from queue. Notify user also. bErrorMail = true; g_lpLogger->Log(EC_LOGLEVEL_WARNING, "Failed message for user %ls will be removed from queue, error 0x%x", sSendData.strUsername.c_str(), status); } } else if(WIFSIGNALED(status)) { /* Child was killed by a signal */ bErrorMail = true; g_lpLogger->Log(EC_LOGLEVEL_NOTICE, "Spooler process %d was killed by signal %d", i->first, WTERMSIG(status)); g_lpLogger->Log(EC_LOGLEVEL_WARNING, "Message for user %ls will be removed from queue", sSendData.strUsername.c_str()); } else { /* Something strange happened */ bErrorMail = true; g_lpLogger->Log(EC_LOGLEVEL_NOTICE, "Spooler process %d terminated abnormally", i->first); g_lpLogger->Log(EC_LOGLEVEL_WARNING, "Message for user %ls will be removed from queue", sSendData.strUsername.c_str()); } #else if (status) { bErrorMail = true; g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Spooler process %d exited with status %d", i->first, status); } #endif if (bErrorMail) { hr = GetErrorObjects(sSendData, lpAdminSession, &lpAddrBook, &lpMailer, &lpUserAdmin, &lpUserStore, &lpMessage); if (hr == hrSuccess) { lpMailer->setError(_("A fatal error occurred while processing your message, and Zarafa is unable to send your email.")); hr = SendUndeliverable(lpAddrBook, lpMailer, lpUserStore, lpUserAdmin, lpMessage); // TODO: if failed, and we have the lpUserStore, create message? } if (hr != hrSuccess) g_lpLogger->Log(EC_LOGLEVEL_WARNING, "Failed to create error message for user %ls", sSendData.strUsername.c_str()); // remove mail from queue hr = lpSpooler->DeleteFromMasterOutgoingTable(sSendData.cbMessageEntryId, (LPENTRYID)sSendData.lpMessageEntryId, sSendData.ulFlags); if (hr != hrSuccess) g_lpLogger->Log(EC_LOGLEVEL_WARNING, "Could not remove invalid message from queue, error code: 0x%08X", hr); // move mail to sent items folder if (sSendData.ulFlags & EC_SUBMIT_DOSENTMAIL && lpMessage) { hr = DoSentMail(lpAdminSession, lpUserStore, 0, lpMessage); lpMessage = NULL; if (hr != hrSuccess) g_lpLogger->Log(EC_LOGLEVEL_ERROR, "Unable to move sent mail to sent-items folder"); } if (lpUserStore) { lpUserStore->Release(); lpUserStore = NULL; } if (lpMessage) { lpMessage->Release(); lpMessage = NULL; } } MAPIFreeBuffer(sSendData.lpStoreEntryId); MAPIFreeBuffer(sSendData.lpMessageEntryId); mapSendData.erase(i->first); } if (lpAddrBook) lpAddrBook->Release(); delete lpMailer; if (lpUserAdmin) MAPIFreeBuffer(lpUserAdmin); if (lpUserStore) lpUserStore->Release(); if (lpMessage) lpMessage->Release(); return hr; }
bool MAPIStorageAdviser::AdviseAll() { IMAPISession* pSession = InitIMAPISession(); IMAPITable* pStoresTable = GetStoresTable(pSession); SizedSPropTagArray(2, tblColumns) = {2, {PR_DISPLAY_NAME, PR_ENTRYID}}; pStoresTable->SetColumns((LPSPropTagArray)&tblColumns, 0); for(;;) { SRowSet * pRowSet = NULL; pStoresTable->QueryRows(1, 0, &pRowSet); if(pRowSet->cRows != 1) break; ASSERT(pRowSet->aRow[0].cValues == tblColumns.cValues); SPropValue* pVal = pRowSet->aRow[0].lpProps; ASSERT(pVal[0].ulPropTag == PR_DISPLAY_NAME); ASSERT(pVal[1].ulPropTag == PR_ENTRYID); LPWSTR lpStoreName = pRowSet->aRow[0].lpProps[0].Value.lpszW; // Open Store LPBYTE pEntry = (LPBYTE)pRowSet->aRow[0].lpProps[1].Value.bin.lpb; ULONG ulStoreBytes = pRowSet->aRow[0].lpProps[1].Value.bin.cb; IMsgStore* pStore = _GetStoreFromEntryID(pSession, ulStoreBytes, pEntry); if (pStore == NULL) { continue; } if (AddSink(pStore) == true) { }else{ } pStore->Release(); FreeProws(pRowSet); } pStoresTable->Release(); pSession->Release(); return true; }