Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

529 lines
16 KiB

  1. /*---------------------------------------------------------------------------
  2. File: ListProfiles.cpp
  3. Comments: Helper functions that dynamically load the MAPI library, and
  4. enumerate the MAPI profiles on the local machine (for the logged on user)
  5. (c) Copyright 1999, Mission Critical Software, Inc., All Rights Reserved
  6. Proprietary and confidential to Mission Critical Software, Inc.
  7. REVISION LOG ENTRY
  8. Revision By: Christy Boles
  9. Revised on 03/18/99 11:09:53
  10. ---------------------------------------------------------------------------
  11. */
  12. #include "stdafx.h"
  13. #include "resource.h"
  14. #include "ListProf.h"
  15. #include "Common.hpp"
  16. #include "Ustring.hpp"
  17. #include <edkmdb.h>
  18. #include <emsabtag.h>
  19. HINSTANCE hMapi = NULL;
  20. LPMAPIALLOCATEBUFFER pMAPIAllocateBuffer = NULL;
  21. LPMAPIFREEBUFFER pMAPIFreeBuffer = NULL;
  22. LPMAPIINITIALIZE pMAPIInitialize = NULL;
  23. LPMAPIUNINITIALIZE pMAPIUninitialize = NULL;
  24. LPMAPILOGONEX pMAPILogonEx = NULL;
  25. LPMAPIADMINPROFILES pMAPIAdminProfiles = NULL;
  26. LPFREEPADRLIST pFreePadrlist = NULL;
  27. LPFREEPROWS pFreeProws = NULL;
  28. LPSCDUPPROPSET pScDupPropset = NULL;
  29. LPHRQUERYALLROWS pHrQueryAllRows = NULL;
  30. LPULRELEASE pUlRelease = NULL;
  31. BOOL bMapiInitialized = FALSE;
  32. #define NOT_PT_ERROR(x) ( PROP_TYPE(x.ulPropTag) != PT_ERROR )
  33. BOOL
  34. LoadMAPI(
  35. IVarSet * pVarSet
  36. )
  37. {
  38. BOOL success = TRUE;
  39. WCHAR errString[1000] = L"";
  40. if ( ! hMapi )
  41. {
  42. hMapi = LoadLibrary(_T("MAPI32.DLL"));
  43. if ( hMapi )
  44. {
  45. do { // once (only show one error message)
  46. pMAPIAllocateBuffer=(LPMAPIALLOCATEBUFFER)GetProcAddress(hMapi,"MAPIAllocateBuffer");
  47. if ( ! pMAPIAllocateBuffer )
  48. {
  49. LoadString(NULL,IDS_NoMAPIAllocateBuffer,errString,DIM(errString));
  50. success = FALSE;
  51. break;
  52. }
  53. pMAPIFreeBuffer = (LPMAPIFREEBUFFER)GetProcAddress(hMapi,"MAPIFreeBuffer");
  54. if ( ! pMAPIFreeBuffer )
  55. {
  56. LoadString(NULL,IDS_NoMAPIFreeBuffer,errString,DIM(errString));
  57. success = FALSE;
  58. break;
  59. }
  60. pMAPIInitialize = (LPMAPIINITIALIZE)GetProcAddress(hMapi,"MAPIInitialize");
  61. if ( ! pMAPIInitialize )
  62. {
  63. LoadString(NULL,IDS_NoMAPIInitialize,errString,DIM(errString));
  64. success = FALSE;
  65. break;
  66. }
  67. pMAPIUninitialize = (LPMAPIUNINITIALIZE)GetProcAddress(hMapi,"MAPIUninitialize");
  68. if ( ! pMAPIUninitialize )
  69. {
  70. LoadString(NULL,IDS_NoMAPIUninitialize,errString,DIM(errString));
  71. success = FALSE;
  72. break;
  73. }
  74. pMAPILogonEx = (LPMAPILOGONEX)GetProcAddress(hMapi,"MAPILogonEx");
  75. if ( ! pMAPILogonEx )
  76. {
  77. LoadString(NULL,IDS_NoMAPILogonEx,errString,DIM(errString));
  78. success = FALSE;
  79. break;
  80. }
  81. pMAPIAdminProfiles = (LPMAPIADMINPROFILES)GetProcAddress(hMapi,"MAPIAdminProfiles");
  82. if ( ! pMAPIAdminProfiles )
  83. {
  84. LoadString(NULL,IDS_NoMAPIAdminProfiles,errString,DIM(errString));
  85. success = FALSE;
  86. break;
  87. }
  88. pFreePadrlist = (LPFREEPADRLIST)GetProcAddress(hMapi,"FreePadrlist@4");
  89. if ( ! pFreePadrlist )
  90. {
  91. LoadString(NULL,IDS_NoFreePadrList,errString,DIM(errString));
  92. success = FALSE;
  93. break;
  94. }
  95. pFreeProws = (LPFREEPROWS)GetProcAddress(hMapi,"FreeProws@4");
  96. if ( ! pFreeProws )
  97. {
  98. LoadString(NULL,IDS_NoFreeProws,errString,DIM(errString));
  99. success = FALSE;
  100. break;
  101. }
  102. pScDupPropset = (LPSCDUPPROPSET)GetProcAddress(hMapi,"ScDupPropset@16");
  103. if ( ! pScDupPropset )
  104. {
  105. LoadString(NULL,IDS_NoScDupPropset,errString,DIM(errString));
  106. success = FALSE;
  107. break;
  108. }
  109. pHrQueryAllRows = (LPHRQUERYALLROWS)GetProcAddress(hMapi,"HrQueryAllRows@24");
  110. if ( ! pHrQueryAllRows )
  111. {
  112. LoadString(NULL,IDS_NoHrQueryAllRows,errString,DIM(errString));
  113. success = FALSE;
  114. break;
  115. }
  116. pUlRelease = (LPULRELEASE)GetProcAddress(hMapi,"UlRelease@4");
  117. if ( ! pUlRelease )
  118. {
  119. LoadString(NULL,IDS_NoUlRelease,errString,DIM(errString));
  120. success = FALSE;
  121. break;
  122. }
  123. }
  124. while (FALSE);
  125. }
  126. else
  127. {
  128. success = FALSE;
  129. LoadString(NULL,IDS_NO_MAPI,errString,DIM(errString));
  130. }
  131. if ( hMapi && !success )
  132. {
  133. ReleaseMAPI();
  134. }
  135. }
  136. if ( !success )
  137. {
  138. if ( pVarSet)
  139. {
  140. pVarSet->put("McsMapiUtil.ErrorText",errString);
  141. }
  142. }
  143. return (hMapi!=NULL && success);
  144. }
  145. void ReleaseMAPI()
  146. {
  147. if ( hMapi )
  148. {
  149. if ( bMapiInitialized )
  150. {
  151. (*pMAPIUninitialize)();
  152. bMapiInitialized = FALSE;
  153. }
  154. FreeLibrary(hMapi);
  155. hMapi = NULL;
  156. pMAPIAllocateBuffer = NULL;
  157. pMAPIFreeBuffer = NULL;
  158. pMAPIInitialize = NULL;
  159. pMAPIUninitialize = NULL;
  160. pMAPILogonEx = NULL;
  161. pMAPIAdminProfiles = NULL;
  162. pFreePadrlist = NULL;
  163. pFreeProws = NULL;
  164. pScDupPropset = NULL;
  165. pHrQueryAllRows = NULL;
  166. pUlRelease = NULL;
  167. }
  168. }
  169. HRESULT ListProfiles(IVarSet * pVarSet)
  170. {
  171. HRESULT hr;
  172. LPPROFADMIN prof = NULL;
  173. LPMAPITABLE table = NULL;
  174. LPSRowSet rows = NULL;
  175. if ( ! LoadMAPI(pVarSet) )
  176. {
  177. return E_FAIL;
  178. }
  179. if ( ! bMapiInitialized )
  180. {
  181. hr = (*pMAPIInitialize)(NULL);
  182. if ( SUCCEEDED(hr) )
  183. {
  184. bMapiInitialized = TRUE;
  185. }
  186. }
  187. if ( SUCCEEDED(hr) )
  188. {
  189. hr = (*pMAPIAdminProfiles)(0,&prof);
  190. }
  191. if ( SUCCEEDED(hr) )
  192. {
  193. hr = prof->GetProfileTable(0,&table);
  194. if ( SUCCEEDED(hr) )
  195. {
  196. hr = (*pHrQueryAllRows)(table,NULL,NULL,NULL,0,&rows);
  197. if ( SUCCEEDED(hr) )
  198. {
  199. for ( UINT i = 0 ; i < rows->cRows ; i ++ )
  200. {
  201. if ( PROP_TYPE(rows->aRow[i].lpProps[0].ulPropTag ) == PT_STRING8 )
  202. {
  203. WCHAR profile[200];
  204. WCHAR key[200];
  205. safecopy(profile,rows->aRow[i].lpProps[0].Value.lpszA);
  206. swprintf(key,L"Profiles.%ld",i);
  207. pVarSet->put(key,profile);
  208. if ( rows->aRow[i].lpProps[1].Value.b )
  209. {
  210. swprintf(key,L"Profiles.%ld.Default",i);
  211. pVarSet->put(key,"Yes");
  212. }
  213. }
  214. }
  215. }
  216. }
  217. }
  218. if ( rows )
  219. {
  220. (*pFreeProws)(rows);
  221. }
  222. if ( table )
  223. {
  224. table->Release();
  225. }
  226. if ( prof )
  227. {
  228. prof->Release();
  229. }
  230. return hr;
  231. }
  232. // GPSGuid is pbGlobalProfileSectionGuid (defined in edkmdb.h) in a byte[] format
  233. // This is used in GetExchangeServerFromProfile
  234. #define GPSGuid { 0x13, 0xDB, 0xB0, 0xC8,0xAA,0x05,0x10,0x1A,0x9B,0xB0,0x00,0xAA,0x00,0x2F,0xC4,0x5A }
  235. MAPIUID exchSrvrGuid = { 0xdc, 0xa7, 0x40, 0xc8,0xC0,0x42,0x10,0x1a,0xb4,0xb9,0x08,0x00,0x2b,0x2f,0xe1,0x82 };
  236. HRESULT ProfileGetServer(IVarSet * pVarSet,WCHAR const * profileW, WCHAR * computerName)
  237. {
  238. HRESULT hr;
  239. MAPIUID uid = GPSGuid;
  240. LPPROFADMIN prof = NULL;
  241. LPSERVICEADMIN admin = NULL;
  242. LPPROFSECT ps = NULL;
  243. char profile[200];
  244. LPSPropValue pVals = NULL;
  245. ULONG ulCount = 0;
  246. WCHAR errString[1000] = L"";
  247. computerName[0] = 0;
  248. safecopy(profile,profileW);
  249. if ( ! LoadMAPI(pVarSet) )
  250. {
  251. return E_FAIL;
  252. }
  253. if ( ! bMapiInitialized )
  254. {
  255. hr = (*pMAPIInitialize)(NULL);
  256. if ( SUCCEEDED(hr) )
  257. {
  258. bMapiInitialized = TRUE;
  259. }
  260. }
  261. SizedSPropTagArray(1,prop) =
  262. {
  263. 1,
  264. {
  265. PR_PROFILE_HOME_SERVER
  266. }
  267. };
  268. if ( profile[0] )
  269. {
  270. hr = (*pMAPIAdminProfiles)(0,&prof);
  271. if ( FAILED(hr) )
  272. {
  273. LoadString(NULL,IDS_CannotAccessProfiles,errString,DIM(errString));
  274. goto err_continue;
  275. }
  276. hr = prof->AdminServices((WCHAR *)profile,NULL,NULL,0,&admin); // profile is ANSI, since MAPI_UNICODE flag not set.
  277. if ( FAILED(hr) )
  278. {
  279. LoadString(NULL,IDS_IProfAdmin_AdminServices,errString,DIM(errString));
  280. goto err_continue;
  281. }
  282. hr = admin->OpenProfileSection(&uid,NULL,0,&ps);
  283. if ( FAILED(hr) )
  284. {
  285. LoadString(NULL,IDS_IServiceAdmin_OpenProfileSection,errString,DIM(errString));;
  286. goto err_continue;
  287. }
  288. hr = ps->GetProps((LPSPropTagArray)&prop,0,&ulCount,&pVals);
  289. if ( FAILED(hr) )
  290. {
  291. LoadString(NULL,IDS_IProfSect_GetProps,errString,DIM(errString));;
  292. goto err_continue;
  293. }
  294. if ( ulCount && PROP_TYPE(pVals[0].ulPropTag) != PT_ERROR )
  295. {
  296. UStrCpy(computerName,pVals[0].Value.lpszA);
  297. }
  298. else
  299. {
  300. hr = E_FAIL;
  301. LoadString(NULL,IDS_DidntGetProp,errString,DIM(errString));;
  302. }
  303. }
  304. err_continue:
  305. if ( pVals )
  306. {
  307. (*pMAPIFreeBuffer)(pVals);
  308. }
  309. if ( prof )
  310. {
  311. prof->Release();
  312. }
  313. if ( admin )
  314. {
  315. admin->Release();
  316. }
  317. if ( ps )
  318. {
  319. ps->Release();
  320. }
  321. if ( FAILED(hr) )
  322. {
  323. if ( pVarSet )
  324. {
  325. pVarSet->put("McsMapiUtil.ErrorText",errString);
  326. }
  327. }
  328. return hr;
  329. }
  330. HRESULT ListContainers(WCHAR * profileName,IVarSet * pVarSet)
  331. {
  332. LPMAPISESSION sess = NULL;
  333. HRESULT hr = S_OK;
  334. LPABCONT pRootEntry = NULL; // root of AB
  335. LPMAPITABLE pRootTable = NULL; // root table
  336. LPSRowSet pRootRows = NULL;
  337. LPADRBOOK pAdrBook = NULL;
  338. ULONG ulObjectType = 0;
  339. FLAGS fLogonOptions = MAPI_NO_MAIL | MAPI_EXTENDED | MAPI_NEW_SESSION | MAPI_EXPLICIT_PROFILE;
  340. char title[MAX_PATH];
  341. char key[MAX_PATH];
  342. char containerDN[MAX_PATH] = "";
  343. long lVarSetNdx = 0;
  344. if ( ! LoadMAPI(pVarSet) )
  345. {
  346. return E_FAIL;
  347. }
  348. if ( ! bMapiInitialized )
  349. {
  350. hr = (*pMAPIInitialize)(NULL);
  351. if ( SUCCEEDED(hr) )
  352. {
  353. bMapiInitialized = TRUE;
  354. }
  355. }
  356. if ( SUCCEEDED(hr) )
  357. {
  358. hr = (*pMAPILogonEx)(0,profileName,NULL, fLogonOptions | MAPI_UNICODE, &sess);
  359. if ( SUCCEEDED(hr) )
  360. {
  361. SizedSPropTagArray(4, rgPropTags) =
  362. {
  363. 4,
  364. {
  365. PR_ENTRYID,
  366. PR_DISPLAY_NAME_A,
  367. PR_DEPTH,
  368. PR_AB_PROVIDER_ID
  369. }
  370. };
  371. hr = sess->OpenAddressBook(0, NULL, AB_NO_DIALOG , &pAdrBook);
  372. // TODO: error messages for these
  373. if ( SUCCEEDED(hr) )
  374. {
  375. // Open the root entry.
  376. hr = pAdrBook->OpenEntry(0, NULL, NULL, 0, &ulObjectType, (LPUNKNOWN*)&pRootEntry);
  377. }
  378. // Get its hierarchical table.
  379. if ( SUCCEEDED(hr) )
  380. {
  381. hr = pRootEntry->GetHierarchyTable( CONVENIENT_DEPTH, &pRootTable);
  382. }
  383. if ( SUCCEEDED(hr) )
  384. {
  385. // Get a list of all rows.
  386. hr = (*pHrQueryAllRows)(pRootTable, (LPSPropTagArray)&rgPropTags, NULL, NULL, 0, &pRootRows);
  387. }
  388. long lStartRow = -1; // Current start point for search.
  389. BOOL bAborted = FALSE; // Set TRUE if we punt due to mismatch.
  390. long lDepth; // Current depth of search.
  391. for (lDepth = 0; (lDepth < 1) && !bAborted; ++lDepth)
  392. {
  393. ++lStartRow;
  394. for (ULONG ulRow = (ULONG)lStartRow; ulRow < pRootRows->cRows; ++ulRow)
  395. {
  396. // Only display Exchange server containers
  397. if ( IsEqualMAPIUID(&exchSrvrGuid,pRootRows->aRow[ulRow].lpProps[3].Value.bin.lpb) )
  398. {
  399. long lRowDepth = pRootRows->aRow[ulRow].lpProps[2].Value.l;
  400. if ( PROP_TYPE(pRootRows->aRow[ulRow].lpProps[1].ulPropTag) == PT_STRING8 )
  401. {
  402. sprintf(title,"%s",pRootRows->aRow[ulRow].lpProps[1].Value.lpszA);
  403. sprintf(key,"Container.%ld",lVarSetNdx);
  404. pVarSet->put(key,title);
  405. sprintf(key,"Container.%ld.Depth",lVarSetNdx);
  406. pVarSet->put(key,lRowDepth);
  407. // Try to get the distinguished name, so that we can uniquely identify this container later
  408. LPSPropValue props = NULL;
  409. LPABCONT pEntry = NULL;
  410. ULONG ulCount;
  411. HRESULT hr2 = S_OK;
  412. ULONG ulObjectType;
  413. SizedSPropTagArray(2, rgPT2) =
  414. {
  415. 2,
  416. {
  417. PR_DISPLAY_NAME_A,
  418. PR_EMS_AB_OBJ_DIST_NAME_A
  419. }
  420. };
  421. if ( NOT_PT_ERROR(pRootRows->aRow[ulRow].lpProps[0]) )
  422. {
  423. hr2 = pAdrBook->OpenEntry(pRootRows->aRow[ulRow].lpProps[0].Value.bin.cb,
  424. (LPENTRYID)pRootRows->aRow[ulRow].lpProps[0].Value.bin.lpb,
  425. NULL,
  426. 0,
  427. &ulObjectType,
  428. (LPUNKNOWN *)&pEntry);
  429. }
  430. else
  431. {
  432. hr2 = E_FAIL;
  433. }
  434. if ( SUCCEEDED(hr2) )
  435. {
  436. hr2 = pEntry->GetProps((LPSPropTagArray)&rgPT2,0,&ulCount,&props);
  437. }
  438. if ( SUCCEEDED(hr2) )
  439. {
  440. if ( ulCount && NOT_PT_ERROR(props[1]) )
  441. {
  442. UStrCpy(containerDN,props[1].Value.lpszA);
  443. }
  444. if ( props )
  445. {
  446. (*pMAPIFreeBuffer)(props);
  447. }
  448. }
  449. if ( *containerDN )
  450. {
  451. sprintf(key,"Container.%ld.DistinguishedName",lVarSetNdx);
  452. pVarSet->put(key,containerDN);
  453. }
  454. }
  455. lVarSetNdx++;
  456. }
  457. }
  458. }
  459. sess->Logoff(0,0,0);
  460. }
  461. }
  462. if ( pRootRows )
  463. {
  464. (*pFreeProws)(pRootRows);
  465. }
  466. if ( pRootEntry )
  467. {
  468. pRootEntry->Release();
  469. }
  470. if ( pRootTable )
  471. {
  472. pRootTable->Release();
  473. }
  474. if ( pAdrBook )
  475. {
  476. pAdrBook->Release();
  477. }
  478. pVarSet->put("Container.NumItems",lVarSetNdx);
  479. return hr;
  480. }