ProviderUtil.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include <utility>
  19. #include <kopano/ECGetText.h>
  20. #include <kopano/memory.hpp>
  21. #include <mapi.h>
  22. #include <mapiutil.h>
  23. #include <mapispi.h>
  24. #include "ClientUtil.h"
  25. #include "Mem.h"
  26. #include <kopano/stringutil.h>
  27. #include <kopano/ECGuid.h>
  28. #include "ECABProvider.h"
  29. #include "ECMSProvider.h"
  30. #include "ECMsgStore.h"
  31. #include "ECArchiveAwareMsgStore.h"
  32. #include "ECMsgStorePublic.h"
  33. #include <kopano/charset/convstring.h>
  34. #include "DLLGlobal.h"
  35. #include "EntryPoint.h"
  36. #include "ProviderUtil.h"
  37. #include <kopano/charset/convert.h>
  38. using namespace std;
  39. using namespace KCHL;
  40. HRESULT CompareStoreIDs(ULONG cbEntryID1, LPENTRYID lpEntryID1, ULONG cbEntryID2, LPENTRYID lpEntryID2, ULONG ulFlags, ULONG *lpulResult)
  41. {
  42. HRESULT hr = hrSuccess;
  43. BOOL fTheSame = FALSE;
  44. PEID peid1 = (PEID)lpEntryID1;
  45. PEID peid2 = (PEID)lpEntryID2;
  46. if(lpEntryID1 == NULL || lpEntryID2 == NULL || lpulResult == NULL) {
  47. hr = MAPI_E_INVALID_PARAMETER;
  48. goto exit;
  49. }
  50. if (cbEntryID1 < (sizeof(GUID) + 4 + 4) || cbEntryID2 < (sizeof(GUID) + 4 + 4)) {
  51. hr = MAPI_E_INVALID_ENTRYID;
  52. goto exit;
  53. }
  54. if(memcmp(&peid1->guid, &peid2->guid, sizeof(GUID)) != 0)
  55. goto exit;
  56. if(peid1->ulVersion != peid2->ulVersion)
  57. goto exit;
  58. if(peid1->usType != peid2->usType)
  59. goto exit;
  60. if(peid1->ulVersion == 0) {
  61. if(cbEntryID1 < sizeof(EID_V0))
  62. goto exit;
  63. if( ((EID_V0*)lpEntryID1)->ulId != ((EID_V0*)lpEntryID2)->ulId )
  64. goto exit;
  65. }else {
  66. if(cbEntryID1 < CbNewEID(""))
  67. goto exit;
  68. if(peid1->uniqueId != peid2->uniqueId) //comp. with the old ulId
  69. goto exit;
  70. }
  71. fTheSame = TRUE;
  72. exit:
  73. if(lpulResult)
  74. *lpulResult = fTheSame;
  75. return hr;
  76. }
  77. HRESULT SetProviderMode(IMAPISupport *lpMAPISup, ECMapProvider* lpmapProvider, LPCSTR lpszProfileName, ULONG ulConnectType)
  78. {
  79. return hrSuccess;
  80. }
  81. HRESULT GetProviders(ECMapProvider* lpmapProvider, IMAPISupport *lpMAPISup, const char *lpszProfileName, ULONG ulFlags, PROVIDER_INFO* lpsProviderInfo)
  82. {
  83. HRESULT hr = hrSuccess;
  84. ECMapProvider::const_iterator iterProvider;
  85. PROVIDER_INFO sProviderInfo;
  86. object_ptr<ECMSProvider> lpECMSProvider;
  87. object_ptr<ECABProvider> lpECABProvider;
  88. sGlobalProfileProps sProfileProps;
  89. if (lpmapProvider == nullptr || lpMAPISup == nullptr ||
  90. lpszProfileName == nullptr || lpsProviderInfo == nullptr)
  91. return MAPI_E_INVALID_PARAMETER;
  92. iterProvider = lpmapProvider->find(lpszProfileName);
  93. if (iterProvider != lpmapProvider->cend()) {
  94. *lpsProviderInfo = iterProvider->second;
  95. return hrSuccess;
  96. }
  97. // Get the username and password from the profile settings
  98. hr = ClientUtil::GetGlobalProfileProperties(lpMAPISup, &sProfileProps);
  99. if(hr != hrSuccess)
  100. return hr;
  101. // Init providers
  102. // Message store online
  103. hr = ECMSProvider::Create(ulFlags, &~lpECMSProvider);
  104. if(hr != hrSuccess)
  105. return hr;
  106. // Addressbook online
  107. hr = ECABProvider::Create(&~lpECABProvider);
  108. if(hr != hrSuccess)
  109. return hr;
  110. // Fill in the Provider info struct
  111. //Init only the firsttime the flags
  112. sProviderInfo.ulProfileFlags = sProfileProps.ulProfileFlags;
  113. sProviderInfo.ulConnectType = CT_ONLINE;
  114. hr = lpECMSProvider->QueryInterface(IID_IMSProvider, (void **)&sProviderInfo.lpMSProviderOnline);
  115. if(hr != hrSuccess)
  116. return hr;
  117. hr = lpECABProvider->QueryInterface(IID_IABProvider, (void **)&sProviderInfo.lpABProviderOnline);
  118. if(hr != hrSuccess)
  119. return hr;
  120. //Add provider in map
  121. lpmapProvider->insert(std::map<string, PROVIDER_INFO>::value_type(lpszProfileName, sProviderInfo));
  122. *lpsProviderInfo = std::move(sProviderInfo);
  123. return hrSuccess;
  124. }
  125. // Create an anonymous message store, linked to transport and support object
  126. //
  127. // NOTE
  128. // Outlook will stay 'alive' when the user shuts down until the support
  129. // object is released, so we have to make sure that when the users has released
  130. // all the msgstore objects, we also release the support object.
  131. //
  132. HRESULT CreateMsgStoreObject(char * lpszProfname, LPMAPISUP lpMAPISup, ULONG cbEntryID, LPENTRYID lpEntryID, ULONG ulMsgFlags, ULONG ulProfileFlags, WSTransport* lpTransport,
  133. MAPIUID* lpguidMDBProvider, BOOL bSpooler, BOOL fIsDefaultStore, BOOL bOfflineStore,
  134. ECMsgStore** lppECMsgStore)
  135. {
  136. HRESULT hr = hrSuccess;
  137. BOOL fModify = FALSE;
  138. object_ptr<ECMsgStore> lpMsgStore;
  139. object_ptr<IECPropStorage> lpStorage;
  140. fModify = ulMsgFlags & MDB_WRITE || ulMsgFlags & MAPI_BEST_ACCESS; // FIXME check access at server
  141. if (CompareMDBProvider(lpguidMDBProvider, &KOPANO_STORE_PUBLIC_GUID) == TRUE)
  142. hr = ECMsgStorePublic::Create(lpszProfname, lpMAPISup, lpTransport, fModify, ulProfileFlags, bSpooler, bOfflineStore, &~lpMsgStore);
  143. else if (CompareMDBProvider(lpguidMDBProvider, &KOPANO_STORE_ARCHIVE_GUID) == TRUE)
  144. hr = ECMsgStore::Create(lpszProfname, lpMAPISup, lpTransport, fModify, ulProfileFlags, bSpooler, FALSE, bOfflineStore, &~lpMsgStore);
  145. else
  146. hr = ECArchiveAwareMsgStore::Create(lpszProfname, lpMAPISup, lpTransport, fModify, ulProfileFlags, bSpooler, fIsDefaultStore, bOfflineStore, &~lpMsgStore);
  147. if (hr != hrSuccess)
  148. return hr;
  149. memcpy(&lpMsgStore->m_guidMDB_Provider, lpguidMDBProvider,sizeof(MAPIUID));
  150. // Get a propstorage for the message store
  151. hr = lpTransport->HrOpenPropStorage(0, nullptr, cbEntryID, lpEntryID, 0, &~lpStorage);
  152. if (hr != hrSuccess)
  153. return hr;
  154. // Set up the message store to use this storage
  155. hr = lpMsgStore->HrSetPropStorage(lpStorage, FALSE);
  156. if (hr != hrSuccess)
  157. return hr;
  158. // Setup callback for session change
  159. hr = lpTransport->AddSessionReloadCallback(lpMsgStore, ECMsgStore::Reload, NULL);
  160. if (hr != hrSuccess)
  161. return hr;
  162. hr = lpMsgStore->SetEntryId(cbEntryID, lpEntryID);
  163. if (hr != hrSuccess)
  164. return hr;
  165. return lpMsgStore->QueryInterface(IID_ECMsgStore,
  166. reinterpret_cast<void **>(lppECMsgStore));
  167. }
  168. HRESULT GetTransportToNamedServer(WSTransport *lpTransport, LPCTSTR lpszServerName, ULONG ulFlags, WSTransport **lppTransport)
  169. {
  170. HRESULT hr;
  171. utf8string strServerName;
  172. utf8string strPseudoUrl = utf8string::from_string("pseudo://");
  173. char *lpszServerPath = NULL;
  174. bool bIsPeer = false;
  175. WSTransport *lpNewTransport = NULL;
  176. if (lpszServerName == NULL || lpTransport == NULL || lppTransport == NULL)
  177. return MAPI_E_INVALID_PARAMETER;
  178. if ((ulFlags & ~MAPI_UNICODE) != 0)
  179. return MAPI_E_UNKNOWN_FLAGS;
  180. strServerName = convstring(lpszServerName, ulFlags);
  181. strPseudoUrl.append(strServerName);
  182. hr = lpTransport->HrResolvePseudoUrl(strPseudoUrl.c_str(), &lpszServerPath, &bIsPeer);
  183. if (hr != hrSuccess)
  184. return hr;
  185. if (bIsPeer) {
  186. lpNewTransport = lpTransport;
  187. lpNewTransport->AddRef();
  188. } else {
  189. hr = lpTransport->CreateAndLogonAlternate(lpszServerPath, &lpNewTransport);
  190. if (hr != hrSuccess)
  191. return hr;
  192. }
  193. *lppTransport = lpNewTransport;
  194. return hrSuccess;
  195. }