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.

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