/** * Checks in the ECStatsTable PR_EC_STATSTABLE_USERS for quota * information per connected server given in lpAdminStore. * * @param[in] cUsers number of users in lpsUserList * @param[in] lpsUserList array of ECUser struct, containing all Zarafa from all companies, on any server * @param[in] lpecCompany same company struct as in ECQuotaMonitor::CheckCompanyQuota() * @param[in] lpAdminStore IMsgStore of SYSTEM user on a specific server instance. * @return hrSuccess or any MAPI error code. */ HRESULT ECQuotaMonitor::CheckServerQuota(ULONG cUsers, LPECUSER lpsUserList, LPECCOMPANY lpecCompany, LPMDB lpAdminStore) { HRESULT hr = hrSuccess; LPSRestriction lpsRestriction = NULL; SPropValue sRestrictProp; LPMAPITABLE lpTable = NULL; LPSRowSet lpRowSet = NULL; ECQUOTASTATUS sQuotaStatus; ULONG i, u; SizedSPropTagArray(5, sCols) = { 5, { PR_EC_USERNAME_A, PR_MESSAGE_SIZE_EXTENDED, PR_QUOTA_WARNING_THRESHOLD, PR_QUOTA_SEND_THRESHOLD, PR_QUOTA_RECEIVE_THRESHOLD, } }; hr = lpAdminStore->OpenProperty(PR_EC_STATSTABLE_USERS, &IID_IMAPITable, 0, 0, (LPUNKNOWN*)&lpTable); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to open stats table for quota sizes, error 0x%08X", hr); goto exit; } hr = lpTable->SetColumns((LPSPropTagArray)&sCols, MAPI_DEFERRED_ERRORS); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to set columns on stats table for quota sizes, error 0x%08X", hr); goto exit; } if (lpecCompany->sCompanyId.cb != 0 && lpecCompany->sCompanyId.lpb != NULL) { sRestrictProp.ulPropTag = PR_EC_COMPANY_NAME_A; sRestrictProp.Value.lpszA = (char*)lpecCompany->lpszCompanyname; CREATE_RESTRICTION(lpsRestriction); CREATE_RES_OR(lpsRestriction, lpsRestriction, 2); CREATE_RES_NOT(lpsRestriction, &lpsRestriction->res.resOr.lpRes[0]); DATA_RES_EXIST(lpsRestriction, lpsRestriction->res.resOr.lpRes[0].res.resNot.lpRes[0], PR_EC_COMPANY_NAME_A); DATA_RES_PROPERTY(lpsRestriction, lpsRestriction->res.resOr.lpRes[1], RELOP_EQ, PR_EC_COMPANY_NAME_A, &sRestrictProp); hr = lpTable->Restrict(lpsRestriction, MAPI_DEFERRED_ERRORS); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to restrict stats table, error 0x%08X", hr); goto exit; } } while (TRUE) { hr = lpTable->QueryRows(50, 0, &lpRowSet); if (hr != hrSuccess) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Unable to receive stats table data, error 0x%08X", hr); goto exit; } if (lpRowSet->cRows == 0) break; for (i = 0; i < lpRowSet->cRows; i++) { LPSPropValue lpUsername = NULL; LPSPropValue lpStoreSize = NULL; LPSPropValue lpQuotaWarn = NULL; LPSPropValue lpQuotaSoft = NULL; LPSPropValue lpQuotaHard = NULL; MsgStorePtr ptrStore; lpUsername = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_EC_USERNAME_A); lpStoreSize = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_MESSAGE_SIZE_EXTENDED); lpQuotaWarn = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_WARNING_THRESHOLD); lpQuotaSoft = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_SEND_THRESHOLD); lpQuotaHard = PpropFindProp(lpRowSet->aRow[i].lpProps, lpRowSet->aRow[i].cValues, PR_QUOTA_RECEIVE_THRESHOLD); if (!lpUsername || !lpStoreSize) continue; // don't log error: could be for several valid reasons (contacts, other server, etc) if (lpStoreSize->Value.li.QuadPart == 0) continue; m_ulProcessed++; memset(&sQuotaStatus, 0, sizeof(ECQUOTASTATUS)); sQuotaStatus.llStoreSize = lpStoreSize->Value.li.QuadPart; sQuotaStatus.quotaStatus = QUOTA_OK; if (lpQuotaHard && lpQuotaHard->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaHard->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_HARDLIMIT; else if (lpQuotaSoft && lpQuotaSoft->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaSoft->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_SOFTLIMIT; else if (lpQuotaWarn && lpQuotaWarn->Value.ul > 0 && lpStoreSize->Value.li.QuadPart > ((long long)lpQuotaWarn->Value.ul * 1024)) sQuotaStatus.quotaStatus = QUOTA_WARN; if (sQuotaStatus.quotaStatus == QUOTA_OK) continue; m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_FATAL, "Mailbox of user %s has exceeded its %s limit", lpUsername->Value.lpszA, sQuotaStatus.quotaStatus == QUOTA_WARN ? "warning" : sQuotaStatus.quotaStatus == QUOTA_SOFTLIMIT ? "soft" : "hard"); // find the user in the full users list for (u = 0; u < cUsers; u++) { if (strcmp((char*)lpsUserList[u].lpszUsername, lpUsername->Value.lpszA) == 0) break; } if (u == cUsers) { m_lpThreadMonitor->lpLogger->Log(EC_LOGLEVEL_ERROR, "Unable to find user %s in userlist", lpUsername->Value.lpszA); m_ulFailed++; continue; } hr = OpenUserStore(lpsUserList[u].lpszUsername, &ptrStore); if (hr != hrSuccess) { hr = hrSuccess; continue; } hr = Notify(&lpsUserList[u], lpecCompany, &sQuotaStatus, ptrStore); if (hr != hrSuccess) m_ulFailed++; } if (lpRowSet) FreeProws(lpRowSet); lpRowSet = NULL; } exit: if (lpRowSet) FreeProws(lpRowSet); if (lpsRestriction) MAPIFreeBuffer(lpsRestriction); if (lpTable) lpTable->Release(); return hr; }