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.

1074 lines
23 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. mapi.c
  5. Abstract:
  6. This file implements wrappers for all mapi apis.
  7. The wrappers are necessary because mapi does not
  8. implement unicode and this code must be non-unicode.
  9. Environment:
  10. WIN32 User Mode
  11. Author:
  12. Wesley Witt (wesw) 7-Aug-1996
  13. --*/
  14. #undef UNICODE
  15. #undef _UNICODE
  16. #include <windows.h>
  17. #include <mapiwin.h>
  18. #include <mapix.h>
  19. #include <stdio.h>
  20. #define INTERNAL 1
  21. #include "common.h"
  22. #define MAPISVC_INF "%windir%\\system32\\mapisvc.inf"
  23. #define PAB_FILE_NAME "%windir%\\msfax.pab"
  24. #define PST_FILE_NAME "%windir%\\msfax.pst"
  25. #define FAXAB_SERVICE_NAME "MSFAX AB"
  26. #define FAXXP_SERVICE_NAME "MSFAX XP"
  27. #define MSAB_SERVICE_NAME "MSPST AB"
  28. #define MSPST_SERVICE_NAME "MSPST MS"
  29. #define CONTAB_SERVICE_NAME "CONTAB"
  30. #define MSAB_SERVICE_NAME_W L"MSPST AB"
  31. #define MSPST_SERVICE_NAME_W L"MSPST MS"
  32. #define FAXAB_SERVICE_NAME_W L"MSFAX AB"
  33. #define CONTAB_SERVICE_NAME_W L"CONTAB"
  34. //
  35. // pab property tags
  36. //
  37. #define PR_PAB_PATH PROP_TAG( PT_TSTRING, 0x6600 )
  38. #define PR_PAB_PATH_W PROP_TAG( PT_UNICODE, 0x6600 )
  39. #define PR_PAB_PATH_A PROP_TAG( PT_STRING8, 0x6600 )
  40. #define PR_PAB_DET_DIR_VIEW_BY PROP_TAG( PT_LONG, 0x6601 )
  41. #define PAB_DIR_VIEW_FIRST_THEN_LAST 0
  42. #define PAB_DIR_VIEW_LAST_THEN_FIRST 1
  43. //
  44. // pst property tags
  45. //
  46. #define PR_PST_PATH PROP_TAG( PT_STRING8, 0x6700 )
  47. #define PR_PST_REMEMBER_PW PROP_TAG( PT_BOOLEAN, 0x6701 )
  48. #define PR_PST_ENCRYPTION PROP_TAG( PT_LONG, 0x6702 )
  49. #define PR_PST_PW_SZ_OLD PROP_TAG( PT_STRING8, 0x6703 )
  50. #define PR_PST_PW_SZ_NEW PROP_TAG( PT_STRING8, 0x6704 )
  51. #define PSTF_NO_ENCRYPTION ((DWORD)0x80000000)
  52. #define PSTF_COMPRESSABLE_ENCRYPTION ((DWORD)0x40000000)
  53. #define PSTF_BEST_ENCRYPTION ((DWORD)0x20000000)
  54. //
  55. // externs & globals
  56. //
  57. extern BOOL MapiAvail;
  58. static HMODULE MapiMod = NULL;
  59. static LPMAPIADMINPROFILES MapiAdminProfiles = NULL;
  60. static LPMAPIINITIALIZE MapiInitialize = NULL;
  61. static LPMAPILOGONEX MapiLogonEx;
  62. static LPMAPIUNINITIALIZE MapiUnInitialize = NULL;
  63. static LPMAPIFREEBUFFER pMAPIFreeBuffer = NULL;
  64. static LPPROFADMIN lpProfAdmin;
  65. static CHAR MapiSvcInf[MAX_PATH*2];
  66. static BOOL MapiStartedByLogon;
  67. static
  68. LPWSTR
  69. AnsiStringToUnicodeString(
  70. LPSTR AnsiString,
  71. LPWSTR UnicodeString
  72. )
  73. {
  74. DWORD Count;
  75. //
  76. // first see how big the buffer needs to be
  77. //
  78. Count = MultiByteToWideChar(
  79. CP_ACP,
  80. MB_PRECOMPOSED,
  81. AnsiString,
  82. -1,
  83. NULL,
  84. 0
  85. );
  86. //
  87. // i guess the input string is empty
  88. //
  89. if (!Count) {
  90. return NULL;
  91. }
  92. //
  93. // convert the string
  94. //
  95. Count = MultiByteToWideChar(
  96. CP_ACP,
  97. MB_PRECOMPOSED,
  98. AnsiString,
  99. -1,
  100. UnicodeString,
  101. Count
  102. );
  103. //
  104. // the conversion failed
  105. //
  106. if (!Count) {
  107. return NULL;
  108. }
  109. return UnicodeString;
  110. }
  111. static
  112. LPSTR
  113. UnicodeStringToAnsiString(
  114. LPWSTR UnicodeString,
  115. LPSTR AnsiString
  116. )
  117. {
  118. DWORD Count;
  119. //
  120. // first see how big the buffer needs to be
  121. //
  122. Count = WideCharToMultiByte(
  123. CP_ACP,
  124. 0,
  125. UnicodeString,
  126. -1,
  127. NULL,
  128. 0,
  129. NULL,
  130. NULL
  131. );
  132. //
  133. // i guess the input string is empty
  134. //
  135. if (!Count) {
  136. return NULL;
  137. }
  138. //
  139. // convert the string
  140. //
  141. Count = WideCharToMultiByte(
  142. CP_ACP,
  143. 0,
  144. UnicodeString,
  145. -1,
  146. AnsiString,
  147. Count,
  148. NULL,
  149. NULL
  150. );
  151. //
  152. // the conversion failed
  153. //
  154. if (!Count) {
  155. return NULL;
  156. }
  157. return AnsiString;
  158. }
  159. VOID
  160. MyWriteProfileString(
  161. LPTSTR SectionName,
  162. LPTSTR KeyName,
  163. LPTSTR Value
  164. )
  165. {
  166. WritePrivateProfileString(
  167. SectionName,
  168. KeyName,
  169. Value,
  170. MapiSvcInf
  171. );
  172. }
  173. VOID
  174. AddFaxAbToMapiSvcInf(
  175. VOID
  176. )
  177. {
  178. MyWriteProfileString( "Default Services", "MSFAX AB", "Fax Address Book" );
  179. MyWriteProfileString( "Services", "MSFAX AB", "Fax Address Book" );
  180. MyWriteProfileString( "MSFAX AB", "PR_DISPLAY_NAME", "Fax Address Book" );
  181. MyWriteProfileString( "MSFAX AB", "Providers", "MSFAX ABP" );
  182. MyWriteProfileString( "MSFAX AB", "PR_SERVICE_DLL_NAME", "FAXAB.DLL" );
  183. MyWriteProfileString( "MSFAX AB", "PR_SERVICE_SUPPORT_FILES", "FAXAB.DLL" );
  184. MyWriteProfileString( "MSFAX AB", "PR_SERVICE_ENTRY_NAME", "FABServiceEntry" );
  185. MyWriteProfileString( "MSFAX AB", "PR_RESOURCE_FLAGS", "SERVICE_SINGLE_COPY|SERVICE_NO_PRIMARY_IDENTITY" );
  186. MyWriteProfileString( "MSFAX ABP", "PR_PROVIDER_DLL_NAME", "FAXAB.DLL" );
  187. MyWriteProfileString( "MSFAX ABP", "PR_RESOURCE_TYPE", "MAPI_AB_PROVIDER" );
  188. MyWriteProfileString( "MSFAX ABP", "PR_DISPLAY_NAME", "Fax Address Book" );
  189. MyWriteProfileString( "MSFAX ABP", "PR_PROVIDER_DISPLAY", "Fax Address Book" );
  190. }
  191. VOID
  192. AddFaxXpToMapiSvcInf(
  193. VOID
  194. )
  195. {
  196. MyWriteProfileString( "Default Services", "MSFAX XP", "Fax Mail Transport" );
  197. MyWriteProfileString( "Services", "MSFAX XP", "Fax Mail Transport" );
  198. MyWriteProfileString( "MSFAX XP", "PR_DISPLAY_NAME", "Fax Mail Transport" );
  199. MyWriteProfileString( "MSFAX XP", "Providers", "MSFAX XPP" );
  200. MyWriteProfileString( "MSFAX XP", "PR_SERVICE_DLL_NAME", "FAXXP.DLL" );
  201. MyWriteProfileString( "MSFAX XP", "PR_SERVICE_SUPPORT_FILES", "FAXXP.DLL" );
  202. MyWriteProfileString( "MSFAX XP", "PR_SERVICE_ENTRY_NAME", "ServiceEntry" );
  203. MyWriteProfileString( "MSFAX XP", "PR_RESOURCE_FLAGS", "SERVICE_SINGLE_COPY|SERVICE_NO_PRIMARY_IDENTITY" );
  204. MyWriteProfileString( "MSFAX XPP", "PR_PROVIDER_DLL_NAME", "FAXXP.DLL" );
  205. MyWriteProfileString( "MSFAX XPP", "PR_RESOURCE_TYPE", "MAPI_TRANSPORT_PROVIDER" );
  206. MyWriteProfileString( "MSFAX XPP", "PR_RESOURCE_FLAGS", "STATUS_NO_DEFAULT_STORE" );
  207. MyWriteProfileString( "MSFAX XPP", "PR_DISPLAY_NAME", "Fax Mail Transport" );
  208. MyWriteProfileString( "MSFAX XPP", "PR_PROVIDER_DISPLAY", "Fax Mail Transport" );
  209. }
  210. VOID
  211. FreeSRowSet(
  212. LPSRowSet prws
  213. )
  214. {
  215. ULONG irw;
  216. if (!prws) {
  217. return;
  218. }
  219. for(irw = 0; irw < prws->cRows; irw++) {
  220. pMAPIFreeBuffer( prws->aRow[irw].lpProps );
  221. }
  222. pMAPIFreeBuffer( prws );
  223. }
  224. ULONG
  225. MLCRelease(
  226. LPUNKNOWN punk
  227. )
  228. {
  229. return (punk) ? punk->lpVtbl->Release(punk) : 0;
  230. }
  231. BOOL
  232. ValidateProp(
  233. LPSPropValue pval,
  234. ULONG ulPropTag
  235. )
  236. {
  237. if (pval->ulPropTag != ulPropTag) {
  238. pval->ulPropTag = ulPropTag;
  239. pval->Value.lpszA = "???";
  240. return TRUE;
  241. }
  242. return FALSE;
  243. }
  244. BOOL
  245. IsMapiServiceInstalled(
  246. LPWSTR ProfileNameW,
  247. LPWSTR ServiceNameW
  248. )
  249. {
  250. SPropTagArray taga = {2,{PR_DISPLAY_NAME,PR_SERVICE_NAME}};
  251. BOOL rVal = FALSE;
  252. LPSERVICEADMIN lpSvcAdmin;
  253. LPMAPITABLE pmt = NULL;
  254. LPSRowSet prws = NULL;
  255. DWORD i;
  256. LPSPropValue pval;
  257. CHAR ProfileName[128];
  258. CHAR ServiceName[64];
  259. if (!MapiAvail) {
  260. goto exit;
  261. }
  262. UnicodeStringToAnsiString( ProfileNameW, ProfileName );
  263. UnicodeStringToAnsiString( ServiceNameW, ServiceName );
  264. if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
  265. goto exit;
  266. }
  267. if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
  268. goto exit;
  269. }
  270. if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
  271. goto exit;
  272. }
  273. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  274. goto exit;
  275. }
  276. for (i=0; i<prws->cRows; i++) {
  277. pval = prws->aRow[i].lpProps;
  278. ValidateProp( &pval[0], PR_DISPLAY_NAME );
  279. ValidateProp( &pval[1], PR_SERVICE_NAME );
  280. if (_stricmp( pval[1].Value.lpszA, ServiceName ) == 0) {
  281. rVal = TRUE;
  282. break;
  283. }
  284. }
  285. exit:
  286. FreeSRowSet( prws );
  287. MLCRelease( (LPUNKNOWN)pmt );
  288. return rVal;
  289. }
  290. BOOL
  291. InstallFaxAddressBook(
  292. HWND hwnd,
  293. LPWSTR ProfileNameW
  294. )
  295. {
  296. SPropTagArray taga = {2,{PR_SERVICE_NAME,PR_SERVICE_UID}};
  297. SPropValue spvProps[2] = { 0 };
  298. BOOL rVal = FALSE;
  299. LPSERVICEADMIN lpSvcAdmin;
  300. CHAR ProfileName[128];
  301. CHAR Buffer[128];
  302. HRESULT hResult;
  303. LPMAPITABLE pmt = NULL;
  304. LPSRowSet prws = NULL;
  305. DWORD i;
  306. LPSPropValue pval;
  307. BOOL ConfigurePst = FALSE;
  308. BOOL ConfigurePab = FALSE;
  309. LPMAPISESSION Session = NULL;
  310. if (!MapiAvail) {
  311. goto exit;
  312. }
  313. UnicodeStringToAnsiString( ProfileNameW, ProfileName );
  314. if (IsMapiServiceInstalled( ProfileNameW, CONTAB_SERVICE_NAME_W )) {
  315. //
  316. // we don't need a pab/fab if we have the outlook contact address book
  317. //
  318. goto exit;
  319. }
  320. hResult = lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin );
  321. if (hResult) {
  322. goto exit;
  323. }
  324. if (!IsMapiServiceInstalled( ProfileNameW, MSAB_SERVICE_NAME_W )) {
  325. hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, MSAB_SERVICE_NAME, NULL, 0, 0 );
  326. if (hResult && hResult != MAPI_E_NO_ACCESS) {
  327. //
  328. // mapi will return MAPI_E_NO_ACCESS when the service is already installed
  329. //
  330. goto exit;
  331. }
  332. ConfigurePab = TRUE;
  333. }
  334. if (!IsMapiServiceInstalled( ProfileNameW, MSPST_SERVICE_NAME_W )) {
  335. hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, MSPST_SERVICE_NAME, NULL, 0, 0 );
  336. if (hResult && hResult != MAPI_E_NO_ACCESS) {
  337. //
  338. // mapi will return MAPI_E_NO_ACCESS when the service is already installed
  339. //
  340. goto exit;
  341. }
  342. ConfigurePst = TRUE;
  343. }
  344. if (!IsMapiServiceInstalled( ProfileNameW, FAXAB_SERVICE_NAME_W )) {
  345. hResult = lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, FAXAB_SERVICE_NAME, NULL, 0, 0 );
  346. if (hResult && hResult != MAPI_E_NO_ACCESS) {
  347. //
  348. // mapi will return MAPI_E_NO_ACCESS when the service is already installed
  349. //
  350. goto exit;
  351. }
  352. }
  353. //
  354. // now configure the address book and pst
  355. //
  356. if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
  357. goto exit;
  358. }
  359. if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
  360. goto exit;
  361. }
  362. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  363. goto exit;
  364. }
  365. for (i=0; i<prws->cRows; i++) {
  366. pval = prws->aRow[i].lpProps;
  367. ValidateProp( &pval[0], PR_SERVICE_NAME );
  368. if (ConfigurePab && (_stricmp( pval[0].Value.lpszA, MSAB_SERVICE_NAME) == 0)) {
  369. //
  370. // configure the pab service
  371. //
  372. ExpandEnvironmentStrings( PAB_FILE_NAME, Buffer, sizeof(Buffer) );
  373. spvProps[0].ulPropTag = PR_PAB_PATH;
  374. spvProps[0].Value.LPSZ = Buffer;
  375. spvProps[1].ulPropTag = PR_PAB_DET_DIR_VIEW_BY;
  376. spvProps[1].Value.ul = PAB_DIR_VIEW_FIRST_THEN_LAST;
  377. if (lpSvcAdmin->lpVtbl->ConfigureMsgService( lpSvcAdmin, (LPMAPIUID)pval[1].Value.bin.lpb, (ULONG) hwnd, 0, 2, spvProps )) {
  378. }
  379. }
  380. if (ConfigurePst && (_stricmp( pval[0].Value.lpszA, MSPST_SERVICE_NAME) == 0)) {
  381. //
  382. // configure the pst service
  383. //
  384. ExpandEnvironmentStrings( PST_FILE_NAME, Buffer, sizeof(Buffer) );
  385. spvProps[0].ulPropTag = PR_PST_PATH;
  386. spvProps[0].Value.LPSZ = Buffer;
  387. spvProps[1].ulPropTag = PR_PST_ENCRYPTION;
  388. spvProps[1].Value.ul = PSTF_NO_ENCRYPTION;
  389. if (lpSvcAdmin->lpVtbl->ConfigureMsgService( lpSvcAdmin, (LPMAPIUID)pval[1].Value.bin.lpb, (ULONG) hwnd, 0, 2, spvProps )) {
  390. }
  391. }
  392. }
  393. if (ConfigurePab || ConfigurePst) {
  394. __try {
  395. if (MapiLogonEx(
  396. 0,
  397. ProfileName,
  398. NULL,
  399. MAPI_NEW_SESSION | MAPI_EXTENDED,
  400. &Session
  401. ) == 0)
  402. {
  403. MapiStartedByLogon = TRUE;
  404. Session->lpVtbl->Logoff( Session, 0, 0, 0 );
  405. }
  406. } __except (EXCEPTION_EXECUTE_HANDLER) {
  407. }
  408. }
  409. rVal = TRUE;
  410. exit:
  411. FreeSRowSet( prws );
  412. MLCRelease( (LPUNKNOWN)pmt );
  413. return rVal;
  414. }
  415. BOOL
  416. InstallFaxTransport(
  417. LPWSTR ProfileNameW
  418. )
  419. {
  420. BOOL rVal = FALSE;
  421. LPSERVICEADMIN lpSvcAdmin;
  422. CHAR ProfileName[128];
  423. if (!MapiAvail) {
  424. goto exit;
  425. }
  426. UnicodeStringToAnsiString( ProfileNameW, ProfileName );
  427. if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
  428. goto exit;
  429. }
  430. if (lpSvcAdmin->lpVtbl->CreateMsgService( lpSvcAdmin, FAXXP_SERVICE_NAME, NULL, 0, 0 )) {
  431. goto exit;
  432. }
  433. rVal = TRUE;
  434. exit:
  435. return rVal;
  436. }
  437. BOOL
  438. CreateDefaultMapiProfile(
  439. LPWSTR ProfileNameW
  440. )
  441. {
  442. BOOL rVal = FALSE;
  443. CHAR ProfileName[128];
  444. if (!MapiAvail) {
  445. goto exit;
  446. }
  447. UnicodeStringToAnsiString( ProfileNameW, ProfileName );
  448. //
  449. // create the new profile
  450. //
  451. if (lpProfAdmin->lpVtbl->CreateProfile( lpProfAdmin, ProfileName, NULL, 0, 0 )) {
  452. goto exit;
  453. }
  454. if (lpProfAdmin->lpVtbl->SetDefaultProfile( lpProfAdmin, ProfileName, 0 )) {
  455. goto exit;
  456. }
  457. rVal = TRUE;
  458. exit:
  459. return rVal;
  460. }
  461. BOOL
  462. GetDefaultMapiProfile(
  463. LPWSTR ProfileName
  464. )
  465. {
  466. BOOL rVal = FALSE;
  467. LPMAPITABLE pmt = NULL;
  468. LPSRowSet prws = NULL;
  469. LPSPropValue pval;
  470. DWORD i;
  471. DWORD j;
  472. if (!MapiAvail) {
  473. goto exit;
  474. }
  475. //
  476. // get the mapi profile table object
  477. //
  478. if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
  479. goto exit;
  480. }
  481. //
  482. // get the actual profile data, FINALLY
  483. //
  484. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  485. goto exit;
  486. }
  487. //
  488. // enumerate the profiles looking for the default profile
  489. //
  490. for (i=0; i<prws->cRows; i++) {
  491. pval = prws->aRow[i].lpProps;
  492. for (j = 0; j < 2; j++) {
  493. if (pval[j].ulPropTag == PR_DEFAULT_PROFILE && pval[j].Value.b) {
  494. //
  495. // this is the default profile
  496. //
  497. AnsiStringToUnicodeString( pval[0].Value.lpszA, ProfileName );
  498. rVal = TRUE;
  499. break;
  500. }
  501. }
  502. }
  503. exit:
  504. FreeSRowSet( prws );
  505. MLCRelease( (LPUNKNOWN)pmt );
  506. return rVal;
  507. }
  508. BOOL
  509. DeleteMessageService(
  510. LPSTR ProfileName
  511. )
  512. {
  513. SPropTagArray taga = {2,{PR_SERVICE_NAME,PR_SERVICE_UID}};
  514. BOOL rVal = FALSE;
  515. LPSERVICEADMIN lpSvcAdmin;
  516. LPMAPITABLE pmt = NULL;
  517. LPSRowSet prws = NULL;
  518. DWORD i;
  519. LPSPropValue pval;
  520. if (!MapiAvail) {
  521. goto exit;
  522. }
  523. if (lpProfAdmin->lpVtbl->AdminServices( lpProfAdmin, ProfileName, NULL, 0, 0, &lpSvcAdmin )) {
  524. goto exit;
  525. }
  526. if (lpSvcAdmin->lpVtbl->GetMsgServiceTable( lpSvcAdmin, 0, &pmt )) {
  527. goto exit;
  528. }
  529. if (pmt->lpVtbl->SetColumns( pmt, &taga, 0 )) {
  530. goto exit;
  531. }
  532. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  533. goto exit;
  534. }
  535. for (i=0; i<prws->cRows; i++) {
  536. pval = prws->aRow[i].lpProps;
  537. ValidateProp( &pval[0], PR_SERVICE_NAME );
  538. if (_stricmp( pval[0].Value.lpszA, "MSFAX AB" ) == 0) {
  539. lpSvcAdmin->lpVtbl->DeleteMsgService( lpSvcAdmin, (LPMAPIUID) pval[1].Value.bin.lpb );
  540. }
  541. if (_stricmp( pval[0].Value.lpszA, "MSFAX XP" ) == 0) {
  542. lpSvcAdmin->lpVtbl->DeleteMsgService( lpSvcAdmin, (LPMAPIUID) pval[1].Value.bin.lpb );
  543. }
  544. }
  545. exit:
  546. FreeSRowSet( prws );
  547. MLCRelease( (LPUNKNOWN)pmt );
  548. return rVal;
  549. }
  550. BOOL
  551. DeleteFaxMsgServices(
  552. VOID
  553. )
  554. {
  555. BOOL rVal = FALSE;
  556. LPMAPITABLE pmt = NULL;
  557. LPSRowSet prws = NULL;
  558. LPSPropValue pval;
  559. DWORD i;
  560. DWORD j;
  561. if (!MapiAvail) {
  562. goto exit;
  563. }
  564. //
  565. // get the mapi profile table object
  566. //
  567. if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
  568. goto exit;
  569. }
  570. //
  571. // get the actual profile data, FINALLY
  572. //
  573. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  574. goto exit;
  575. }
  576. //
  577. // enumerate the profiles looking for the default profile
  578. //
  579. for (i=0; i<prws->cRows; i++) {
  580. pval = prws->aRow[i].lpProps;
  581. for (j = 0; j < 2; j++) {
  582. if (pval[j].ulPropTag == PR_DISPLAY_NAME) {
  583. DeleteMessageService( pval[j].Value.lpszA );
  584. break;
  585. }
  586. }
  587. }
  588. exit:
  589. FreeSRowSet( prws );
  590. MLCRelease( (LPUNKNOWN)pmt );
  591. return rVal;
  592. }
  593. BOOL
  594. IsExchangeInstalled(
  595. VOID
  596. )
  597. {
  598. BOOL MapiAvail = FALSE;
  599. CHAR MapiOption[4];
  600. HKEY hKey;
  601. LONG rVal;
  602. DWORD Bytes;
  603. DWORD Type;
  604. rVal = RegOpenKey(
  605. HKEY_LOCAL_MACHINE,
  606. "Software\\Microsoft\\Windows Messaging Subsystem",
  607. &hKey
  608. );
  609. if (rVal == ERROR_SUCCESS) {
  610. Bytes = sizeof(MapiOption);
  611. rVal = RegQueryValueEx(
  612. hKey,
  613. "MAPIX",
  614. NULL,
  615. &Type,
  616. (LPBYTE) MapiOption,
  617. &Bytes
  618. );
  619. if (rVal == ERROR_SUCCESS) {
  620. if (Bytes && MapiOption[0] == '1') {
  621. MapiAvail = TRUE;
  622. }
  623. }
  624. RegCloseKey( hKey );
  625. }
  626. return MapiAvail;
  627. }
  628. BOOL
  629. InitializeMapi(
  630. VOID
  631. )
  632. {
  633. MAPIINIT_0 MapiInit;
  634. ExpandEnvironmentStrings( MAPISVC_INF, MapiSvcInf, sizeof(MapiSvcInf) );
  635. MapiAvail = IsExchangeInstalled();
  636. if (!MapiAvail) {
  637. goto exit;
  638. }
  639. //
  640. // load the mapi dll
  641. //
  642. MapiMod = LoadLibrary( "mapi32.dll" );
  643. if (!MapiMod) {
  644. MapiAvail = FALSE;
  645. goto exit;
  646. }
  647. //
  648. // get the addresses of the mapi functions that we need
  649. //
  650. MapiAdminProfiles = (LPMAPIADMINPROFILES) GetProcAddress( MapiMod, "MAPIAdminProfiles" );
  651. MapiInitialize = (LPMAPIINITIALIZE) GetProcAddress( MapiMod, "MAPIInitialize" );
  652. MapiUnInitialize = (LPMAPIUNINITIALIZE) GetProcAddress( MapiMod, "MAPIUninitialize" );
  653. pMAPIFreeBuffer = (LPMAPIFREEBUFFER) GetProcAddress( MapiMod, "MAPIFreeBuffer" );
  654. MapiLogonEx = (LPMAPILOGONEX) GetProcAddress( MapiMod, "MAPILogonEx" );
  655. if ((!MapiAdminProfiles) || (!MapiInitialize) || (!MapiUnInitialize) || (!pMAPIFreeBuffer) || (!MapiLogonEx)) {
  656. MapiAvail = FALSE;
  657. goto exit;
  658. }
  659. //
  660. // initialize mapi for our calls
  661. //
  662. MapiInit.ulVersion = 0;
  663. MapiInit.ulFlags = 0;
  664. if (MapiInitialize( &MapiInit )) {
  665. MapiAvail = FALSE;
  666. goto exit;
  667. }
  668. //
  669. // get the admin profile object
  670. //
  671. if (MapiAdminProfiles( 0, &lpProfAdmin )) {
  672. MapiAvail = FALSE;
  673. goto exit;
  674. }
  675. exit:
  676. return MapiAvail;
  677. }
  678. BOOL
  679. GetMapiProfiles(
  680. HWND hwnd,
  681. DWORD ResourceId
  682. )
  683. {
  684. BOOL rVal = FALSE;
  685. HMODULE MapiMod = NULL;
  686. LPMAPITABLE pmt = NULL;
  687. LPSRowSet prws = NULL;
  688. LPSPropValue pval;
  689. DWORD i;
  690. //
  691. // add the default profile
  692. //
  693. SendDlgItemMessageA(
  694. hwnd,
  695. ResourceId,
  696. CB_ADDSTRING,
  697. 0,
  698. (LPARAM) "<Default Profile>"
  699. );
  700. SendDlgItemMessage(
  701. hwnd,
  702. ResourceId,
  703. CB_SETCURSEL,
  704. 0,
  705. 0
  706. );
  707. if (!MapiAvail) {
  708. goto exit;
  709. }
  710. //
  711. // get the mapi table object
  712. //
  713. if (lpProfAdmin->lpVtbl->GetProfileTable( lpProfAdmin, 0, &pmt )) {
  714. goto exit;
  715. }
  716. //
  717. // get the actual profile data, FINALLY
  718. //
  719. if (pmt->lpVtbl->QueryRows( pmt, 4000, 0, &prws )) {
  720. goto exit;
  721. }
  722. //
  723. // enumerate the profiles and put the name
  724. // of each profile in the combo box
  725. //
  726. for (i=0; i<prws->cRows; i++) {
  727. pval = prws->aRow[i].lpProps;
  728. SendDlgItemMessageA(
  729. hwnd,
  730. ResourceId,
  731. CB_ADDSTRING,
  732. 0,
  733. (LPARAM) pval[0].Value.lpszA
  734. );
  735. if (pval[2].Value.b) {
  736. //
  737. // this is the default profile
  738. //
  739. }
  740. }
  741. //
  742. // set the first one to be the current one
  743. //
  744. SendDlgItemMessage(
  745. hwnd,
  746. ResourceId,
  747. CB_SETCURSEL,
  748. 0,
  749. 0
  750. );
  751. rVal = TRUE;
  752. exit:
  753. FreeSRowSet( prws );
  754. MLCRelease( (LPUNKNOWN)pmt );
  755. return rVal;
  756. }
  757. BOOL
  758. GetExchangeInstallCommand(
  759. LPWSTR InstallCommandW
  760. )
  761. {
  762. HKEY hKey;
  763. LONG rVal;
  764. DWORD Bytes;
  765. DWORD Type;
  766. CHAR InstallCommand[512];
  767. rVal = RegOpenKey(
  768. HKEY_LOCAL_MACHINE,
  769. "Software\\Microsoft\\Windows Messaging Subsystem",
  770. &hKey
  771. );
  772. if (rVal == ERROR_SUCCESS) {
  773. Bytes = sizeof(InstallCommand);
  774. rVal = RegQueryValueEx(
  775. hKey,
  776. "InstallCmd",
  777. NULL,
  778. &Type,
  779. (LPBYTE) InstallCommand,
  780. &Bytes
  781. );
  782. RegCloseKey( hKey );
  783. if (rVal == ERROR_SUCCESS) {
  784. AnsiStringToUnicodeString( InstallCommand, InstallCommandW );
  785. return TRUE;
  786. }
  787. }
  788. return FALSE;
  789. }
  790. BOOL
  791. InstallExchangeClientExtension(
  792. LPSTR ExtensionName,
  793. LPSTR FileName,
  794. LPSTR ContextMask
  795. )
  796. {
  797. HKEY hKey;
  798. LONG rVal;
  799. CHAR Buffer[512];
  800. CHAR ExpandedFileName[MAX_PATH];
  801. rVal = RegOpenKey(
  802. HKEY_LOCAL_MACHINE,
  803. "Software\\Microsoft\\Exchange\\Client\\Extensions",
  804. &hKey
  805. );
  806. if (rVal == ERROR_SUCCESS) {
  807. ExpandEnvironmentStrings( FileName, ExpandedFileName, sizeof(ExpandedFileName) );
  808. sprintf( Buffer, "4.0;%s;1;%s", ExpandedFileName, ContextMask );
  809. rVal = RegSetValueEx(
  810. hKey,
  811. ExtensionName,
  812. 0,
  813. REG_SZ,
  814. (LPBYTE) Buffer,
  815. strlen(Buffer) + 1
  816. );
  817. RegCloseKey( hKey );
  818. return rVal == ERROR_SUCCESS;
  819. }
  820. return FALSE;
  821. }
  822. DWORD
  823. IsExchangeRunning(
  824. VOID
  825. )
  826. {
  827. #define MAX_TASKS 256
  828. DWORD TaskCount;
  829. PTASK_LIST TaskList = NULL;
  830. DWORD ExchangePid = 0;
  831. DWORD i;
  832. if (MapiStartedByLogon) {
  833. return 0;
  834. }
  835. TaskList = (PTASK_LIST) malloc( MAX_TASKS * sizeof(TASK_LIST) );
  836. if (!TaskList) {
  837. goto exit;
  838. }
  839. TaskCount = GetTaskList( TaskList, MAX_TASKS );
  840. if (!TaskCount) {
  841. goto exit;
  842. }
  843. for (i=0; i<TaskCount; i++) {
  844. if (_stricmp( TaskList[i].ProcessName, "exchng32.exe" ) == 0) {
  845. ExchangePid = TaskList[i].dwProcessId;
  846. break;
  847. } else
  848. if (_stricmp( TaskList[i].ProcessName, "mapisp32.exe" ) == 0) {
  849. ExchangePid = TaskList[i].dwProcessId;
  850. break;
  851. }
  852. }
  853. exit:
  854. free( TaskList );
  855. return ExchangePid;
  856. }