PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/MAPIProfileFunctions.cpp

#
C++ | 1092 lines | 831 code | 191 blank | 70 comment | 119 complexity | 84e0c42221025ef38f9d9ff41972ab11 MD5 | raw file
  1. // MAPIProfileFunctions.cpp : Collection of useful MAPI functions
  2. #include "stdafx.h"
  3. #include "MAPIProfileFunctions.h"
  4. #include "ImportProcs.h"
  5. #include "Editor.h"
  6. #include "MAPIFunctions.h"
  7. #include "ExtraPropTags.h"
  8. #include "Guids.h"
  9. #ifndef MRMAPI
  10. // This declaration is missing from the MAPI headers
  11. STDAPI STDAPICALLTYPE LaunchWizard(HWND hParentWnd,
  12. ULONG ulFlags,
  13. LPCSTR* lppszServiceNameToAdd,
  14. ULONG cchBufferMax,
  15. _Out_cap_(cchBufferMax) LPSTR lpszNewProfileName);
  16. void LaunchProfileWizard(
  17. _In_ HWND hParentWnd,
  18. ULONG ulFlags,
  19. _In_z_ LPCSTR* lppszServiceNameToAdd,
  20. ULONG cchBufferMax,
  21. _Out_cap_(cchBufferMax) LPSTR lpszNewProfileName)
  22. {
  23. HRESULT hRes = S_OK;
  24. DebugPrint(DBGGeneric, L"LaunchProfileWizard: Using LAUNCHWIZARDENTRY to launch wizard API.\n");
  25. // Call LaunchWizard to add the service.
  26. WC_MAPI(LaunchWizard(
  27. hParentWnd,
  28. ulFlags,
  29. lppszServiceNameToAdd,
  30. cchBufferMax,
  31. lpszNewProfileName));
  32. if (MAPI_E_CALL_FAILED == hRes)
  33. {
  34. CHECKHRESMSG(hRes, IDS_LAUNCHWIZARDFAILED);
  35. }
  36. else CHECKHRES(hRes);
  37. if (SUCCEEDED(hRes))
  38. {
  39. DebugPrint(DBGGeneric, L"LaunchProfileWizard: Profile \"%hs\" configured.\n", lpszNewProfileName);
  40. }
  41. } // LaunchProfileWizard
  42. void DisplayMAPISVCPath(_In_ CWnd* pParentWnd)
  43. {
  44. HRESULT hRes = S_OK;
  45. TCHAR szServicesIni[MAX_PATH + 12] = { 0 }; // 12 = space for 'MAPISVC.INF'
  46. DebugPrint(DBGGeneric, L"DisplayMAPISVCPath()\n");
  47. GetMAPISVCPath(szServicesIni, _countof(szServicesIni));
  48. CEditor MyData(
  49. pParentWnd,
  50. IDS_MAPISVCTITLE,
  51. IDS_MAPISVCTEXT,
  52. 1,
  53. CEDITOR_BUTTON_OK);
  54. MyData.InitPane(0, CreateSingleLinePane(IDS_FILEPATH, NULL, true));
  55. MyData.SetString(0, szServicesIni);
  56. WC_H(MyData.DisplayDialog());
  57. } // DisplayMAPISVCPath
  58. ///////////////////////////////////////////////////////////////////////////////
  59. // Function name : GetMAPISVCPath
  60. // Description : This will get the correct path to the MAPISVC.INF file.
  61. // Return type : void
  62. // Argument : LPTSTR szMAPIDir - Buffer to hold the path to the MAPISVC file.
  63. // ULONG cchMAPIDir - size of the buffer
  64. void GetMAPISVCPath(_Inout_z_count_(cchMAPIDir) LPTSTR szMAPIDir, ULONG cchMAPIDir)
  65. {
  66. HRESULT hRes = S_OK;
  67. GetMAPIPath(_T("Microsoft Outlook"), szMAPIDir, cchMAPIDir); // STRING_OK
  68. // We got the path to MAPI - need to strip it
  69. if (szMAPIDir[0])
  70. {
  71. LPTSTR lpszSlash = NULL;
  72. LPTSTR lpszCur = szMAPIDir;
  73. for (lpszSlash = lpszCur; *lpszCur; lpszCur = lpszCur++)
  74. {
  75. if (*lpszCur == _T('\\')) lpszSlash = lpszCur;
  76. }
  77. *lpszSlash = _T('\0');
  78. }
  79. else
  80. {
  81. // Fall back on System32
  82. UINT cchSystemDir = 0;
  83. TCHAR szSystemDir[MAX_PATH] = { 0 };
  84. EC_D(cchSystemDir, GetSystemDirectory(szSystemDir, _countof(szSystemDir)));
  85. if (cchSystemDir < _countof(szSystemDir))
  86. {
  87. EC_H(StringCchCopy(szMAPIDir, cchMAPIDir, szSystemDir));
  88. }
  89. }
  90. if (SUCCEEDED(hRes) && szMAPIDir[0])
  91. {
  92. EC_H(StringCchPrintf(
  93. szMAPIDir,
  94. cchMAPIDir,
  95. _T("%s\\%s"), // STRING_OK
  96. szMAPIDir,
  97. _T("MAPISVC.INF"))); // STRING_OK
  98. }
  99. } // GetMAPISVCPath
  100. struct SERVICESINIREC
  101. {
  102. LPTSTR lpszSection;
  103. LPTSTR lpszKey;
  104. ULONG ulKey;
  105. LPTSTR lpszValue;
  106. };
  107. static SERVICESINIREC aEMSServicesIni[] =
  108. {
  109. { _T("Default Services"), _T("MSEMS"), 0L, _T("Microsoft Exchange Server") }, // STRING_OK
  110. { _T("Services"), _T("MSEMS"), 0L, _T("Microsoft Exchange Server") }, // STRING_OK
  111. { _T("MSEMS"), _T("PR_DISPLAY_NAME"), 0L, _T("Microsoft Exchange Server") }, // STRING_OK
  112. { _T("MSEMS"), _T("Sections"), 0L, _T("MSEMS_MSMail_Section") }, // STRING_OK
  113. { _T("MSEMS"), _T("PR_SERVICE_DLL_NAME"), 0L, _T("emsui.dll") }, // STRING_OK
  114. { _T("MSEMS"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  115. { _T("MSEMS"), _T("PR_SERVICE_ENTRY_NAME"), 0L, _T("EMSCfg") }, // STRING_OK
  116. { _T("MSEMS"), _T("PR_RESOURCE_FLAGS"), 0L, _T("SERVICE_SINGLE_COPY") }, // STRING_OK
  117. { _T("MSEMS"), _T("WIZARD_ENTRY_NAME"), 0L, _T("EMSWizardEntry") }, // STRING_OK
  118. { _T("MSEMS"), _T("Providers"), 0L, _T("EMS_DSA, EMS_MDB_public, EMS_MDB_private, EMS_RXP, EMS_MSX, EMS_Hook") }, // STRING_OK
  119. { _T("MSEMS"), _T("PR_SERVICE_SUPPORT_FILES"), 0L, _T("emsui.dll,emsabp.dll,emsmdb.dll") }, // STRING_OK
  120. { _T("EMS_MDB_public"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_STORE_PROVIDER") }, // STRING_OK
  121. { _T("EMS_MDB_public"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSMDB.DLL") }, // STRING_OK
  122. { _T("EMS_MDB_public"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  123. { _T("EMS_MDB_public"), _T("PR_RESOURCE_FLAGS"), 0L, _T("STATUS_NO_DEFAULT_STORE") }, // STRING_OK
  124. { _T("EMS_MDB_public"), NULL, PR_PROFILE_OPEN_FLAGS, _T("06000000") }, // STRING_OK
  125. { _T("EMS_MDB_public"), NULL, PR_PROFILE_TYPE, _T("03000000") }, // STRING_OK
  126. { _T("EMS_MDB_public"), NULL, PR_MDB_PROVIDER, _T("78b2fa70aff711cd9bc800aa002fc45a") }, // STRING_OK
  127. { _T("EMS_MDB_public"), _T("PR_DISPLAY_NAME"), 0L, _T("Public Folders") }, // STRING_OK
  128. { _T("EMS_MDB_public"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Message Store") }, // STRING_OK
  129. { _T("EMS_MDB_private"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSMDB.DLL") }, // STRING_OK
  130. { _T("EMS_MDB_private"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  131. { _T("EMS_MDB_private"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_STORE_PROVIDER") }, // STRING_OK
  132. { _T("EMS_MDB_private"), _T("PR_RESOURCE_FLAGS"), 0L, _T("STATUS_PRIMARY_IDENTITY|STATUS_DEFAULT_STORE|STATUS_PRIMARY_STORE") }, // STRING_OK
  133. { _T("EMS_MDB_private"), NULL, PR_PROFILE_OPEN_FLAGS, _T("0C000000") }, // STRING_OK
  134. { _T("EMS_MDB_private"), NULL, PR_PROFILE_TYPE, _T("01000000") }, // STRING_OK
  135. { _T("EMS_MDB_private"), NULL, PR_MDB_PROVIDER, _T("5494A1C0297F101BA58708002B2A2517") }, // STRING_OK
  136. { _T("EMS_MDB_private"), _T("PR_DISPLAY_NAME"), 0L, _T("Private Folders") }, // STRING_OK
  137. { _T("EMS_MDB_private"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Message Store") }, // STRING_OK
  138. { _T("EMS_DSA"), _T("PR_DISPLAY_NAME"), 0L, _T("Microsoft Exchange Directory Service") }, // STRING_OK
  139. { _T("EMS_DSA"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Directory Service") }, // STRING_OK
  140. { _T("EMS_DSA"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSABP.DLL") }, // STRING_OK
  141. { _T("EMS_DSA"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  142. { _T("EMS_DSA"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_AB_PROVIDER") }, // STRING_OK
  143. { _T("MSEMS_MSMail_Section"), _T("UID"), 0L, _T("13DBB0C8AA05101A9BB000AA002FC45A") }, // STRING_OK
  144. { _T("MSEMS_MSMail_Section"), NULL, PR_PROFILE_VERSION, _T("01050000") }, // STRING_OK
  145. { _T("MSEMS_MSMail_Section"), NULL, PR_PROFILE_CONFIG_FLAGS, _T("04000000") }, // STRING_OK
  146. { _T("MSEMS_MSMail_Section"), NULL, PR_PROFILE_TRANSPORT_FLAGS, _T("03000000") }, // STRING_OK
  147. { _T("MSEMS_MSMail_Section"), NULL, PR_PROFILE_CONNECT_FLAGS, _T("02000000") }, // STRING_OK
  148. { _T("EMS_RXP"), _T("PR_DISPLAY_NAME"), 0L, _T("Microsoft Exchange Remote Transport") }, // STRING_OK
  149. { _T("EMS_RXP"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Remote Transport") }, // STRING_OK
  150. { _T("EMS_RXP"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSUI.DLL") }, // STRING_OK
  151. { _T("EMS_RXP"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  152. { _T("EMS_RXP"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_TRANSPORT_PROVIDER") }, // STRING_OK
  153. { _T("EMS_RXP"), NULL, PR_PROFILE_OPEN_FLAGS, _T("40000000") }, // STRING_OK
  154. { _T("EMS_RXP"), NULL, PR_PROFILE_TYPE, _T("0A000000") }, // STRING_OK
  155. { _T("EMS_MSX"), _T("PR_DISPLAY_NAME"), 0L, _T("Microsoft Exchange Transport") }, // STRING_OK
  156. { _T("EMS_MSX"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Transport") }, // STRING_OK
  157. { _T("EMS_MSX"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSMDB.DLL") }, // STRING_OK
  158. { _T("EMS_MSX"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  159. { _T("EMS_MSX"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_TRANSPORT_PROVIDER") }, // STRING_OK
  160. { _T("EMS_MSX"), NULL, PR_PROFILE_OPEN_FLAGS, _T("00000000") }, // STRING_OK
  161. { _T("EMS_Hook"), _T("PR_DISPLAY_NAME"), 0L, _T("Microsoft Exchange Hook") }, // STRING_OK
  162. { _T("EMS_Hook"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Microsoft Exchange Hook") }, // STRING_OK
  163. { _T("EMS_Hook"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("EMSMDB.DLL") }, // STRING_OK
  164. { _T("EMS_Hook"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D26A-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  165. { _T("EMS_Hook"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_HOOK_PROVIDER") }, // STRING_OK
  166. { _T("EMS_Hook"), _T("PR_RESOURCE_FLAGS"), 0L, _T("HOOK_INBOUND") }, // STRING_OK
  167. { NULL, NULL, 0L, NULL }
  168. };
  169. // Here's an example of the array to use to remove a service
  170. static SERVICESINIREC aREMOVE_MSEMSServicesIni[] =
  171. {
  172. { _T("Default Services"), _T("MSEMS"), 0L, NULL }, // STRING_OK
  173. { _T("Services"), _T("MSEMS"), 0L, NULL }, // STRING_OK
  174. { _T("MSEMS"), NULL, 0L, NULL }, // STRING_OK
  175. { _T("EMS_MDB_public"), NULL, 0L, NULL }, // STRING_OK
  176. { _T("EMS_MDB_private"), NULL, 0L, NULL }, // STRING_OK
  177. { _T("EMS_DSA"), NULL, 0L, NULL }, // STRING_OK
  178. { _T("MSEMS_MSMail_Section"), NULL, 0L, NULL }, // STRING_OK
  179. { _T("EMS_RXP"), NULL, 0L, NULL }, // STRING_OK
  180. { _T("EMS_MSX"), NULL, 0L, NULL }, // STRING_OK
  181. { _T("EMS_Hook"), NULL, 0L, NULL }, // STRING_OK
  182. { _T("EMSDelegate"), NULL, 0L, NULL }, // STRING_OK
  183. { NULL, NULL, 0L, NULL }
  184. };
  185. static SERVICESINIREC aPSTServicesIni[] =
  186. {
  187. { _T("Services"), _T("MSPST MS"), 0L, _T("Personal Folders File (.pst)") }, // STRING_OK
  188. { _T("Services"), _T("MSPST AB"), 0L, _T("Personal Address Book") }, // STRING_OK
  189. { _T("MSPST AB"), _T("PR_DISPLAY_NAME"), 0L, _T("Personal Address Book") }, // STRING_OK
  190. { _T("MSPST AB"), _T("Providers"), 0L, _T("MSPST ABP") }, // STRING_OK
  191. { _T("MSPST AB"), _T("PR_SERVICE_DLL_NAME"), 0L, _T("MSPST.DLL") }, // STRING_OK
  192. { _T("MSPST AB"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D262-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  193. { _T("MSPST AB"), _T("PR_SERVICE_SUPPORT_FILES"), 0L, _T("MSPST.DLL") }, // STRING_OK
  194. { _T("MSPST AB"), _T("PR_SERVICE_ENTRY_NAME"), 0L, _T("PABServiceEntry") }, // STRING_OK
  195. { _T("MSPST AB"), _T("PR_RESOURCE_FLAGS"), 0L, _T("SERVICE_SINGLE_COPY|SERVICE_NO_PRIMARY_IDENTITY") }, // STRING_OK
  196. { _T("MSPST ABP"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("MSPST.DLL") }, // STRING_OK
  197. { _T("MSPST ABP"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D262-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  198. { _T("MSPST ABP"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_AB_PROVIDER") }, // STRING_OK
  199. { _T("MSPST ABP"), _T("PR_DISPLAY_NAME"), 0L, _T("Personal Address Book") }, // STRING_OK
  200. { _T("MSPST ABP"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Personal Address Book") }, // STRING_OK
  201. { _T("MSPST ABP"), _T("PR_SERVICE_DLL_NAME"), 0L, _T("MSPST.DLL") }, // STRING_OK
  202. { _T("MSPST MS"), _T("Providers"), 0L, _T("MSPST MSP") }, // STRING_OK
  203. { _T("MSPST MS"), _T("PR_SERVICE_DLL_NAME"), 0L, _T("mspst.dll") }, // STRING_OK
  204. { _T("MSPST MS"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D262-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  205. { _T("MSPST MS"), _T("PR_SERVICE_SUPPORT_FILES"), 0L, _T("mspst.dll") }, // STRING_OK
  206. { _T("MSPST MS"), _T("PR_SERVICE_ENTRY_NAME"), 0L, _T("PSTServiceEntry") }, // STRING_OK
  207. { _T("MSPST MS"), _T("PR_RESOURCE_FLAGS"), 0L, _T("SERVICE_NO_PRIMARY_IDENTITY") }, // STRING_OK
  208. { _T("MSPST MSP"), NULL, PR_MDB_PROVIDER, _T("4e495441f9bfb80100aa0037d96e0000") }, // STRING_OK
  209. { _T("MSPST MSP"), _T("PR_PROVIDER_DLL_NAME"), 0L, _T("mspst.dll") }, // STRING_OK
  210. { _T("MSPST MSP"), _T("PR_SERVICE_INSTALL_ID"), 0L, _T("{6485D262-C2AC-11D1-AD3E-10A0C911C9C0}") }, // STRING_OK
  211. { _T("MSPST MSP"), _T("PR_RESOURCE_TYPE"), 0L, _T("MAPI_STORE_PROVIDER") }, // STRING_OK
  212. { _T("MSPST MSP"), _T("PR_RESOURCE_FLAGS"), 0L, _T("STATUS_DEFAULT_STORE") }, // STRING_OK
  213. { _T("MSPST MSP"), _T("PR_DISPLAY_NAME"), 0L, _T("Personal Folders") }, // STRING_OK
  214. { _T("MSPST MSP"), _T("PR_PROVIDER_DISPLAY"), 0L, _T("Personal Folders File (.pst)") }, // STRING_OK
  215. { _T("MSPST MSP"), _T("PR_SERVICE_DLL_NAME"), 0L, _T("mspst.dll") }, // STRING_OK
  216. { NULL, NULL, 0L, NULL }
  217. };
  218. static SERVICESINIREC aREMOVE_MSPSTServicesIni[] =
  219. {
  220. { _T("Default Services"), _T("MSPST MS"), 0L, NULL }, // STRING_OK
  221. { _T("Default Services"), _T("MSPST AB"), 0L, NULL }, // STRING_OK
  222. { _T("Services"), _T("MSPST MS"), 0L, NULL }, // STRING_OK
  223. { _T("Services"), _T("MSPST AB"), 0L, NULL }, // STRING_OK
  224. { _T("MSPST AB"), NULL, 0L, NULL }, // STRING_OK
  225. { _T("MSPST ABP"), NULL, 0L, NULL }, // STRING_OK
  226. { _T("MSPST MS"), NULL, 0L, NULL }, // STRING_OK
  227. { _T("MSPST MSP"), NULL, 0L, NULL }, // STRING_OK
  228. { NULL, NULL, 0L, NULL }
  229. };
  230. // $--HrSetProfileParameters----------------------------------------------
  231. // Add values to MAPISVC.INF
  232. // -----------------------------------------------------------------------------
  233. _Check_return_ HRESULT HrSetProfileParameters(_In_ SERVICESINIREC *lpServicesIni)
  234. {
  235. HRESULT hRes = S_OK;
  236. TCHAR szServicesIni[MAX_PATH + 12] = { 0 }; // 12 = space for 'MAPISVC.INF'
  237. UINT n = 0;
  238. TCHAR szPropNum[10] = { 0 };
  239. DebugPrint(DBGGeneric, L"HrSetProfileParameters()\n");
  240. if (!lpServicesIni) return MAPI_E_INVALID_PARAMETER;
  241. GetMAPISVCPath(szServicesIni, _countof(szServicesIni));
  242. if (!szServicesIni[0])
  243. {
  244. hRes = MAPI_E_NOT_FOUND;
  245. }
  246. else
  247. {
  248. DebugPrint(DBGGeneric, L"Writing to this file: \"%ws\"\n", LPCTSTRToWstring(szServicesIni).c_str());
  249. //
  250. // Loop through and add items to MAPISVC.INF
  251. //
  252. n = 0;
  253. while (lpServicesIni[n].lpszSection != NULL)
  254. {
  255. LPTSTR lpszProp = lpServicesIni[n].lpszKey;
  256. LPTSTR lpszValue = lpServicesIni[n].lpszValue;
  257. // Switch the property if necessary
  258. if ((lpszProp == NULL) && (lpServicesIni[n].ulKey != 0))
  259. {
  260. EC_H(StringCchPrintf(
  261. szPropNum,
  262. _countof(szPropNum),
  263. _T("%lx"), // STRING_OK
  264. lpServicesIni[n].ulKey));
  265. lpszProp = szPropNum;
  266. }
  267. //
  268. // Write the item to MAPISVC.INF
  269. //
  270. DebugPrint(DBGGeneric, L"\tWriting: \"%ws\"::\"%ws\"::\"%ws\"\n",
  271. LPCTSTRToWstring(lpServicesIni[n].lpszSection).c_str(),
  272. LPCTSTRToWstring(lpszProp).c_str(),
  273. LPCTSTRToWstring(lpszValue).c_str());
  274. EC_B(WritePrivateProfileString(
  275. lpServicesIni[n].lpszSection,
  276. lpszProp,
  277. lpszValue,
  278. szServicesIni));
  279. n++;
  280. }
  281. // Flush the information - we can ignore the return code
  282. WritePrivateProfileString(NULL, NULL, NULL, szServicesIni);
  283. }
  284. return hRes;
  285. } // HrSetProfileParameters
  286. void AddServicesToMapiSvcInf()
  287. {
  288. HRESULT hRes = S_OK;
  289. CEditor MyData(
  290. NULL,
  291. IDS_ADDSERVICESTOINF,
  292. IDS_ADDSERVICESTOINFPROMPT,
  293. 2,
  294. CEDITOR_BUTTON_OK | CEDITOR_BUTTON_CANCEL);
  295. MyData.InitPane(0, CreateCheckPane(IDS_EXCHANGE, false, false));
  296. MyData.InitPane(1, CreateCheckPane(IDS_PST, false, false));
  297. WC_H(MyData.DisplayDialog());
  298. if (S_OK == hRes)
  299. {
  300. if (MyData.GetCheck(0))
  301. {
  302. EC_H(HrSetProfileParameters(aEMSServicesIni));
  303. hRes = S_OK;
  304. }
  305. if (MyData.GetCheck(1))
  306. {
  307. EC_H(HrSetProfileParameters(aPSTServicesIni));
  308. hRes = S_OK;
  309. }
  310. }
  311. } // AddServicesToMapiSvcInf
  312. void RemoveServicesFromMapiSvcInf()
  313. {
  314. HRESULT hRes = S_OK;
  315. CEditor MyData(
  316. NULL,
  317. IDS_REMOVEFROMINF,
  318. IDS_REMOVEFROMINFPROMPT,
  319. 2,
  320. CEDITOR_BUTTON_OK | CEDITOR_BUTTON_CANCEL);
  321. MyData.InitPane(0, CreateCheckPane(IDS_EXCHANGE, false, false));
  322. MyData.InitPane(1, CreateCheckPane(IDS_PST, false, false));
  323. WC_H(MyData.DisplayDialog());
  324. if (S_OK == hRes)
  325. {
  326. if (MyData.GetCheck(0))
  327. {
  328. EC_H(HrSetProfileParameters(aREMOVE_MSEMSServicesIni));
  329. hRes = S_OK;
  330. }
  331. if (MyData.GetCheck(1))
  332. {
  333. EC_H(HrSetProfileParameters(aREMOVE_MSPSTServicesIni));
  334. hRes = S_OK;
  335. }
  336. }
  337. } // RemoveServicesFromMapiSvcInf
  338. #define PR_MARKER PR_BODY_A
  339. #define MARKER_STRING "MFCMAPI Existing Provider Marker" // STRING_OK
  340. // Walk through providers and add/remove our tag
  341. // bAddMark of true will add tag, bAddMark of false will remove it
  342. _Check_return_ HRESULT HrMarkExistingProviders(_In_ LPSERVICEADMIN lpServiceAdmin, bool bAddMark)
  343. {
  344. HRESULT hRes = S_OK;
  345. LPMAPITABLE lpProviderTable = NULL;
  346. if (!lpServiceAdmin) return MAPI_E_INVALID_PARAMETER;
  347. static const SizedSPropTagArray(1, pTagUID) =
  348. {
  349. 1,
  350. PR_SERVICE_UID
  351. };
  352. EC_MAPI(lpServiceAdmin->GetMsgServiceTable(0, &lpProviderTable));
  353. if (lpProviderTable)
  354. {
  355. LPSRowSet lpRowSet = NULL;
  356. EC_MAPI(HrQueryAllRows(lpProviderTable, (LPSPropTagArray)&pTagUID, NULL, NULL, 0, &lpRowSet));
  357. if (lpRowSet) DebugPrintSRowSet(DBGGeneric, lpRowSet, NULL);
  358. if (lpRowSet && lpRowSet->cRows >= 1)
  359. {
  360. for (ULONG i = 0; i < lpRowSet->cRows; i++)
  361. {
  362. LPSRow lpCurRow = NULL;
  363. LPSPropValue lpServiceUID = NULL;
  364. hRes = S_OK;
  365. lpCurRow = &lpRowSet->aRow[i];
  366. lpServiceUID = PpropFindProp(
  367. lpCurRow->lpProps,
  368. lpCurRow->cValues,
  369. PR_SERVICE_UID);
  370. if (lpServiceUID)
  371. {
  372. LPPROFSECT lpSect = NULL;
  373. EC_H(OpenProfileSection(
  374. lpServiceAdmin,
  375. &lpServiceUID->Value.bin,
  376. &lpSect));
  377. if (lpSect)
  378. {
  379. if (bAddMark)
  380. {
  381. SPropValue PropVal;
  382. PropVal.ulPropTag = PR_MARKER;
  383. PropVal.Value.lpszA = MARKER_STRING;
  384. EC_MAPI(lpSect->SetProps(1, &PropVal, NULL));
  385. }
  386. else
  387. {
  388. SPropTagArray pTagArray = { 1, PR_MARKER };
  389. WC_MAPI(lpSect->DeleteProps(&pTagArray, NULL));
  390. }
  391. hRes = S_OK;
  392. EC_MAPI(lpSect->SaveChanges(0));
  393. lpSect->Release();
  394. }
  395. }
  396. }
  397. }
  398. FreeProws(lpRowSet);
  399. lpProviderTable->Release();
  400. }
  401. return hRes;
  402. } // HrMarkExistingProviders
  403. // Returns first provider without our mark on it
  404. _Check_return_ HRESULT HrFindUnmarkedProvider(_In_ LPSERVICEADMIN lpServiceAdmin, _Deref_out_opt_ LPSRowSet* lpRowSet)
  405. {
  406. HRESULT hRes = S_OK;
  407. LPMAPITABLE lpProviderTable = NULL;
  408. LPPROFSECT lpSect = NULL;
  409. if (!lpServiceAdmin || !lpRowSet) return MAPI_E_INVALID_PARAMETER;
  410. *lpRowSet = NULL;
  411. static const SizedSPropTagArray(1, pTagUID) =
  412. {
  413. 1,
  414. PR_SERVICE_UID
  415. };
  416. EC_MAPI(lpServiceAdmin->GetMsgServiceTable(0, &lpProviderTable));
  417. if (lpProviderTable)
  418. {
  419. EC_MAPI(lpProviderTable->SetColumns((LPSPropTagArray)&pTagUID, TBL_BATCH));
  420. for (;;)
  421. {
  422. EC_MAPI(lpProviderTable->QueryRows(1, 0, lpRowSet));
  423. if (S_OK == hRes && *lpRowSet && 1 == (*lpRowSet)->cRows)
  424. {
  425. LPSRow lpCurRow = NULL;
  426. LPSPropValue lpServiceUID = NULL;
  427. lpCurRow = &(*lpRowSet)->aRow[0];
  428. lpServiceUID = PpropFindProp(
  429. lpCurRow->lpProps,
  430. lpCurRow->cValues,
  431. PR_SERVICE_UID);
  432. if (lpServiceUID)
  433. {
  434. EC_H(OpenProfileSection(
  435. lpServiceAdmin,
  436. &lpServiceUID->Value.bin,
  437. &lpSect));
  438. if (lpSect)
  439. {
  440. SPropTagArray pTagArray = { 1, PR_MARKER };
  441. ULONG ulPropVal = 0;
  442. LPSPropValue lpsPropVal = NULL;
  443. EC_H_GETPROPS(lpSect->GetProps(&pTagArray, NULL, &ulPropVal, &lpsPropVal));
  444. if (!(CheckStringProp(lpsPropVal, PROP_TYPE(PR_MARKER)) &&
  445. !strcmp(lpsPropVal->Value.lpszA, MARKER_STRING)))
  446. {
  447. // got an unmarked provider - this is our hit
  448. // Don't free *lpRowSet - we're returning it
  449. hRes = S_OK; // wipe any error from the GetProps - it was expected
  450. MAPIFreeBuffer(lpsPropVal);
  451. break;
  452. }
  453. MAPIFreeBuffer(lpsPropVal);
  454. lpSect->Release();
  455. lpSect = NULL;
  456. }
  457. }
  458. // go on to next one in the loop
  459. FreeProws(*lpRowSet);
  460. *lpRowSet = NULL;
  461. }
  462. else
  463. {
  464. // no more hits - get out of the loop
  465. FreeProws(*lpRowSet);
  466. *lpRowSet = NULL;
  467. break;
  468. }
  469. }
  470. if (lpSect) lpSect->Release();
  471. lpProviderTable->Release();
  472. }
  473. return hRes;
  474. } // HrFindUnmarkedProvider
  475. _Check_return_ HRESULT HrAddServiceToProfile(
  476. _In_z_ LPCSTR lpszServiceName, // Service Name
  477. _In_ ULONG_PTR ulUIParam, // hwnd for CreateMsgService
  478. ULONG ulFlags, // Flags for CreateMsgService
  479. ULONG cPropVals, // Count of properties for ConfigureMsgService
  480. _In_opt_ LPSPropValue lpPropVals, // Properties for ConfigureMsgService
  481. _In_z_ LPCSTR lpszProfileName) // profile name
  482. {
  483. HRESULT hRes = S_OK;
  484. LPPROFADMIN lpProfAdmin = NULL;
  485. LPSERVICEADMIN lpServiceAdmin = NULL;
  486. LPSRowSet lpRowSet = NULL;
  487. DebugPrint(DBGGeneric, L"HrAddServiceToProfile(%hs,%hs)\n", lpszServiceName, lpszProfileName);
  488. if (!lpszServiceName || !lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  489. // Connect to Profile Admin interface.
  490. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  491. if (!lpProfAdmin) return hRes;
  492. EC_MAPI(lpProfAdmin->AdminServices(
  493. (LPTSTR)lpszProfileName,
  494. (LPTSTR)_T(""),
  495. 0,
  496. 0,
  497. &lpServiceAdmin));
  498. if (lpServiceAdmin)
  499. {
  500. MAPIUID uidService = { 0 };
  501. LPMAPIUID lpuidService = &uidService;
  502. LPSERVICEADMIN2 lpServiceAdmin2 = NULL;
  503. WC_MAPI(lpServiceAdmin->QueryInterface(IID_IMsgServiceAdmin2, (LPVOID*)&lpServiceAdmin2));
  504. if (SUCCEEDED(hRes) && lpServiceAdmin2)
  505. {
  506. EC_H_MSG(lpServiceAdmin2->CreateMsgServiceEx(
  507. (LPTSTR)lpszServiceName,
  508. (LPTSTR)lpszServiceName,
  509. ulUIParam,
  510. ulFlags,
  511. &uidService),
  512. IDS_CREATEMSGSERVICEFAILED);
  513. }
  514. else
  515. {
  516. hRes = S_OK;
  517. // Only need to mark if we plan on calling ConfigureMsgService
  518. if (lpPropVals)
  519. {
  520. // Add a dummy prop to the current providers
  521. EC_H(HrMarkExistingProviders(lpServiceAdmin, true));
  522. }
  523. EC_H_MSG(lpServiceAdmin->CreateMsgService(
  524. (LPTSTR)lpszServiceName,
  525. (LPTSTR)lpszServiceName,
  526. ulUIParam,
  527. ulFlags),
  528. IDS_CREATEMSGSERVICEFAILED);
  529. if (lpPropVals)
  530. {
  531. // Look for a provider without our dummy prop
  532. EC_H(HrFindUnmarkedProvider(lpServiceAdmin, &lpRowSet));
  533. if (lpRowSet) DebugPrintSRowSet(DBGGeneric, lpRowSet, NULL);
  534. // should only have one unmarked row
  535. if (lpRowSet && lpRowSet->cRows == 1)
  536. {
  537. LPSPropValue lpServiceUIDProp = NULL;
  538. lpServiceUIDProp = PpropFindProp(
  539. lpRowSet->aRow[0].lpProps,
  540. lpRowSet->aRow[0].cValues,
  541. PR_SERVICE_UID);
  542. if (lpServiceUIDProp)
  543. {
  544. lpuidService = (LPMAPIUID)lpServiceUIDProp->Value.bin.lpb;
  545. }
  546. }
  547. hRes = S_OK;
  548. // Strip out the dummy prop
  549. EC_H(HrMarkExistingProviders(lpServiceAdmin, false));
  550. }
  551. }
  552. if (lpPropVals)
  553. {
  554. EC_H_CANCEL(lpServiceAdmin->ConfigureMsgService(
  555. lpuidService,
  556. NULL,
  557. 0,
  558. cPropVals,
  559. lpPropVals));
  560. }
  561. FreeProws(lpRowSet);
  562. if (lpServiceAdmin2) lpServiceAdmin2->Release();
  563. lpServiceAdmin->Release();
  564. }
  565. lpProfAdmin->Release();
  566. return hRes;
  567. } // HrAddServiceToProfile
  568. _Check_return_ HRESULT HrAddExchangeToProfile(
  569. _In_ ULONG_PTR ulUIParam, // hwnd for CreateMsgService
  570. _In_z_ LPCSTR lpszServerName,
  571. _In_z_ LPCSTR lpszMailboxName,
  572. _In_z_ LPCSTR lpszProfileName)
  573. {
  574. HRESULT hRes = S_OK;
  575. DebugPrint(DBGGeneric, L"HrAddExchangeToProfile(%hs,%hs,%hs)\n", lpszServerName, lpszMailboxName, lpszProfileName);
  576. if (!lpszServerName || !lpszMailboxName || !lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  577. #define NUMEXCHANGEPROPS 2
  578. SPropValue PropVal[NUMEXCHANGEPROPS];
  579. PropVal[0].ulPropTag = PR_PROFILE_UNRESOLVED_SERVER;
  580. PropVal[0].Value.lpszA = (LPSTR)lpszServerName;
  581. PropVal[1].ulPropTag = PR_PROFILE_UNRESOLVED_NAME;
  582. PropVal[1].Value.lpszA = (LPSTR)lpszMailboxName;
  583. EC_H(HrAddServiceToProfile("MSEMS", ulUIParam, NULL, NUMEXCHANGEPROPS, PropVal, lpszProfileName)); // STRING_OK
  584. return hRes;
  585. } // HrAddExchangeToProfile
  586. _Check_return_ HRESULT HrAddPSTToProfile(
  587. _In_ ULONG_PTR ulUIParam, // hwnd for CreateMsgService
  588. bool bUnicodePST,
  589. _In_z_ LPCTSTR lpszPSTPath, // PST name
  590. _In_z_ LPCSTR lpszProfileName, // profile name
  591. bool bPasswordSet, // whether or not to include a password
  592. _In_z_ LPCSTR lpszPassword) // password to include
  593. {
  594. HRESULT hRes = S_OK;
  595. DebugPrint(DBGGeneric, L"HrAddPSTToProfile(0x%X,%ws,%hs,0x%X,%hs)\n", bUnicodePST, LPCTSTRToWstring(lpszPSTPath).c_str(), lpszProfileName, bPasswordSet, lpszPassword);
  596. if (!lpszPSTPath || !lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  597. SPropValue PropVal[2];
  598. PropVal[0].ulPropTag = CHANGE_PROP_TYPE(PR_PST_PATH, PT_TSTRING);
  599. PropVal[0].Value.LPSZ = (LPTSTR)lpszPSTPath;
  600. PropVal[1].ulPropTag = PR_PST_PW_SZ_OLD;
  601. PropVal[1].Value.lpszA = (LPSTR)lpszPassword;
  602. if (bUnicodePST)
  603. {
  604. EC_H(HrAddServiceToProfile("MSUPST MS", ulUIParam, NULL, bPasswordSet ? 2 : 1, PropVal, lpszProfileName)); // STRING_OK
  605. }
  606. else
  607. {
  608. EC_H(HrAddServiceToProfile("MSPST MS", ulUIParam, NULL, bPasswordSet ? 2 : 1, PropVal, lpszProfileName)); // STRING_OK
  609. }
  610. return hRes;
  611. } // HrAddPSTToProfile
  612. // $--HrCreateProfile---------------------------------------------
  613. // Creates an empty profile.
  614. // -----------------------------------------------------------------------------
  615. _Check_return_ HRESULT HrCreateProfile(
  616. _In_z_ LPCSTR lpszProfileName) // profile name
  617. {
  618. HRESULT hRes = S_OK;
  619. LPPROFADMIN lpProfAdmin = NULL;
  620. DebugPrint(DBGGeneric, L"HrCreateProfile(%hs)\n", lpszProfileName);
  621. if (!lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  622. // Connect to Profile Admin interface.
  623. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  624. if (!lpProfAdmin) return hRes;
  625. // Create the profile
  626. WC_MAPI(lpProfAdmin->CreateProfile(
  627. (LPTSTR)lpszProfileName,
  628. NULL,
  629. 0,
  630. NULL)); // fMapiUnicode is not supported!
  631. if (S_OK != hRes)
  632. {
  633. // Did it fail because a profile of this name already exists?
  634. EC_H_MSG(HrMAPIProfileExists(lpProfAdmin, lpszProfileName),
  635. IDS_DUPLICATEPROFILE);
  636. }
  637. lpProfAdmin->Release();
  638. return hRes;
  639. } // HrCreateProfile
  640. // $--HrRemoveProfile---------------------------------------------------------
  641. // Removes a profile.
  642. // ------------------------------------------------------------------------------
  643. _Check_return_ HRESULT HrRemoveProfile(
  644. _In_z_ LPCSTR lpszProfileName)
  645. {
  646. HRESULT hRes = S_OK;
  647. LPPROFADMIN lpProfAdmin = NULL;
  648. DebugPrint(DBGGeneric, L"HrRemoveProfile(%hs)\n", lpszProfileName);
  649. if (!lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  650. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  651. if (!lpProfAdmin) return hRes;
  652. EC_MAPI(lpProfAdmin->DeleteProfile((LPTSTR)lpszProfileName, 0));
  653. lpProfAdmin->Release();
  654. RegFlushKey(HKEY_LOCAL_MACHINE);
  655. RegFlushKey(HKEY_CURRENT_USER);
  656. return hRes;
  657. } // HrRemoveProfile
  658. // $--HrSetDefaultProfile---------------------------------------------------------
  659. // Set a profile as default.
  660. // ------------------------------------------------------------------------------
  661. _Check_return_ HRESULT HrSetDefaultProfile(
  662. _In_z_ LPCSTR lpszProfileName)
  663. {
  664. HRESULT hRes = S_OK;
  665. LPPROFADMIN lpProfAdmin = NULL;
  666. DebugPrint(DBGGeneric, L"HrRemoveProfile(%hs)\n", lpszProfileName);
  667. if (!lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  668. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  669. if (!lpProfAdmin) return hRes;
  670. EC_MAPI(lpProfAdmin->SetDefaultProfile((LPTSTR)lpszProfileName, 0));
  671. lpProfAdmin->Release();
  672. RegFlushKey(HKEY_LOCAL_MACHINE);
  673. RegFlushKey(HKEY_CURRENT_USER);
  674. return hRes;
  675. } // HrSetDefaultProfile
  676. // $--HrMAPIProfileExists---------------------------------------------------------
  677. // Checks for an existing profile.
  678. // -----------------------------------------------------------------------------
  679. _Check_return_ HRESULT HrMAPIProfileExists(
  680. _In_ LPPROFADMIN lpProfAdmin,
  681. _In_z_ LPCSTR lpszProfileName)
  682. {
  683. HRESULT hRes = S_OK;
  684. LPMAPITABLE lpTable = NULL;
  685. LPSRowSet lpRows = NULL;
  686. LPSPropValue lpProp = NULL;
  687. ULONG i = 0;
  688. static const SizedSPropTagArray(1, rgPropTag) =
  689. {
  690. 1,
  691. PR_DISPLAY_NAME_A
  692. };
  693. DebugPrint(DBGGeneric, L"HrMAPIProfileExists()\n");
  694. if (!lpProfAdmin || !lpszProfileName) return MAPI_E_INVALID_PARAMETER;
  695. // Get a table of existing profiles
  696. EC_MAPI(lpProfAdmin->GetProfileTable(
  697. 0,
  698. &lpTable));
  699. if (!lpTable) return hRes;
  700. EC_MAPI(HrQueryAllRows(
  701. lpTable,
  702. (LPSPropTagArray)&rgPropTag,
  703. NULL,
  704. NULL,
  705. 0,
  706. &lpRows));
  707. if (lpRows)
  708. {
  709. if (lpRows->cRows == 0)
  710. {
  711. // If table is empty then profile doesn't exist
  712. hRes = S_OK;
  713. }
  714. else
  715. {
  716. // Search rows for the folder in question
  717. if (!FAILED(hRes)) for (i = 0; i < lpRows->cRows; i++)
  718. {
  719. hRes = S_OK;
  720. lpProp = lpRows->aRow[i].lpProps;
  721. ULONG ulComp = NULL;
  722. EC_D(ulComp, CompareStringA(
  723. g_lcid, // LOCALE_INVARIANT,
  724. NORM_IGNORECASE,
  725. lpProp[0].Value.lpszA,
  726. -1,
  727. lpszProfileName,
  728. -1));
  729. if (CSTR_EQUAL == ulComp)
  730. {
  731. hRes = E_ACCESSDENIED;
  732. break;
  733. }
  734. }
  735. }
  736. }
  737. if (lpRows) FreeProws(lpRows);
  738. lpTable->Release();
  739. return hRes;
  740. } // HrMAPIProfileExists
  741. _Check_return_ HRESULT GetProfileServiceVersion(_In_z_ LPCSTR lpszProfileName,
  742. _Out_ ULONG* lpulServerVersion,
  743. _Out_ EXCHANGE_STORE_VERSION_NUM* lpStoreVersion,
  744. _Out_ bool* lpbFoundServerVersion,
  745. _Out_ bool* lpbFoundServerFullVersion)
  746. {
  747. if (!lpszProfileName
  748. || !lpulServerVersion
  749. || !lpStoreVersion
  750. || !lpbFoundServerVersion
  751. || !lpbFoundServerFullVersion) return MAPI_E_INVALID_PARAMETER;
  752. *lpulServerVersion = NULL;
  753. memset(lpStoreVersion, 0, sizeof(EXCHANGE_STORE_VERSION_NUM));
  754. *lpbFoundServerVersion = false;
  755. *lpbFoundServerFullVersion = false;
  756. HRESULT hRes = S_OK;
  757. LPPROFADMIN lpProfAdmin = NULL;
  758. LPSERVICEADMIN lpServiceAdmin = NULL;
  759. DebugPrint(DBGGeneric, L"GetProfileServiceVersion(%hs)\n", lpszProfileName);
  760. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  761. if (!lpProfAdmin) return hRes;
  762. EC_MAPI(lpProfAdmin->AdminServices(
  763. (LPTSTR)lpszProfileName,
  764. (LPTSTR)_T(""),
  765. 0,
  766. 0,
  767. &lpServiceAdmin));
  768. if (lpServiceAdmin)
  769. {
  770. LPPROFSECT lpProfSect = NULL;
  771. EC_MAPI(lpServiceAdmin->OpenProfileSection(
  772. (LPMAPIUID)pbGlobalProfileSectionGuid,
  773. NULL,
  774. 0,
  775. &lpProfSect));
  776. if (lpProfSect)
  777. {
  778. LPSPropValue lpServerVersion = NULL;
  779. WC_MAPI(HrGetOneProp(lpProfSect, PR_PROFILE_SERVER_VERSION, &lpServerVersion));
  780. if (SUCCEEDED(hRes) && lpServerVersion && PR_PROFILE_SERVER_VERSION == lpServerVersion->ulPropTag)
  781. {
  782. *lpbFoundServerVersion = true;
  783. *lpulServerVersion = lpServerVersion->Value.l;
  784. }
  785. MAPIFreeBuffer(lpServerVersion);
  786. hRes = S_OK;
  787. LPSPropValue lpServerFullVersion = NULL;
  788. WC_MAPI(HrGetOneProp(lpProfSect, PR_PROFILE_SERVER_FULL_VERSION, &lpServerFullVersion));
  789. if (SUCCEEDED(hRes) &&
  790. lpServerFullVersion &&
  791. PR_PROFILE_SERVER_FULL_VERSION == lpServerFullVersion->ulPropTag &&
  792. sizeof(EXCHANGE_STORE_VERSION_NUM) == lpServerFullVersion->Value.bin.cb)
  793. {
  794. DebugPrint(DBGGeneric, L"PR_PROFILE_SERVER_FULL_VERSION = ");
  795. DebugPrintBinary(DBGGeneric, &lpServerFullVersion->Value.bin);
  796. DebugPrint(DBGGeneric, L"\n");
  797. memcpy(lpStoreVersion, lpServerFullVersion->Value.bin.lpb, sizeof(EXCHANGE_STORE_VERSION_NUM));
  798. *lpbFoundServerFullVersion = true;
  799. }
  800. MAPIFreeBuffer(lpServerFullVersion);
  801. lpProfSect->Release();
  802. }
  803. lpServiceAdmin->Release();
  804. }
  805. lpProfAdmin->Release();
  806. // If we found any server version, consider the call a success
  807. if (*lpbFoundServerVersion || *lpbFoundServerFullVersion) hRes = S_OK;
  808. return hRes;
  809. } // GetProfileServiceVersion
  810. // $--HrCopyProfile---------------------------------------------------------
  811. // Copies a profile.
  812. // ------------------------------------------------------------------------------
  813. _Check_return_ HRESULT HrCopyProfile(_In_z_ LPCSTR lpszOldProfileName,
  814. _In_z_ LPCSTR lpszNewProfileName)
  815. {
  816. HRESULT hRes = S_OK;
  817. LPPROFADMIN lpProfAdmin = NULL;
  818. DebugPrint(DBGGeneric, L"HrCopyProfile(%hs, %hs)\n", lpszOldProfileName, lpszNewProfileName);
  819. if (!lpszOldProfileName || !lpszNewProfileName) return MAPI_E_INVALID_PARAMETER;
  820. EC_MAPI(MAPIAdminProfiles(0, &lpProfAdmin));
  821. if (!lpProfAdmin) return hRes;
  822. EC_MAPI(lpProfAdmin->CopyProfile((LPTSTR)lpszOldProfileName, NULL, (LPTSTR)lpszNewProfileName, NULL, NULL));
  823. lpProfAdmin->Release();
  824. return hRes;
  825. } // HrCopyProfile
  826. #endif
  827. #define MAPI_FORCE_ACCESS 0x00080000
  828. _Check_return_ HRESULT OpenProfileSection(_In_ LPSERVICEADMIN lpServiceAdmin, _In_ LPSBinary lpServiceUID, _Deref_out_opt_ LPPROFSECT* lppProfSect)
  829. {
  830. HRESULT hRes = S_OK;
  831. DebugPrint(DBGOpenItemProp, L"OpenProfileSection opening lpServiceUID = ");
  832. DebugPrintBinary(DBGOpenItemProp, lpServiceUID);
  833. DebugPrint(DBGOpenItemProp, L"\n");
  834. if (!lpServiceUID || !lpServiceAdmin || !lppProfSect) return MAPI_E_INVALID_PARAMETER;
  835. *lppProfSect = NULL;
  836. // First, we try the normal way of opening the profile section:
  837. WC_MAPI(lpServiceAdmin->OpenProfileSection(
  838. (LPMAPIUID)lpServiceUID->lpb,
  839. NULL,
  840. MAPI_MODIFY | MAPI_FORCE_ACCESS, // passing this flag might actually work with Outlook 2000 and XP
  841. lppProfSect));
  842. if (!*lppProfSect)
  843. {
  844. hRes = S_OK;
  845. ///////////////////////////////////////////////////////////////////
  846. // HACK CENTRAL. This is a MAJOR hack. MAPI will always return E_ACCESSDENIED
  847. // when we open a profile section on the service if we are a client. The workaround
  848. // (HACK) is to call into one of MAPI's internal functions that bypasses
  849. // the security check. We build a Interface to it and then point to it from our
  850. // offset of 0x48. USE AT YOUR OWN RISK! NOT SUPPORTED!
  851. interface IOpenSectionHack : public IUnknown
  852. {
  853. public:
  854. virtual HRESULT STDMETHODCALLTYPE OpenSection(LPMAPIUID, ULONG, LPPROFSECT*) = 0;
  855. };
  856. IOpenSectionHack** ppProfile;
  857. ppProfile = (IOpenSectionHack**)((((BYTE*)lpServiceAdmin) + 0x48));
  858. // Now, we want to get open the Services Profile Section and store that
  859. // interface with the Object
  860. if (ppProfile && *ppProfile)
  861. {
  862. EC_MAPI((*ppProfile)->OpenSection(
  863. (LPMAPIUID)lpServiceUID->lpb,
  864. MAPI_MODIFY,
  865. lppProfSect));
  866. }
  867. else
  868. {
  869. hRes = MAPI_E_NOT_FOUND;
  870. }
  871. // END OF HACK. I'm amazed that this works....
  872. ///////////////////////////////////////////////////////////////////
  873. }
  874. return hRes;
  875. } // OpenProfileSection
  876. _Check_return_ HRESULT OpenProfileSection(_In_ LPPROVIDERADMIN lpProviderAdmin, _In_ LPSBinary lpProviderUID, _Deref_out_ LPPROFSECT* lppProfSect)
  877. {
  878. HRESULT hRes = S_OK;
  879. DebugPrint(DBGOpenItemProp, L"OpenProfileSection opening lpServiceUID = ");
  880. DebugPrintBinary(DBGOpenItemProp, lpProviderUID);
  881. DebugPrint(DBGOpenItemProp, L"\n");
  882. if (!lpProviderUID || !lpProviderAdmin || !lppProfSect) return MAPI_E_INVALID_PARAMETER;
  883. *lppProfSect = NULL;
  884. WC_MAPI(lpProviderAdmin->OpenProfileSection(
  885. (LPMAPIUID)lpProviderUID->lpb,
  886. NULL,
  887. MAPI_MODIFY | MAPI_FORCE_ACCESS,
  888. lppProfSect));
  889. if (!*lppProfSect)
  890. {
  891. hRes = S_OK;
  892. // We only do this hack as a last resort - it can crash some versions of Outlook, but is required for Exchange
  893. *(((BYTE*)lpProviderAdmin) + 0x60) = 0x2; // Use at your own risk! NOT SUPPORTED!
  894. WC_MAPI(lpProviderAdmin->OpenProfileSection(
  895. (LPMAPIUID)lpProviderUID->lpb,
  896. NULL,
  897. MAPI_MODIFY,
  898. lppProfSect));
  899. }
  900. return hRes;
  901. } // OpenProfileSection