Leaked source code of windows server 2003
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.

5087 lines
163 KiB

  1. /******************************************************************************
  2. FILENAME: wabimp.c
  3. MODULE: DLL for PAB, CSV, NetScape, Eudora and Athena16 address book
  4. conversions.
  5. PURPOSE: Contains modules which will implement importing
  6. MAPI PAB, CSV, NetScape, Eudora and Athena16
  7. address book to Athena32 (WAB).
  8. EXPORTED FUNCTIONS: STDMETHODIMP NetscapeImport(HWND hwnd, LPADRBOOK lpAdrBook,
  9. LPWABOBJECT lpWABObject,
  10. LPWAB_PROGRESS_CALLBACK lpProgressCB,
  11. LPWAB_IMPORT_OPTIONS lpOptions)
  12. STDMETHODIMP Athena16Import(HWND hwnd,LPADRBOOK lpAdrBook,
  13. LPWABOBJECT lpWABObject,
  14. LPWAB_PROGRESS_CALLBACK lpProgressCB,
  15. LPWAB_IMPORT_OPTIONS lpOptions)
  16. STDMETHODIMP EudoraImport(HWND hwnd,LPADRBOOK lpAdrBook,
  17. LPWABOBJECT lpWABObject,
  18. LPWAB_PROGRESS_CALLBACK lpProgressCB,
  19. LPWAB_IMPORT_OPTIONS lpOptions)
  20. Programmer(s): Arathi (NetQuest)
  21. Radhika (NetQuest)
  22. Krishnamoorthy SeethaRaman(NetQuest)
  23. Revision History:
  24. 4/7/97 - vikramm Fix Bugs: Netscape Display Names not being imported.
  25. "Replace Import" dialog has no parent.
  26. 4/8/97 - vikramm Fix Bugs: Handle Leak.
  27. Add code to look for additional Eudora address books
  28. that may be in subdirectories ...
  29. 4/9/97 - vikramm Change the Eudora registry search path ...
  30. Fix Bugs: Looking in wrong reg Key for Netscape on NT
  31. and wrongly assuming key exists for pre netscape 3.0
  32. Change dialog messages.
  33. *******************************************************************************/
  34. //Includes
  35. #define _WABIMP_C
  36. #include "_comctl.h"
  37. #include <windows.h>
  38. #include <commctrl.h>
  39. #include <mapix.h>
  40. #include <wab.h>
  41. #include <wabmig.h>
  42. #include <wabguid.h>
  43. #include <wabdbg.h>
  44. #include <dbgutil.h>
  45. #include "..\..\wab32res\resrc2.h"
  46. #include <wabimp.h>
  47. #include <string.h>
  48. #include <advpub.h>
  49. #include <shlwapi.h>
  50. // Per-process Globals
  51. TCHAR szGlobalAlloc[MAX_MESSAGE]; // Buffer used for LoadString
  52. TCHAR szGlobalTempAlloc[MAX_MESSAGE];
  53. const TCHAR szTextFilter[] = "*.txt";
  54. const TCHAR szAllFilter[] = "*.*";
  55. const TCHAR szMSN[] = "MSN";
  56. const TCHAR szMSNINET[] = "MSNINET";
  57. const TCHAR szCOMPUSERVE[] = "COMPUSERVE";
  58. const TCHAR szFAX[] = "FAX";
  59. const TCHAR szSMTP[] = "SMTP";
  60. const TCHAR szMS[] = "MS";
  61. const TCHAR szEX[] = "EX";
  62. const TCHAR szX400[] = "X400";
  63. const TCHAR szMSA[] = "MSA";
  64. const TCHAR szMAPIPDL[] = "MAPIPDL";
  65. const TCHAR szEmpty[] = "";
  66. const TCHAR szDescription[] = "description";
  67. const TCHAR szDll[] = "dll";
  68. const TCHAR szEntry[] = "entry";
  69. const TCHAR szEXPORT[] = "EXPORT";
  70. const TCHAR szIMPORT[] = "IMPORT";
  71. const TCHAR szAtSign[] = "@";
  72. const TCHAR szMSNpostfix[] = "@msn.com";
  73. const TCHAR szCOMPUSERVEpostfix[] = "@compuserve.com";
  74. LPENTRY_SEEN lpEntriesSeen = NULL;
  75. ULONG ulEntriesSeen = 0;
  76. ULONG ulMaxEntries = 0;
  77. const LPTSTR szWABKey = "Software\\Microsoft\\WAB";
  78. LPTARGET_INFO rgTargetInfo = NULL;
  79. HINSTANCE hInst = NULL;
  80. HINSTANCE hInstApp = NULL;
  81. //
  82. // Properties to get for each row of the contents table
  83. //
  84. const SizedSPropTagArray(iptaColumnsMax, ptaColumns) =
  85. {
  86. iptaColumnsMax,
  87. {
  88. PR_OBJECT_TYPE,
  89. PR_ENTRYID,
  90. PR_DISPLAY_NAME,
  91. PR_EMAIL_ADDRESS,
  92. }
  93. };
  94. const SizedSPropTagArray(ieidMax, ptaEid)=
  95. {
  96. ieidMax,
  97. {
  98. PR_ENTRYID,
  99. }
  100. };
  101. const SizedSPropTagArray(iconMax, ptaCon)=
  102. {
  103. iconMax,
  104. {
  105. PR_DEF_CREATE_MAILUSER,
  106. PR_DEF_CREATE_DL,
  107. }
  108. };
  109. // Global WAB Allocator access functions
  110. //
  111. typedef struct _WAB_ALLOCATORS {
  112. LPWABOBJECT lpWABObject;
  113. LPWABALLOCATEBUFFER lpAllocateBuffer;
  114. LPWABALLOCATEMORE lpAllocateMore;
  115. LPWABFREEBUFFER lpFreeBuffer;
  116. } WAB_ALLOCATORS, *LPWAB_ALLOCATORS;
  117. WAB_ALLOCATORS WABAllocators = {0};
  118. /******************************************************************************
  119. Name : SetGlobalBufferFunctions
  120. Purpose : Set the global buffer functions based on methods from
  121. the WAB object.
  122. Parameters: lpWABObject = the open wab object
  123. Returns : none
  124. Comment :
  125. ******************************************************************************/
  126. void SetGlobalBufferFunctions(LPWABOBJECT lpWABObject)
  127. {
  128. if (lpWABObject && ! WABAllocators.lpWABObject) {
  129. WABAllocators.lpAllocateBuffer = lpWABObject->lpVtbl->AllocateBuffer;
  130. WABAllocators.lpAllocateMore = lpWABObject->lpVtbl->AllocateMore;
  131. WABAllocators.lpFreeBuffer = lpWABObject->lpVtbl->FreeBuffer;
  132. WABAllocators.lpWABObject = lpWABObject;
  133. }
  134. }
  135. /******************************************************************************
  136. Name : WABAllocateBuffer
  137. Purpose : Use the WAB Allocator
  138. Parameters: cbSize = size to allocate
  139. lppBuffer = returned buffer
  140. Returns : SCODE
  141. Comment :
  142. *******************************************************************************/
  143. SCODE WABAllocateBuffer(ULONG cbSize, LPVOID FAR * lppBuffer)
  144. {
  145. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateBuffer) {
  146. return(WABAllocators.lpAllocateBuffer(WABAllocators. lpWABObject, cbSize,
  147. lppBuffer));
  148. } else {
  149. return(MAPI_E_INVALID_OBJECT);
  150. }
  151. }
  152. /******************************************************************************
  153. Name : WABAllocateMore
  154. Purpose : Use the WAB Allocator
  155. Parameters: cbSize = size to allocate
  156. lpObject = existing allocation
  157. lppBuffer = returned buffer
  158. Returns : SCODE
  159. Comment :
  160. *******************************************************************************/
  161. SCODE WABAllocateMore(ULONG cbSize, LPVOID lpObject, LPVOID FAR * lppBuffer)
  162. {
  163. if (WABAllocators.lpWABObject && WABAllocators.lpAllocateMore) {
  164. return(WABAllocators.lpAllocateMore(WABAllocators. lpWABObject, cbSize,
  165. lpObject, lppBuffer));
  166. } else {
  167. return(MAPI_E_INVALID_OBJECT);
  168. }
  169. }
  170. /******************************************************************************
  171. Name : WABFreeBuffer
  172. Purpose : Use the WAB Allocator
  173. Parameters: lpBuffer = buffer to free
  174. Returns : SCODE
  175. Comment :
  176. *******************************************************************************/
  177. SCODE WABFreeBuffer(LPVOID lpBuffer)
  178. {
  179. if (WABAllocators.lpWABObject && WABAllocators.lpFreeBuffer) {
  180. return(WABAllocators.lpFreeBuffer(WABAllocators.lpWABObject, lpBuffer));
  181. } else {
  182. return(MAPI_E_INVALID_OBJECT);
  183. }
  184. }
  185. /***************************************************************************
  186. Name : IsSpace
  187. Purpose : Does the single or DBCS character represent a space?
  188. Parameters: lpChar -> SBCS or DBCS character
  189. Returns : TRUE if this character is a space
  190. Comment :
  191. ***************************************************************************/
  192. BOOL IsSpace(LPTSTR lpChar) {
  193. Assert(lpChar);
  194. if (*lpChar) {
  195. if (IsDBCSLeadByte(*lpChar)) {
  196. WORD CharType[2] = {0};
  197. GetStringTypeA(LOCALE_USER_DEFAULT,
  198. CT_CTYPE1,
  199. lpChar,
  200. 2, // Double-Byte
  201. CharType);
  202. return(CharType[0] & C1_SPACE);
  203. } else {
  204. return(*lpChar == ' ');
  205. }
  206. } else {
  207. return(FALSE); // end of string
  208. }
  209. }
  210. /******************************************************************************
  211. Name : NetscapeImport
  212. Purpose : Entry Point for NetScape Addressbook import
  213. Parameters: hwnd = Handle to the parent Window
  214. lpAdrBook = pointer to the IADRBOOK interface
  215. lpWABObject = pointer to IWABOBJECT interface
  216. lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  217. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  218. Returns :
  219. Comment :
  220. /******************************************************************************/
  221. STDMETHODIMP NetscapeImport(HWND hwnd, LPADRBOOK lpAdrBook,
  222. LPWABOBJECT lpWABObject,
  223. LPWAB_PROGRESS_CALLBACK lpProgressCB,
  224. LPWAB_IMPORT_OPTIONS lpOptions)
  225. {
  226. HRESULT hResult = S_OK;
  227. SetGlobalBufferFunctions(lpWABObject);
  228. hResult = MigrateUser(hwnd, lpOptions, lpProgressCB, lpAdrBook);
  229. if (hResult == hrMemory) {
  230. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc));
  231. MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  232. }
  233. return(hResult);
  234. }
  235. /******************************************************************************
  236. Name : Athena16Import
  237. Purpose : Entry Point for Athena 16 Addressbook import
  238. Parameters: hwnd = Handle to the parent Window
  239. lpAdrBook = pointer to the IADRBOOK interface
  240. lpWABObject = poiinter to IWABOBJECT interface
  241. lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  242. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  243. Returns :
  244. Comment :
  245. /******************************************************************************/
  246. STDMETHODIMP Athena16Import(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject,
  247. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
  248. {
  249. HRESULT hResult = S_OK;
  250. SetGlobalBufferFunctions(lpWABObject);
  251. hResult = MigrateAthUser(hwnd, lpOptions, lpProgressCB,lpAdrBook);
  252. return(hResult);
  253. }
  254. /******************************************************************************
  255. Name : EudoraImport
  256. Purpose : Entry Point for Eudora Addressbook import
  257. Parameters: hwnd = Handle to the parent Window
  258. lpAdrBook = pointer to the IADRBOOK interface
  259. lpWABObject = poiinter to IWABOBJECT interface
  260. lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  261. lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  262. Returns :
  263. Comment :
  264. /******************************************************************************/
  265. STDMETHODIMP EudoraImport(HWND hwnd,LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject,
  266. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
  267. {
  268. LPABCONT lpWabContainer = NULL;
  269. HRESULT hResult = S_OK;
  270. SetGlobalBufferFunctions(lpWABObject);
  271. if (FAILED(hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) {
  272. goto Error;
  273. }
  274. hResult = MigrateEudoraUser(hwnd,lpWabContainer,lpOptions,lpProgressCB,lpAdrBook);
  275. if (hResult == hrMemory) {
  276. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc));
  277. MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  278. }
  279. if (lpWabContainer) {
  280. lpWabContainer->lpVtbl->Release(lpWabContainer);
  281. }
  282. Error:
  283. return(hResult);
  284. }
  285. STDMETHODIMP NetscapeExport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject,
  286. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
  287. {
  288. SCODE sc = SUCCESS_SUCCESS;
  289. HRESULT hResult = hrSuccess;
  290. SetGlobalBufferFunctions(lpWABObject);
  291. return(hResult);
  292. }
  293. STDMETHODIMP Athena16Export(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject,
  294. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
  295. {
  296. SCODE sc = SUCCESS_SUCCESS;
  297. HRESULT hResult = hrSuccess;
  298. SetGlobalBufferFunctions(lpWABObject);
  299. return(hResult);
  300. }
  301. STDMETHODIMP EudoraExport(HWND hwnd, LPADRBOOK lpAdrBook, LPWABOBJECT lpWABObject,
  302. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPWAB_IMPORT_OPTIONS lpOptions)
  303. {
  304. SCODE sc = SUCCESS_SUCCESS;
  305. HRESULT hResult = hrSuccess;
  306. SetGlobalBufferFunctions(lpWABObject);
  307. return(hResult);
  308. }
  309. /******************************************************************************
  310. *********************NetScape Functions***************************************
  311. ******************************************************************************
  312. * FUNCTION NAME:MigrateUser
  313. *
  314. * PURPOSE: Get the installation path of the address book and starts processing
  315. * the NetScape address book
  316. *
  317. * PARAMETERS: hwnd = Handle to the parent Window
  318. * lpAdrBook = pointer to the IADRBOOK interface
  319. * lpWABObject = poiinter to IWABOBJECT interface
  320. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  321. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  322. *
  323. * RETURNS: HRESULT
  324. ******************************************************************************/
  325. HRESULT MigrateUser(HWND hwnd, LPWAB_IMPORT_OPTIONS lpOptions,
  326. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  327. {
  328. TCHAR szFileName[MAX_FILE_NAME];
  329. HRESULT hResult;
  330. HANDLE h1 = NULL;
  331. WIN32_FIND_DATA lpFindFileData;
  332. if (0 != (hResult= GetRegistryPath(szFileName, ARRAYSIZE(szFileName), NETSCAPE))) {
  333. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_STRING_SELECTPATH), ARRAYSIZE(szGlobalTempAlloc));
  334. if (IDNO ==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_YESNO)) {
  335. return(ResultFromScode(MAPI_E_USER_CANCEL));
  336. }
  337. if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), NETSCAPE)) {
  338. return(ResultFromScode(MAPI_E_USER_CANCEL));
  339. }
  340. } else {
  341. StrCatBuff(szFileName, LoadStringToGlobalBuffer(IDS_NETSCAPE_ADDRESSBOOK), ARRAYSIZE(szFileName));
  342. h1 =FindFirstFile(szFileName,&lpFindFileData);
  343. if (h1 == INVALID_HANDLE_VALUE) {
  344. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ADDRESS_HTM), ARRAYSIZE(szGlobalTempAlloc));
  345. if (IDNO==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_YESNO)) {
  346. h1=NULL;
  347. return(ResultFromScode(MAPI_E_USER_CANCEL));
  348. }
  349. if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), NETSCAPE)) {
  350. h1=NULL;
  351. return(ResultFromScode(MAPI_E_USER_CANCEL));
  352. }
  353. }
  354. FindClose(h1);
  355. }
  356. hResult = ParseAddressBook(hwnd,szFileName,lpOptions,lpProgressCB,lpAdrBook);
  357. return(hResult);
  358. }
  359. /******************************************************************************
  360. * FUNCTION NAME:ParseAddressBook
  361. *
  362. * PURPOSE: Open the address book file ,put the data in a buffer and call
  363. * the ParseAddress function to do the parsing
  364. *
  365. * PARAMETERS: hwnd = Handle to the parent Window
  366. * lpAdrBook = pointer to the IADRBOOK interface
  367. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  368. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  369. * szFileName = Filename of the address book
  370. *
  371. * RETURNS: HRESULT
  372. ******************************************************************************/
  373. HRESULT ParseAddressBook(HWND hwnd, LPTSTR szFileName, LPWAB_IMPORT_OPTIONS lpOptions,
  374. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  375. {
  376. ULONG ulRead = 0;
  377. HANDLE hFile = NULL;
  378. ULONG ulFileSize = 0;
  379. LPTSTR szBuffer = NULL;
  380. HRESULT hResult;
  381. hFile = CreateFile(szFileName,
  382. GENERIC_READ,
  383. FILE_SHARE_READ,
  384. NULL,
  385. OPEN_EXISTING,
  386. FILE_FLAG_SEQUENTIAL_SCAN,
  387. NULL);
  388. if (INVALID_HANDLE_VALUE == hFile) {
  389. return(ResultFromScode(MAPI_E_NOT_FOUND));
  390. }
  391. ulFileSize = GetFileSize(hFile,NULL);
  392. szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulFileSize+1));
  393. if (!szBuffer) {
  394. hResult = hrMemory;
  395. goto Error;
  396. }
  397. if (! ReadFile(hFile, szBuffer, ulFileSize, &ulRead, NULL)) {
  398. goto Error;
  399. }
  400. hResult = ParseAddress(hwnd,szBuffer,lpOptions,lpProgressCB,lpAdrBook);
  401. Error:
  402. if (szBuffer) {
  403. LocalFree((HLOCAL)szBuffer);
  404. }
  405. if (hFile) {
  406. CloseHandle(hFile);
  407. }
  408. return(hResult);
  409. }
  410. /******************************************************************************
  411. * FUNCTION NAME:ParseAddress
  412. *
  413. * PURPOSE: Gets the address portion of the address book in a buffer and calls
  414. * ProcessAdrBuffer for further processing
  415. *
  416. * PARAMETERS: hwnd = Handle to the parent Window
  417. * lpAdrBook = pointer to the IADRBOOK interface
  418. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  419. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  420. * szBuffer = Address book in a buffer
  421. *
  422. * RETURNS: HRESULT
  423. ******************************************************************************/
  424. HRESULT ParseAddress(HWND hwnd, LPTSTR szBuffer, LPWAB_IMPORT_OPTIONS lpOptions,
  425. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  426. {
  427. LPTSTR AdrBuffer = NULL; //address starting <DL> to ending </DL>
  428. HRESULT hResult = S_OK;
  429. hResult = GetAdrBuffer(&szBuffer, &AdrBuffer);
  430. if (hrMemory == hResult)
  431. goto Error;
  432. if (hrINVALIDFILE == hResult) {
  433. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_INVALID_FILE), ARRAYSIZE(szGlobalTempAlloc));
  434. MessageBox(hwnd,szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_ERROR), MB_OK);
  435. hResult = ResultFromScode(MAPI_E_CALL_FAILED);
  436. goto Error;
  437. }
  438. hResult = ProcessAdrBuffer(hwnd,AdrBuffer,lpOptions,lpProgressCB,lpAdrBook);
  439. Error:
  440. if (AdrBuffer)
  441. LocalFree((HLOCAL)AdrBuffer);
  442. return(hResult);
  443. }
  444. /******************************************************************************
  445. * FUNCTION NAME: GetAdrBuffer
  446. *
  447. * PURPOSE: Gets the address portion of the address book in a buffer
  448. *
  449. * PARAMETERS: szBuffer = points to the complete address book
  450. * szAdrBuffer = output buffer which gets filled up
  451. *
  452. * RETURNS: HRESULT
  453. ******************************************************************************/
  454. HRESULT GetAdrBuffer(LPTSTR *szBuffer, LPTSTR *szAdrBuffer)
  455. {
  456. LPTSTR szAdrStart = NULL, szAdrBufStart = NULL, szAdrBufEnd = NULL;
  457. ULONG ulSize = 0;
  458. // Get Adr Start
  459. szAdrBufStart = GetAdrStart((*szBuffer));
  460. szAdrBufEnd = GetAdrEnd((*szBuffer));
  461. if (NULL == szAdrBufStart || NULL == szAdrBufEnd) {
  462. return(hrINVALIDFILE);
  463. }
  464. if (szAdrBufEnd - szAdrBufStart) {
  465. ulSize = (ULONG) (szAdrBufEnd - szAdrBufStart);
  466. }
  467. if (ulSize) {
  468. *szAdrBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize+1));
  469. if (!*szAdrBuffer) {
  470. return(hrMemory);
  471. }
  472. StrCpyN(*szAdrBuffer, szAdrBufStart, ulSize+1);
  473. *szBuffer= szAdrBufEnd;
  474. }
  475. return(S_OK);
  476. }
  477. /******************************************************************************
  478. * FUNCTION NAME:ProcessAdrBuffer
  479. *
  480. * PURPOSE: Gets the individual address and then fills up the WAB by calling
  481. appropriate functions.
  482. *
  483. * PARAMETERS: hwnd = Handle to the parent Window
  484. * lpAdrBook = pointer to the IADRBOOK interface
  485. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  486. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  487. * AdrBuffer = all the addresses in a buffer
  488. *
  489. * RETURNS: HRESULT
  490. ******************************************************************************/
  491. HRESULT ProcessAdrBuffer(HWND hwnd, LPTSTR AdrBuffer, LPWAB_IMPORT_OPTIONS lpOptions,
  492. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  493. {
  494. LPTSTR szL = NULL, szDesc = NULL, szLine = NULL, szDescription = NULL;
  495. ULONG ulCount = 0;
  496. NSADRBOOK nsAdrBook;
  497. ULONG cCurrent = 0;
  498. LPSBinary lpsbinary = NULL;
  499. LPABCONT lpWabContainer = NULL;
  500. ULONG cProps;
  501. HRESULT hResult = S_OK;
  502. static LPSPropValue sProp = NULL;
  503. WAB_PROGRESS Progress;
  504. ULONG ul = 0;
  505. ul = GetAddressCount(AdrBuffer);
  506. if (0 == ul) {
  507. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NO_ENTRY), ARRAYSIZE(szGlobalTempAlloc));
  508. MessageBox(hwnd,szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  509. return(S_OK);
  510. }
  511. ulCount=GetAddrCount((AdrBuffer));
  512. if (ulCount) {
  513. lpsbinary = (LPSBinary)LocalAlloc(LMEM_FIXED,((ulCount+1)*sizeof(SBinary)));
  514. if (! lpsbinary) {
  515. return(hrMemory);
  516. }
  517. memset(lpsbinary,0,((ulCount+1) * sizeof(SBinary)));
  518. }
  519. if (0 != (hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) {
  520. return(hResult);
  521. }
  522. if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer,
  523. (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) {
  524. if (hResult == MAPI_W_ERRORS_RETURNED) {
  525. WABFreeBuffer(sProp);
  526. sProp = NULL;
  527. }
  528. goto Error;
  529. }
  530. Progress.denominator = ul;
  531. Progress.numerator = 0;
  532. Progress.lpText = NULL;
  533. ul = 0;
  534. while (GetAdrLine(&AdrBuffer, &szL, &szDesc)) {
  535. szLine = szL;
  536. szDescription = szDesc;
  537. Progress.numerator = ul++;
  538. lpProgressCB(hwnd,&Progress);
  539. if (0 == (hResult = ProcessLn(&szLine, &szDescription,&nsAdrBook,&AdrBuffer))) {
  540. if (nsAdrBook.DistList) {
  541. hResult=FillDistList(hwnd, lpWabContainer,sProp,lpOptions,&nsAdrBook,
  542. lpsbinary,lpAdrBook);
  543. } else {
  544. hResult = FillMailUser(hwnd, lpWabContainer,sProp, lpOptions,(void *)&nsAdrBook,
  545. lpsbinary,0,NETSCAPE);
  546. }
  547. }
  548. if (szL) {
  549. LocalFree((HLOCAL)szL);
  550. szL = NULL;
  551. }
  552. if (szDesc) {
  553. LocalFree(szDesc);
  554. szDesc = NULL;
  555. }
  556. if (nsAdrBook.Description) {
  557. LocalFree((HLOCAL)nsAdrBook.Description);
  558. }
  559. nsAdrBook.Description = NULL;
  560. if (nsAdrBook.NickName) {
  561. LocalFree((HLOCAL)nsAdrBook.NickName);
  562. }
  563. nsAdrBook.NickName = NULL;
  564. if (nsAdrBook.Address) {
  565. LocalFree((HLOCAL)nsAdrBook.Address);
  566. }
  567. nsAdrBook.Address = NULL;
  568. if (nsAdrBook.Entry) {
  569. LocalFree((HLOCAL)nsAdrBook.Entry);
  570. }
  571. nsAdrBook.Entry = NULL;
  572. if (hrMemory == hResult) {
  573. break;
  574. }
  575. }
  576. if (sProp) {
  577. WABFreeBuffer(sProp);
  578. sProp = NULL;
  579. }
  580. Error:
  581. if (NULL != lpsbinary) {
  582. for (ul=0; ul < ulCount + 1; ul++) {
  583. if (lpsbinary[ul].lpb) {
  584. LocalFree((HLOCAL)lpsbinary[ul].lpb);
  585. lpsbinary[ul].lpb=NULL;
  586. }
  587. }
  588. LocalFree((HLOCAL)lpsbinary);
  589. lpsbinary = NULL;
  590. }
  591. if (lpWabContainer) {
  592. lpWabContainer->lpVtbl->Release(lpWabContainer);
  593. lpWabContainer = NULL;
  594. }
  595. return(S_OK);
  596. }
  597. /******************************************************************************
  598. * FUNCTION NAME:GetAdrLine
  599. *
  600. * PURPOSE: To get an address line and description of the address in a buffer
  601. * from NetScape address book.
  602. *
  603. * PARAMETERS: szCurPointer = pointer to the buffer containing the entire
  604. * addresses.
  605. * szBuffer = pointer to the address line buffer
  606. * szDesc = pointer to the description buffeer.
  607. *
  608. * RETURNS: BOOL
  609. ******************************************************************************/
  610. BOOL GetAdrLine(LPTSTR *szCurPointer, LPTSTR *szBuffer, LPTSTR *szDesc)
  611. {
  612. static TCHAR szAdrStart[] = "<DT>";
  613. static TCHAR szAdrEnd[] = "</A>";
  614. static TCHAR szDescStart[] = "<DD>";
  615. static TCHAR szDistListEnd[] = "</H3>";
  616. LPTSTR temp = NULL;
  617. BOOL flag = TRUE;
  618. ULONG ulSize = 0;
  619. LPTSTR szS = NULL, szE = NULL, szD = NULL, szDE = NULL ,szH = NULL;
  620. szS = strstr(*szCurPointer, szAdrStart);
  621. szE = strstr(*szCurPointer, szAdrEnd);
  622. szH = strstr(*szCurPointer, szDistListEnd);
  623. if (szS) {
  624. szS += lstrlen(szAdrStart);
  625. } else {
  626. return(FALSE);
  627. }
  628. if (szE != NULL) {
  629. if (szH != NULL && szE <szH) {
  630. ulSize = (ULONG) (szE - szS + 1);
  631. flag = TRUE;
  632. } else {
  633. if (szH != NULL) {
  634. ulSize = (ULONG) (szH - szS + 1);
  635. flag = FALSE;
  636. } else {
  637. ulSize = (ULONG) (szE - szS + 1);
  638. flag = TRUE;
  639. }
  640. }
  641. } else {
  642. if (szH != NULL) {
  643. ulSize = (ULONG) (szH - szS + 1);
  644. flag = FALSE;
  645. }
  646. }
  647. if (ulSize) {
  648. *szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize + 1));
  649. if (! *szBuffer) {
  650. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc));
  651. MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  652. return(FALSE);
  653. }
  654. StrCpyN(*szBuffer, szS,ulSize);
  655. }
  656. szD = strstr(*szCurPointer, szDescStart);
  657. // check if DT flag comes before DD. that means DD is not for this address
  658. temp = strstr((szS + 4), "<DT>");
  659. if ((temp != NULL && temp < szD) || (szD == NULL)) {
  660. *szDesc = NULL;
  661. if (flag) {
  662. *szCurPointer = szE + lstrlen(szAdrEnd);
  663. } else {
  664. *szCurPointer = szH + lstrlen(szDistListEnd);
  665. }
  666. return(TRUE);
  667. }
  668. temp = NULL;
  669. // Description will be uptil next \r\n
  670. if (szD) {
  671. szD += lstrlen(szDescStart);
  672. szDE = strstr(szD, LoadStringToGlobalBuffer(IDS_EOL));
  673. if (szDE) {
  674. szDE -= 1;
  675. }
  676. ulSize = (ULONG) (szDE - szD + 1);
  677. }
  678. if (ulSize) {
  679. *szDesc = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize+1));
  680. if (! *szDesc) {
  681. StrCpyN(szGlobalTempAlloc,LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc));
  682. MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  683. return(FALSE);
  684. }
  685. StrCpyN(*szDesc, szD, ulSize);
  686. *szCurPointer = szDE + 2;
  687. } else {
  688. *szDesc = NULL;
  689. *szCurPointer = szDE + 2;
  690. }
  691. return(TRUE);
  692. }
  693. /******************************************************************************
  694. * FUNCTION NAME:ProcessLn
  695. *
  696. * PURPOSE: Process an address line and fill the NSADRBOOK structure.
  697. *
  698. * PARAMETERS: szL = pointer to the address line buffer
  699. * szDesc = pointer to the description buffer
  700. * nsAdrBook = pointer to the NSADRBOOK structure.
  701. *
  702. * RETURNS: HRESULT
  703. ******************************************************************************/
  704. HRESULT ProcessLn(LPTSTR *szL, LPTSTR *szDesc, NSADRBOOK *nsAdrBook, LPTSTR *szBuffer)
  705. {
  706. LPTSTR szPrmStart = NULL, szPrmEnd = NULL;
  707. TCHAR cMailto[MAX_STRING_SIZE];
  708. TCHAR cAliasId[MAX_STRING_SIZE];
  709. TCHAR cNickname[MAX_STRING_SIZE];
  710. BOOL flag = FALSE; //To check for distribution list
  711. LPNSDISTLIST present=NULL, previous=NULL;
  712. TCHAR *tmpStr = NULL;
  713. ULONG ulSize = 0;
  714. LPTSTR szDistStart = NULL, szDistEnd = NULL, szDistBuffer = NULL, szName = NULL;
  715. LPTSTR temp = NULL;
  716. BOOL NoNickName = FALSE;
  717. HRESULT hResult = S_OK;
  718. StrCpyN(cMailto, LoadStringToGlobalBuffer(IDS_MAILTO), ARRAYSIZE(cMailto));
  719. StrCpyN(cAliasId, LoadStringToGlobalBuffer(IDS_ALIAS_ID), ARRAYSIZE(cAliasId));
  720. StrCpyN(cNickname, LoadStringToGlobalBuffer(IDS_NICKNAME), ARRAYSIZE(cNickname));
  721. memset(nsAdrBook,0, sizeof(NSADRBOOK));
  722. nsAdrBook->DistList = TRUE;
  723. /* Get Mailto entry */
  724. szPrmStart = strstr(*szL, cMailto);
  725. if (! szPrmStart) {
  726. flag = TRUE;
  727. nsAdrBook->DistList = TRUE;
  728. szName = strchr(*szL,'>');
  729. goto AliasID;
  730. }
  731. nsAdrBook->DistList = FALSE;
  732. szPrmStart += lstrlen(cMailto);
  733. // search for quotes
  734. szPrmEnd = szPrmStart;
  735. if (! szPrmEnd) {
  736. goto AliasID;
  737. }
  738. while (*szPrmEnd != 34) {
  739. szPrmEnd = szPrmEnd + 1; // What if there is no end quote
  740. if (szPrmEnd > (*szL + lstrlen(*szL))) {
  741. goto Down;
  742. }
  743. }
  744. ulSize = (ULONG) (szPrmEnd - szPrmStart);
  745. if (ulSize) {
  746. nsAdrBook->Address = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1));
  747. if (!nsAdrBook->Address) {
  748. return(hrMemory);
  749. }
  750. StrCpyN(nsAdrBook->Address, szPrmStart, ulSize+1);
  751. }
  752. *szL = szPrmEnd + 1;
  753. /* Get the AliasID */
  754. if (szPrmEnd) {
  755. szName = strchr(szPrmEnd, '>');
  756. }
  757. AliasID:
  758. szPrmStart = strstr(*szL, cAliasId);
  759. if (!szPrmStart) {
  760. nsAdrBook->Sbinary=FALSE;
  761. goto Nickname;
  762. }
  763. nsAdrBook->Sbinary=TRUE;
  764. szPrmStart += lstrlen(cAliasId);
  765. szPrmEnd = szPrmStart;
  766. while (*szPrmEnd != 34) {
  767. szPrmEnd++;
  768. if (szPrmEnd > (*szL + strlen(*szL))) {
  769. goto Down;
  770. }
  771. }
  772. ulSize = (ULONG) (szPrmEnd - szPrmStart + 1);
  773. tmpStr = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize);
  774. if (!tmpStr) {
  775. return(hrMemory);
  776. }
  777. StrCpyN(tmpStr, szPrmStart, ulSize);
  778. nsAdrBook->AliasID = atoi(tmpStr);
  779. if (tmpStr) {
  780. LocalFree((HLOCAL)tmpStr);
  781. }
  782. *szL = szPrmEnd + 1;
  783. Nickname:
  784. szPrmStart = strstr(*szL, cNickname);
  785. if (!szPrmStart) {
  786. NoNickName = TRUE;
  787. goto Entry;
  788. }
  789. if (szName && szName < szPrmStart) {
  790. NoNickName = TRUE;
  791. goto Entry;
  792. }
  793. szPrmStart += lstrlen(cNickname);
  794. szPrmStart += 1;
  795. szPrmEnd = szPrmStart;
  796. while (*szPrmEnd != 34) {
  797. szPrmEnd++;
  798. if (szPrmEnd > (*szL + strlen(*szL))) {
  799. goto Down;
  800. }
  801. }
  802. ulSize = (ULONG) (szPrmEnd - szPrmStart);
  803. if (0 == ulSize) {
  804. NoNickName = TRUE;
  805. } else {
  806. NoNickName = FALSE;
  807. nsAdrBook->NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1));
  808. if (!nsAdrBook->NickName) {
  809. return(hrMemory);
  810. }
  811. StrCpyN(nsAdrBook->NickName, szPrmStart, ulSize + 1);
  812. }
  813. *szL = szPrmEnd +1;
  814. Entry:
  815. szPrmStart = szName;
  816. if (szPrmStart) {
  817. szPrmStart++;
  818. ulSize = (ULONG) ((*szL + lstrlen(*szL)) - szPrmStart);
  819. if (ulSize) {
  820. nsAdrBook->Entry = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulSize + 1));
  821. if (!nsAdrBook->Entry) {
  822. return(hrMemory);
  823. }
  824. StrCpyN(nsAdrBook->Entry, szPrmStart, ulSize + 1);
  825. }
  826. if (/*NoNickName && */!nsAdrBook->Entry && nsAdrBook->Address) {
  827. ulSize = lstrlen(nsAdrBook->Address) + 1;
  828. nsAdrBook->Entry = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize);
  829. if (!nsAdrBook->Entry) {
  830. return(hrMemory);
  831. }
  832. StrCpyN(nsAdrBook->Entry, nsAdrBook->Address, ulSize);
  833. }
  834. }
  835. if (*szDesc) {
  836. ulSize = lstrlen(*szDesc) + 1;
  837. nsAdrBook->Description = (TCHAR *)LocalAlloc(LMEM_FIXED, ulSize);
  838. if (! nsAdrBook->Description) {
  839. return(hrMemory);
  840. }
  841. StrCpyN(nsAdrBook->Description, *szDesc,ulSize);
  842. } else {
  843. nsAdrBook->Description = NULL;
  844. }
  845. if (flag == TRUE) {
  846. ulSize = 0;
  847. szDistStart = GetAdrStart(*szBuffer);
  848. szDistEnd = GetDLNext(*szBuffer);
  849. if (szDistEnd - szDistStart) {
  850. ulSize = (ULONG) (szDistEnd-szDistStart);
  851. }
  852. if (ulSize) {
  853. szDistBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulSize + 1));
  854. if (!szDistBuffer) {
  855. return(hrMemory);
  856. }
  857. StrCpyN(szDistBuffer, szDistStart, ulSize + 1);
  858. *szBuffer=szDistEnd;
  859. } else {
  860. return(S_OK);
  861. }
  862. szPrmStart=szDistBuffer;
  863. if ((temp = strstr(szPrmStart, LoadStringToGlobalBuffer(IDS_ALIASOF))) == NULL) {
  864. if (szDistBuffer) {
  865. LocalFree((HLOCAL)szDistBuffer);
  866. }
  867. return(S_OK);
  868. }
  869. while ((szPrmEnd=strstr(szPrmStart, LoadStringToGlobalBuffer(IDS_ALIASOF)))!=NULL) {
  870. present = (LPNSDISTLIST)LocalAlloc(LMEM_FIXED,sizeof(NSDISTLIST));
  871. if (! present) {
  872. if (szDistBuffer) {
  873. LocalFree((HLOCAL)szDistBuffer);
  874. }
  875. return(hrMemory);
  876. }
  877. szPrmEnd += strlen(LoadStringToGlobalBuffer(IDS_ALIASOF));
  878. szPrmStart = strchr(szPrmEnd,'"');
  879. ulSize = (ULONG) (szPrmStart - szPrmEnd + 1);
  880. tmpStr = (TCHAR *)LocalAlloc(LMEM_FIXED,ulSize);
  881. if (! tmpStr) {
  882. return(hrMemory);
  883. }
  884. StrCpyN(tmpStr, szPrmEnd, ulSize);
  885. present->AliasID = atoi(tmpStr);
  886. if (tmpStr) {
  887. LocalFree((HLOCAL)tmpStr);
  888. }
  889. if (previous != NULL) {
  890. previous->lpDist = present;
  891. } else {
  892. nsAdrBook->lpDist = present;
  893. }
  894. previous=present;
  895. }
  896. present->lpDist=NULL;
  897. if (szDistBuffer) {
  898. LocalFree((HLOCAL)szDistBuffer);
  899. }
  900. } else {
  901. nsAdrBook->lpDist=NULL;
  902. }
  903. Down:
  904. return(S_OK);
  905. }
  906. /******************************************************************************
  907. * FUNCTION NAME:GetAddressCount
  908. *
  909. * PURPOSE: To get the count of number of <DT> in the buffer containing the
  910. * addresses.
  911. *
  912. * PARAMETERS: AdrBuffer = Buffer containing the addresses.
  913. *
  914. * RETURNS:ULONG , count of <DT>
  915. ******************************************************************************/
  916. ULONG GetAddressCount(LPTSTR AdrBuffer)
  917. {
  918. TCHAR szToken[] = "<DT>";
  919. LPTSTR szTemp = AdrBuffer;
  920. LPTSTR szP = NULL;
  921. ULONG ulCount = 0;
  922. while ((szP = strstr(szTemp, szToken)) != NULL) {
  923. ulCount++;
  924. szTemp = szP + lstrlen(szToken);
  925. }
  926. return(ulCount);
  927. }
  928. /******************************************************************************
  929. * FUNCTION NAME:GetAdrStart
  930. *
  931. * PURPOSE: To get a pointer to the starting of addresses in the NetScape
  932. * address book.
  933. *
  934. * PARAMETERS: szBuffer = pointer to the buffer containing the address book.
  935. *
  936. * RETURNS: LPTSTR, pointer to the starting of addresses (<DL><p>).
  937. ******************************************************************************/
  938. LPTSTR GetAdrStart(LPTSTR szBuffer)
  939. {
  940. TCHAR szAdrStart[] = "<DL><p>";
  941. LPTSTR szS=NULL;
  942. szS = strstr(szBuffer, szAdrStart);
  943. if (szS) {
  944. szS += lstrlen(szAdrStart);
  945. }
  946. return(szS);
  947. }
  948. /******************************************************************************
  949. * FUNCTION NAME:GetDLNext
  950. *
  951. * PURPOSE: To get a pointer to the </DL><p> in the address buffer.
  952. *
  953. * PARAMETERS: szBuffer = address buffer
  954. *
  955. * RETURNS: LPTSTR, pointer to the </DL><p>
  956. ******************************************************************************/
  957. LPTSTR GetDLNext(LPTSTR szBuffer)
  958. {
  959. TCHAR szAdrStart[] = "</DL><p>";
  960. LPTSTR szS = NULL;
  961. szS = strstr(szBuffer, szAdrStart);
  962. if (szS) {
  963. szS += lstrlen(szAdrStart) + 1;
  964. }
  965. return(szS);
  966. }
  967. /******************************************************************************
  968. * FUNCTION NAME:GetAdrEnd
  969. *
  970. * PURPOSE: To get a pointer to the last occurance of </DL><p> in the address
  971. * buffer.
  972. *
  973. * PARAMETERS: szBuffer = address buffer
  974. *
  975. * RETURNS: LPTSTR, pointer to the last </DL><p>
  976. ******************************************************************************/
  977. LPTSTR GetAdrEnd(LPTSTR szBuffer)
  978. {
  979. TCHAR szAdrEnd[] = "</DL><p>";
  980. LPTSTR szE = NULL, szT = NULL;
  981. LPTSTR szTemp = szBuffer;
  982. while ((szE = strstr(szTemp, szAdrEnd)) != NULL) {
  983. szT=szE;
  984. szTemp = szE + lstrlen(szAdrEnd);
  985. }
  986. szE = szT;
  987. if (szE) {
  988. szE += lstrlen(szAdrEnd);
  989. }
  990. return(szE);
  991. }
  992. /******************************************************************************
  993. * FUNCTION NAME:GetAddrCount
  994. *
  995. * PURPOSE: To get a count of number of ALIASID in the address buffer.
  996. *
  997. * PARAMETERS: AdrBuffer = address buffer
  998. *
  999. * RETURNS: ULONG, count of total ALIASID in the address buffer
  1000. ******************************************************************************/
  1001. ULONG GetAddrCount(LPTSTR AdrBuffer)
  1002. {
  1003. TCHAR szToken[MAX_STRING_SIZE];
  1004. LPTSTR szTemp=AdrBuffer;
  1005. LPTSTR szP=NULL;
  1006. ULONG ulCount=0;
  1007. StrCpyN(szToken, LoadStringToGlobalBuffer(IDS_ALIAS_ID), ARRAYSIZE(szToken));
  1008. while ((szP=strstr(szTemp,szToken))!=NULL) {
  1009. ulCount++;
  1010. szTemp =szP+lstrlen(szToken);
  1011. }
  1012. return(ulCount);
  1013. }
  1014. /******************************************************************************
  1015. * FUNCTION NAME:FillDistList
  1016. *
  1017. * PURPOSE: To create a Distribution list in the WAB.
  1018. *
  1019. * PARAMETERS: hwnd - hwnd of parent
  1020. * lpWabContainer = pointer to the IABCONT interface
  1021. * sProp = pointer to SPropValue
  1022. * lpAdrBook = pointer to the IADRBOOK interface
  1023. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  1024. * lpsbinary = pointer to the SBinary array.
  1025. * lpnAdrBook = pointer to the NSADRBOOK structure
  1026. *
  1027. * RETURNS: HRESULT
  1028. ******************************************************************************/
  1029. HRESULT FillDistList(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp,
  1030. LPWAB_IMPORT_OPTIONS lpOptions, LPNSADRBOOK lpnAdrBook,
  1031. LPSBinary lpsbinary, LPADRBOOK lpAdrBook)
  1032. {
  1033. LPNSDISTLIST lptemp=lpnAdrBook->lpDist;
  1034. LPSPropValue lpNewDLProps = NULL;
  1035. LPDISTLIST lpDistList = NULL;
  1036. ULONG cProps;
  1037. ULONG ulObjType;
  1038. int i;
  1039. HRESULT hResult;
  1040. static LPMAPIPROP lpMailUserWAB =NULL;
  1041. SPropValue rgProps[4];
  1042. LPMAPIPROP lpDlWAB = NULL;
  1043. ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL;
  1044. BOOL flag = FALSE;
  1045. REPLACE_INFO RI = {0};
  1046. ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT;
  1047. retry:
  1048. if (lpnAdrBook->Sbinary == FALSE) {
  1049. if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags,
  1050. &lpMailUserWAB))) {
  1051. goto error1;
  1052. }
  1053. } else {
  1054. if (lpsbinary[lpnAdrBook->AliasID].lpb == NULL) {
  1055. if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags,
  1056. &lpMailUserWAB))) {
  1057. goto error1;
  1058. }
  1059. } else {
  1060. if (0 != (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1061. lpsbinary[lpnAdrBook->AliasID].cb,
  1062. (LPENTRYID)lpsbinary[lpnAdrBook->AliasID].lpb,
  1063. (LPIID)&IID_IMAPIProp,
  1064. MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
  1065. &ulObjType,
  1066. (LPUNKNOWN *)&lpMailUserWAB))) {
  1067. goto error1;
  1068. }
  1069. flag = TRUE;
  1070. }
  1071. }
  1072. if (lpnAdrBook->Entry) {
  1073. rgProps[0].Value.lpszA = lpnAdrBook->Entry;
  1074. rgProps[0].ulPropTag = PR_DISPLAY_NAME;
  1075. } else if (lpnAdrBook->NickName) {
  1076. rgProps[0].Value.lpszA = lpnAdrBook->NickName;
  1077. rgProps[0].ulPropTag = PR_DISPLAY_NAME;
  1078. } else {
  1079. rgProps[0].Value.lpszA = NULL;
  1080. rgProps[0].ulPropTag = PR_NULL;
  1081. }
  1082. rgProps[1].Value.lpszA = lpnAdrBook->Description;
  1083. if (lpnAdrBook->Description) {
  1084. rgProps[1].ulPropTag = PR_COMMENT;
  1085. } else {
  1086. rgProps[1].ulPropTag = PR_NULL;
  1087. }
  1088. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB,
  1089. 2, rgProps, NULL))) {
  1090. goto error1;
  1091. }
  1092. if (0 != (hResult=lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  1093. FORCE_SAVE|KEEP_OPEN_READWRITE))) {
  1094. if (GetScode(hResult) == MAPI_E_COLLISION) {
  1095. if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) {
  1096. if (lpMailUserWAB) {
  1097. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  1098. }
  1099. lpMailUserWAB = NULL;
  1100. ulCreateFlags |= CREATE_REPLACE;
  1101. goto retry;
  1102. }
  1103. if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) {
  1104. hResult = S_OK;
  1105. goto error1;
  1106. }
  1107. if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) {
  1108. if (lpnAdrBook->Entry) {
  1109. RI.lpszDisplayName = lpnAdrBook->Entry;
  1110. RI.lpszEmailAddress = lpnAdrBook->Address;
  1111. } else if (lpnAdrBook->NickName) {
  1112. RI.lpszDisplayName = lpnAdrBook->NickName;
  1113. RI.lpszEmailAddress = lpnAdrBook->Address;
  1114. } else if (lpnAdrBook->Address) {
  1115. RI.lpszDisplayName = lpnAdrBook->Address;
  1116. RI.lpszEmailAddress = NULL;
  1117. } else if (lpnAdrBook->Description) {
  1118. RI.lpszDisplayName = lpnAdrBook->Description;
  1119. RI.lpszEmailAddress = NULL;
  1120. } else {
  1121. RI.lpszDisplayName = "";
  1122. RI.lpszEmailAddress = NULL;
  1123. }
  1124. RI.ConfirmResult = CONFIRM_ERROR;
  1125. RI.fExport = FALSE;
  1126. RI.lpImportOptions = lpOptions;
  1127. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd,
  1128. ReplaceDialogProc, (LPARAM)&RI);
  1129. switch (RI.ConfirmResult) {
  1130. case CONFIRM_YES:
  1131. case CONFIRM_YES_TO_ALL:
  1132. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  1133. lpMailUserWAB = NULL;
  1134. ulCreateFlags |= CREATE_REPLACE;
  1135. goto retry;
  1136. break;
  1137. case CONFIRM_NO:
  1138. if (lpnAdrBook->Sbinary == TRUE) {
  1139. hResult = GetExistEntry(lpWabContainer,lpsbinary,
  1140. lpnAdrBook->AliasID,
  1141. lpnAdrBook->Entry,
  1142. lpnAdrBook->NickName);
  1143. }
  1144. goto error1;
  1145. case CONFIRM_ABORT:
  1146. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  1147. goto error1;
  1148. default:
  1149. break;
  1150. }
  1151. }
  1152. }
  1153. }
  1154. if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB,
  1155. (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) {
  1156. if (hResult == MAPI_W_ERRORS_RETURNED) {
  1157. WABFreeBuffer(lpNewDLProps);
  1158. lpNewDLProps = NULL;
  1159. }
  1160. goto error1;
  1161. }
  1162. if (lpnAdrBook->Sbinary == TRUE) {
  1163. if (flag == FALSE) {
  1164. lpsbinary[lpnAdrBook->AliasID].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,
  1165. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  1166. if (! lpsbinary[lpnAdrBook->AliasID].lpb) {
  1167. hResult = hrMemory;
  1168. goto error1;
  1169. }
  1170. CopyMemory(lpsbinary[lpnAdrBook->AliasID].lpb,
  1171. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,
  1172. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  1173. lpsbinary[lpnAdrBook->AliasID].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
  1174. }
  1175. }
  1176. if (lpMailUserWAB) {
  1177. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  1178. lpMailUserWAB = NULL;
  1179. }
  1180. if (0 != (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  1181. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb,
  1182. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,
  1183. (LPIID)&IID_IDistList,
  1184. MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
  1185. &ulObjType,
  1186. (LPUNKNOWN *)&lpDistList))) {
  1187. goto error1;
  1188. }
  1189. if (lpNewDLProps) {
  1190. WABFreeBuffer(lpNewDLProps);
  1191. lpNewDLProps = NULL;
  1192. }
  1193. if (NULL == lpnAdrBook->lpDist) {
  1194. goto error1;
  1195. }
  1196. do {
  1197. i = lpnAdrBook->lpDist->AliasID;
  1198. if ((LPENTRYID)lpsbinary[i].lpb == NULL) {
  1199. if (0 != (hResult=CreateDistEntry(lpWabContainer,sProp,ulCreateFlags,
  1200. &lpMailUserWAB))) {
  1201. goto error2;
  1202. }
  1203. rgProps[0].ulPropTag = PR_DISPLAY_NAME;
  1204. rgProps[0].Value.lpszA = LoadStringToGlobalBuffer(IDS_DUMMY);
  1205. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB,
  1206. 1, rgProps, NULL))) {
  1207. goto error2;
  1208. }
  1209. if (0 != (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  1210. FORCE_SAVE|KEEP_OPEN_READONLY))) {
  1211. goto error2;
  1212. }
  1213. if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB,
  1214. (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) {
  1215. if (hResult == MAPI_W_ERRORS_RETURNED) {
  1216. WABFreeBuffer(lpNewDLProps);
  1217. lpNewDLProps = NULL;
  1218. }
  1219. goto error2;
  1220. }
  1221. lpsbinary[i].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  1222. if (!lpsbinary[i].lpb) {
  1223. hResult = hrMemory;
  1224. goto error1;
  1225. }
  1226. CopyMemory(lpsbinary[i].lpb,
  1227. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  1228. lpsbinary[i].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
  1229. if (lpNewDLProps) {
  1230. WABFreeBuffer(lpNewDLProps);
  1231. lpNewDLProps = NULL;
  1232. }
  1233. error2:
  1234. if (lpMailUserWAB) {
  1235. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  1236. lpMailUserWAB = NULL;
  1237. }
  1238. }
  1239. if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList,
  1240. lpsbinary[i].cb,
  1241. (LPENTRYID)lpsbinary[i].lpb,
  1242. CREATE_CHECK_DUP_STRICT|CREATE_REPLACE,
  1243. &lpDlWAB))) {
  1244. goto error3;
  1245. }
  1246. if (0 != (hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE))) {
  1247. if (MAPI_E_FOLDER_CYCLE ==hResult) {
  1248. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_LOOPING), ARRAYSIZE(szGlobalTempAlloc));
  1249. MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ENTRY_NOIMPORT),MB_OK);
  1250. }
  1251. hResult = S_OK;
  1252. goto error3;
  1253. }
  1254. error3:
  1255. if (lpDlWAB) {
  1256. lpDlWAB->lpVtbl->Release(lpDlWAB);
  1257. lpDlWAB = NULL;
  1258. }
  1259. lpnAdrBook->lpDist = FreeNSdistlist(lpnAdrBook->lpDist);
  1260. } while (lpnAdrBook->lpDist!=NULL);
  1261. error1:
  1262. if (lpDistList) {
  1263. lpDistList->lpVtbl->Release(lpDistList);
  1264. lpDistList = NULL;
  1265. }
  1266. if (lpDlWAB) {
  1267. lpDlWAB->lpVtbl->Release(lpDlWAB);
  1268. lpDlWAB = NULL;
  1269. }
  1270. if (lpMailUserWAB) {
  1271. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  1272. lpMailUserWAB = NULL;
  1273. }
  1274. return(hResult);
  1275. }
  1276. /******************************************************************************
  1277. * FUNCTION NAME: FillWABStruct
  1278. *
  1279. * PURPOSE: To fill the SpropValue array.
  1280. *
  1281. * PARAMETERS: nsAdrBook = pointer to the NSADRBOOK structure.
  1282. * rgProps = pointer to the SpropValue array.
  1283. *
  1284. * RETURNS: HRESULT
  1285. ******************************************************************************/
  1286. HRESULT FillWABStruct(LPSPropValue rgProps, NSADRBOOK *nsAdrBook)
  1287. {
  1288. HRESULT hr = S_OK;
  1289. rgProps[1].ulPropTag = PR_DISPLAY_NAME;
  1290. if (nsAdrBook->Entry) {
  1291. rgProps[1].Value.lpszA = nsAdrBook->Entry;
  1292. } else if (nsAdrBook->NickName) {
  1293. rgProps[1].Value.lpszA = nsAdrBook->NickName;
  1294. } else {
  1295. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NONAME), ARRAYSIZE(szGlobalTempAlloc));
  1296. rgProps[1].Value.lpszA = szGlobalTempAlloc;
  1297. }
  1298. rgProps[0].Value.lpszA = nsAdrBook->Address;
  1299. if (nsAdrBook->Address) {
  1300. rgProps[0].ulPropTag = PR_EMAIL_ADDRESS;
  1301. rgProps[2].ulPropTag = PR_ADDRTYPE;
  1302. rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP);
  1303. } else {
  1304. rgProps[0].ulPropTag = PR_NULL;
  1305. rgProps[2].ulPropTag = PR_NULL;
  1306. rgProps[2].Value.lpszA = NULL;
  1307. }
  1308. rgProps[3].Value.lpszA = nsAdrBook->Description;
  1309. if (nsAdrBook->Description) {
  1310. rgProps[3].ulPropTag = PR_COMMENT;
  1311. } else {
  1312. rgProps[3].ulPropTag = PR_NULL;
  1313. }
  1314. rgProps[4].Value.lpszA = nsAdrBook->NickName;
  1315. if (nsAdrBook->NickName) {
  1316. rgProps[4].ulPropTag = PR_NICKNAME;
  1317. } else {
  1318. rgProps[4].ulPropTag = PR_NULL;
  1319. }
  1320. return(hr);
  1321. }
  1322. /******************************************************************************
  1323. * FUNCTION NAME:CreateDistEntry
  1324. *
  1325. * PURPOSE: To create an entry in the WAB for a Distribution List
  1326. *
  1327. * PARAMETERS: lpWabContainer = pointer to the WAB container.
  1328. * sProp = pointer to SPropValue
  1329. * ulCreateFlags = Flags
  1330. * lppMailUserWab = pointer to the IMAPIPROP interface
  1331. *
  1332. * RETURNS: HRESULT
  1333. ******************************************************************************/
  1334. HRESULT CreateDistEntry(LPABCONT lpWabContainer,LPSPropValue sProp,
  1335. ULONG ulCreateFlags,LPMAPIPROP *lppMailUserWab)
  1336. {
  1337. HRESULT hResult;
  1338. ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL;
  1339. hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer,
  1340. sProp[iCreateTemplatedl].Value.bin.cb,
  1341. (LPENTRYID)sProp[iCreateTemplatedl].Value.bin.lpb,
  1342. ulCreateFlags,
  1343. lppMailUserWab);
  1344. return(hResult);
  1345. }
  1346. /******************************************************************************
  1347. * FUNCTION NAME:FreeNSdistlist
  1348. *
  1349. * PURPOSE: To free one node from NSDISTLIST(linked list)
  1350. *
  1351. * PARAMETERS: lpDist = pointer to the NSDISTLIST structure.
  1352. *
  1353. * RETURNS: LPNSDISTLIST , pointer to the next link.
  1354. ******************************************************************************/
  1355. LPNSDISTLIST FreeNSdistlist(LPNSDISTLIST lpDist)
  1356. {
  1357. LPNSDISTLIST lpTemp = NULL;
  1358. if (lpDist==NULL) {
  1359. return(NULL);
  1360. }
  1361. lpTemp = lpDist->lpDist;
  1362. LocalFree((HLOCAL)lpDist);
  1363. lpDist = NULL;
  1364. return(lpTemp);
  1365. }
  1366. /******************************************************************************
  1367. *********************Eudora Functions*****************************************/
  1368. HRESULT ImportEudoraAddressBookFile(HWND hwnd, LPTSTR szFileName, LPABCONT lpWabContainer,
  1369. LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  1370. {
  1371. HRESULT hResult = E_FAIL;
  1372. ULONG cProps;
  1373. LPEUDADRBOOK lpeudAdrBook = NULL;
  1374. ULONG ulCount = 0, uCounter = 0;
  1375. LPSPropValue sProp = NULL;
  1376. if (! (ulCount = ParseEudAddress(szFileName,&lpeudAdrBook))) {
  1377. goto Error;
  1378. }
  1379. if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer,
  1380. (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) {
  1381. if (hResult == MAPI_W_ERRORS_RETURNED) {
  1382. WABFreeBuffer(sProp);
  1383. sProp = NULL;
  1384. }
  1385. goto Error;
  1386. }
  1387. hResult = ImportEudUsers(hwnd, szFileName, lpWabContainer, sProp, lpeudAdrBook,ulCount,
  1388. lpOptions,lpProgressCB,lpAdrBook);
  1389. if (sProp) {
  1390. WABFreeBuffer(sProp);
  1391. }
  1392. Error:
  1393. if (lpeudAdrBook) {
  1394. for (; uCounter < ulCount ; uCounter++) {
  1395. if (lpeudAdrBook[uCounter].Description) {
  1396. LocalFree((HLOCAL)lpeudAdrBook[uCounter].Description);
  1397. }
  1398. lpeudAdrBook[uCounter].Description = NULL;
  1399. if (lpeudAdrBook[uCounter].NickName) {
  1400. LocalFree((HLOCAL)lpeudAdrBook[uCounter].NickName);
  1401. }
  1402. lpeudAdrBook[uCounter].NickName = NULL;
  1403. if (lpeudAdrBook[uCounter].Address) {
  1404. LocalFree((HLOCAL)lpeudAdrBook[uCounter].Address);
  1405. }
  1406. lpeudAdrBook[uCounter].Address = NULL;
  1407. }
  1408. LocalFree((HLOCAL)lpeudAdrBook);
  1409. lpeudAdrBook=NULL;
  1410. }
  1411. return(hResult);
  1412. }
  1413. /******************************************************************************
  1414. * FUNCTION NAME:MigrateEudoraUser
  1415. *
  1416. * PURPOSE: Get the installation path of the address book and starts processing
  1417. * the Eudora address book
  1418. *
  1419. * PARAMETERS: hwnd = Handle to the parent Window
  1420. * lpAdrBook = pointer to the IADRBOOK interface
  1421. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  1422. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  1423. * lpWabContainer = pointer to the IABCONT interface
  1424. *
  1425. * RETURNS: HRESULT
  1426. ******************************************************************************/
  1427. HRESULT MigrateEudoraUser(HWND hwnd, LPABCONT lpWabContainer,
  1428. LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB,
  1429. LPADRBOOK lpAdrBook)
  1430. {
  1431. TCHAR szFileName[MAX_FILE_NAME];
  1432. TCHAR szFilePath[MAX_FILE_NAME];
  1433. TCHAR szFileSubPath[MAX_FILE_NAME];
  1434. HRESULT hResult = S_OK;
  1435. WIN32_FIND_DATA FindFileData;
  1436. HANDLE hFile = NULL;
  1437. szFilePath[0] = szFileName[0] = '\0';
  1438. hResult= GetRegistryPath(szFileName, ARRAYSIZE(szFileName), EUDORA);
  1439. if (hResult == hrMemory) {
  1440. return(hrMemory);
  1441. }
  1442. if (0 != hResult) {
  1443. // Didnt find the registry setting .. look for "c:\eudora"
  1444. StrCpyN(szFileName, LoadStringToGlobalBuffer(IDS_EUDORA_DEFAULT_INSTALL), ARRAYSIZE(szFileName));
  1445. if (0xFFFFFFFF != GetFileAttributes(szFileName)) {
  1446. // This directory exists .. reset the error value
  1447. hResult = S_OK;
  1448. }
  1449. }
  1450. if (0 != hResult) {
  1451. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_STRING_SELECTPATH), ARRAYSIZE(szGlobalTempAlloc));
  1452. if (IDNO ==MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),
  1453. MB_YESNO)) {
  1454. return(ResultFromScode(MAPI_E_USER_CANCEL));
  1455. }
  1456. if (!GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), EUDORA)) {
  1457. return(ResultFromScode(MAPI_E_USER_CANCEL));
  1458. }
  1459. } else {
  1460. StrCatBuff(szFileName, LoadStringToGlobalBuffer(IDS_EUDORA_ADDRESS), ARRAYSIZE(szFileName));
  1461. hFile = FindFirstFile(szFileName,&FindFileData);
  1462. if (INVALID_HANDLE_VALUE == hFile) {
  1463. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ADDRESS_HTM), ARRAYSIZE(szGlobalTempAlloc));
  1464. if (IDNO == MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_YESNO)) {
  1465. return(ResultFromScode(MAPI_E_USER_CANCEL));
  1466. }
  1467. if (FALSE ==GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), EUDORA)) {
  1468. return(ResultFromScode(MAPI_E_USER_CANCEL));
  1469. }
  1470. } else {
  1471. FindClose(hFile);
  1472. }
  1473. }
  1474. // Extract the file directory from the file name
  1475. if (lstrlen(szFileName) && !lstrlen(szFilePath)) {
  1476. LPTSTR lp1 = NULL, lp2 = NULL;
  1477. StrCpyN(szFilePath,szFileName, ARRAYSIZE(szFilePath));
  1478. lp1 = szFilePath;
  1479. // Find the last '\' and terminate the path at that char
  1480. while (lp1 && *lp1) {
  1481. if (*lp1 == '\\') {
  1482. lp2 = lp1;
  1483. }
  1484. lp1 = CharNext(lp1);
  1485. }
  1486. if (lp2 && (*lp2 == '\\')) {
  1487. *lp2 = '\0';
  1488. }
  1489. }
  1490. // import the basic file ...
  1491. //
  1492. hResult = ImportEudoraAddressBookFile(hwnd,
  1493. szFileName, lpWabContainer, lpOptions, lpProgressCB, lpAdrBook);
  1494. szFileName[0]='\0';
  1495. // Now look for files in the nicknames subdirectory
  1496. //
  1497. StrCatBuff(szFilePath, LoadStringToGlobalBuffer(IDS_EUDORA_SUBDIR_NAME), ARRAYSIZE(szFilePath));
  1498. if (0xFFFFFFFF != GetFileAttributes(szFilePath)) {
  1499. BOOL bRet = TRUE;
  1500. // Yes this directory exists ...
  1501. // Now scan all the *.txt files in this subdir and try to import them
  1502. StrCpyN(szFileSubPath, szFilePath, ARRAYSIZE(szFileSubPath));
  1503. StrCatBuff(szFileSubPath, LoadStringToGlobalBuffer(IDS_EUDORA_GENERIC_SUFFIX), ARRAYSIZE(szFileSubPath));
  1504. hFile = FindFirstFile(szFileSubPath, &FindFileData);
  1505. while (bRet && hFile != INVALID_HANDLE_VALUE) {
  1506. StrCpyN(szFileName, szFilePath, ARRAYSIZE(szFileName));
  1507. StrCatBuff(szFileName, TEXT("\\"), ARRAYSIZE(szFileName));
  1508. StrCatBuff(szFileName, FindFileData.cFileName, ARRAYSIZE(szFileName));
  1509. hResult = ImportEudoraAddressBookFile(hwnd,
  1510. szFileName, lpWabContainer, lpOptions, lpProgressCB, lpAdrBook);
  1511. hResult = S_OK;
  1512. // Dont report errors .. just continue ...
  1513. bRet = FindNextFile(hFile, &FindFileData);
  1514. }
  1515. if (hFile) {
  1516. FindClose(hFile);
  1517. }
  1518. }
  1519. return(hResult);
  1520. }
  1521. /******************************************************************************
  1522. * FUNCTION NAME:ParseEudAddress
  1523. *
  1524. * PURPOSE: To open the nndbase.txt and toc files and starts processing the
  1525. * address book.
  1526. *
  1527. * PARAMETERS: szFileName = contains the path of the address book.
  1528. * lppeudAdrBook = pointer to the EUDADRBOOK structure.
  1529. *
  1530. * RETURNS: ULONG, number of addresses in the address book.
  1531. ******************************************************************************/
  1532. ULONG ParseEudAddress(LPTSTR szFileName, LPEUDADRBOOK *lppeudAdrBook)
  1533. {
  1534. HANDLE htoc,htxt;
  1535. TCHAR cNndbasetoc[_MAX_PATH];
  1536. ULONG ucount=0;
  1537. ULONG ulAdrcount=0;
  1538. UINT i,j;
  1539. LPTSTR szBuffer=NULL;
  1540. LPTSTR szAdrBuffer=NULL;
  1541. LPTSTR *szAliaspt=NULL;
  1542. ULONG ulRead=0;
  1543. ULONG ulFileSize,ulTxtSize;
  1544. LPEUDADRBOOK lpeudAdrBook;
  1545. StrCpyN(cNndbasetoc,szFileName, ARRAYSIZE(cNndbasetoc));
  1546. cNndbasetoc[strlen(cNndbasetoc)-3] = '\0';
  1547. StrCatBuff(cNndbasetoc, LoadStringToGlobalBuffer(IDS_EUDORA_TOC), ARRAYSIZE(cNndbasetoc));
  1548. /* Eudora address book has two files,nndbase.txt and nndbase.toc.
  1549. nndbase.toc format:
  1550. Nicknames start from byte 3. Every Nickname will be delimited by /r/n.
  1551. After this there will 4 byte address offset,4 byte address size,
  1552. 4 byte description offset and 4 byte description size. The address offset
  1553. and size constitute all the addresses in the NickName.(A NickName can
  1554. be a distribution list or a single mail user */
  1555. htoc = CreateFile(cNndbasetoc, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  1556. FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  1557. if (INVALID_HANDLE_VALUE == htoc) {
  1558. goto Error;
  1559. }
  1560. htxt = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
  1561. FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  1562. if (INVALID_HANDLE_VALUE == htxt) {
  1563. goto Error;
  1564. }
  1565. //get toc file in a buffer
  1566. ulFileSize = GetFileSize(htoc, NULL);
  1567. szBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulFileSize+1));
  1568. if (! szBuffer) {
  1569. goto NoMemory;
  1570. }
  1571. if (! ReadFile(htoc, szBuffer, ulFileSize, &ulRead, NULL)) {
  1572. goto Error;
  1573. }
  1574. szBuffer[ulFileSize] = '\0';
  1575. //get address file in a buffer
  1576. ulTxtSize = GetFileSize(htxt, NULL);
  1577. szAdrBuffer = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulTxtSize+1));
  1578. if (!szAdrBuffer) {
  1579. goto NoMemory;
  1580. }
  1581. if (! ReadFile(htxt, szAdrBuffer, ulTxtSize, &ulRead, NULL)) {
  1582. goto Error;
  1583. }
  1584. szAdrBuffer[ulTxtSize] = '\0';
  1585. // BUG 2120: to deal with only LF's and not CR/LF's
  1586. for (i = 2; i < (UINT)ulFileSize; i++) {
  1587. if (! (/*szBuffer[i] == '\r' && */szBuffer[i+1] == '\n') ) {
  1588. continue;
  1589. }
  1590. ulAdrcount++ ; //to get count of number of address
  1591. }
  1592. if (ulAdrcount) {
  1593. lpeudAdrBook = (LPEUDADRBOOK)LocalAlloc(LMEM_FIXED,
  1594. ((ulAdrcount) * sizeof(EUDADRBOOK)));
  1595. if (!lpeudAdrBook) {
  1596. goto NoMemory;
  1597. }
  1598. memset(lpeudAdrBook,0,((ulAdrcount) * sizeof(EUDADRBOOK)));
  1599. szAliaspt = (LPTSTR *)LocalAlloc(LMEM_FIXED,(sizeof(LPTSTR))*(ulAdrcount+1));
  1600. if (! szAliaspt) {
  1601. goto NoMemory;
  1602. }
  1603. for (i = 0; i < ulAdrcount; i++) {
  1604. szAliaspt[i] = (LPTSTR)LocalAlloc(LMEM_FIXED,256);
  1605. if (!szAliaspt[i]) {
  1606. goto NoMemory;
  1607. }
  1608. }
  1609. szAliaspt[i]=NULL; //to know it is the end.
  1610. j=0;
  1611. for (i = 2; i < (UINT)ulFileSize; i++) {
  1612. // BUG 2120: to deal with only LF's and not CR/LF's
  1613. if ((/*szBuffer[i] == '\r' &&*/ szBuffer[i+1] == '\n')) {
  1614. i += (EUDORA_STRUCT + 1);
  1615. //16 bytes structure +1 for 10
  1616. szAliaspt[ucount][j] = '\0';
  1617. ucount++;
  1618. j=0;
  1619. continue;
  1620. }
  1621. szAliaspt[ucount][j++]=szBuffer[i];
  1622. }
  1623. if (hrMemory == ParseAddressTokens(szBuffer,szAdrBuffer,ulAdrcount,szAliaspt,lpeudAdrBook)) {
  1624. goto NoMemory;
  1625. }
  1626. *lppeudAdrBook = lpeudAdrBook;
  1627. }
  1628. Error:
  1629. if (szBuffer) {
  1630. LocalFree((HLOCAL)szBuffer);
  1631. }
  1632. if (szAdrBuffer) {
  1633. LocalFree((HLOCAL)szAdrBuffer);
  1634. }
  1635. if (htxt) {
  1636. CloseHandle(htxt);
  1637. }
  1638. if (htoc) {
  1639. CloseHandle(htoc);
  1640. }
  1641. if (szAliaspt) {
  1642. for (i = 0; i < ulAdrcount; i++) {
  1643. if (szAliaspt[i]) {
  1644. LocalFree((HLOCAL)szAliaspt[i]);
  1645. }
  1646. szAliaspt[i] = NULL;
  1647. }
  1648. LocalFree((HLOCAL)szAliaspt);
  1649. szAliaspt = NULL;
  1650. }
  1651. return(ulAdrcount);
  1652. NoMemory:
  1653. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MEMORY), ARRAYSIZE(szGlobalTempAlloc));
  1654. MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE),MB_OK);
  1655. if (szBuffer) {
  1656. LocalFree((HLOCAL)szBuffer);
  1657. }
  1658. if (szAdrBuffer) {
  1659. LocalFree((HLOCAL)szAdrBuffer);
  1660. }
  1661. if (htxt) {
  1662. CloseHandle(htxt);
  1663. }
  1664. if (htoc) {
  1665. CloseHandle(htoc);
  1666. }
  1667. if (szAliaspt) {
  1668. for (i = 0; i < ulAdrcount; i++) {
  1669. if (szAliaspt[i]) {
  1670. LocalFree((HLOCAL)szAliaspt[i]);
  1671. }
  1672. szAliaspt[i] = NULL;
  1673. }
  1674. LocalFree((HLOCAL)szAliaspt);
  1675. szAliaspt = NULL;
  1676. }
  1677. return(0);
  1678. }
  1679. /******************************************************************************
  1680. * FUNCTION NAME:ParseAddressTokens
  1681. *
  1682. * PURPOSE: To fill the EUDADRBOOK array structure after processing all the
  1683. * addresses from Eudora address book.
  1684. *
  1685. * PARAMETERS: szBuffer = buffer containing the nndbase.toc file.
  1686. * szAdrBuffer = buffer containing the nndbase.txt file.
  1687. * ulCount = number of addresses in the eudora address book.
  1688. * szAliaspt = pointer to a two dimensional array containing
  1689. * all the nicknames.
  1690. * EudAdrBook = pointer to the EUDADRBOOK structure.
  1691. *
  1692. * RETURNS: HRESULT
  1693. ******************************************************************************/
  1694. HRESULT ParseAddressTokens(LPTSTR szBuffer,LPTSTR szAdrBuffer,UINT ulCount,
  1695. LPTSTR *szAliaspt,EUDADRBOOK *EudAdrBook)
  1696. {
  1697. ULONG ulAdrSize = 0, ulAdrOffset = 0, i = 0, uDescription = 0, uOffset = 0;
  1698. int iCounter =0;
  1699. LPTSTR szAdrLine = NULL, szAdrEnd = NULL, szAdrStart=NULL, szAdrCur=NULL;
  1700. HRESULT hr = S_OK;
  1701. szAdrStart=&szBuffer[2];
  1702. do {
  1703. if (szAliaspt[i] == NULL) {
  1704. break;
  1705. }
  1706. szAdrCur = Getstr(szAdrStart, szAliaspt[i]);
  1707. if (szAdrCur == NULL) {
  1708. hr = hrMemory;
  1709. goto Error;
  1710. }
  1711. szAdrCur+=strlen(szAliaspt[i])+2;
  1712. ulAdrOffset = ShiftAdd(0,szAdrCur);
  1713. ulAdrSize = ShiftAdd(4,szAdrCur);
  1714. szAdrStart=szAdrCur+16;
  1715. EudAdrBook[i].lpDist=NULL;
  1716. if (hrMemory == (hr = CreateAdrLineBuffer(&szAdrLine,szAdrBuffer,ulAdrOffset,ulAdrSize))) {
  1717. goto Error;
  1718. }
  1719. if (hrMemory == (hr = ParseAdrLineBuffer(szAdrLine,szAliaspt,i,EudAdrBook))) {
  1720. goto Error;
  1721. }
  1722. ulAdrOffset = ShiftAdd(8,szAdrCur);
  1723. ulAdrSize = ShiftAdd(12,szAdrCur);
  1724. if (! (ulAdrSize == 0xFFFFFFFF && ulAdrOffset == 0xFFFFFFFF)) {
  1725. EudAdrBook[i].Description = (TCHAR *)LocalAlloc(LMEM_FIXED, (ulAdrSize+1));
  1726. if (! EudAdrBook[i].Description) {
  1727. hr = hrMemory;
  1728. goto Error;
  1729. }
  1730. for (uDescription = 0, uOffset = 0; uDescription < ulAdrSize; uDescription++,uOffset++) {
  1731. if (szAdrBuffer[ulAdrOffset + uOffset] != 03) { //delimitor for next line in nndbase.txt file
  1732. EudAdrBook[i].Description[uDescription] = szAdrBuffer[ulAdrOffset + uOffset];
  1733. } else {
  1734. EudAdrBook[i].Description[uDescription++] = '\r';
  1735. EudAdrBook[i].Description[uDescription] = '\n';
  1736. }
  1737. }
  1738. // Bug 29803 - this line is not being terminated - has garrbage at end ...
  1739. EudAdrBook[i].Description[uDescription] = '\0';
  1740. } else {
  1741. EudAdrBook[i].Description = NULL;
  1742. }
  1743. i++;
  1744. if (szAdrLine) {
  1745. LocalFree((HLOCAL)szAdrLine);
  1746. }
  1747. szAdrLine = NULL;
  1748. } while (szAdrStart[0]!='\0');
  1749. Error:
  1750. if (szAdrLine) {
  1751. LocalFree((HLOCAL)szAdrLine);
  1752. }
  1753. szAdrLine = NULL;
  1754. return(hr);
  1755. }
  1756. /*******************************************************************************
  1757. * FUNCTION NAME:CreateAdrLineBuffer
  1758. *
  1759. * PURPOSE: To get an address line in a buufer from the buffer conatining
  1760. * the addressbook.
  1761. *
  1762. * PARAMETERS: szAdrline = pointer to the address line buffer.
  1763. * szAdrBuffer = pointer to the buffer containing the address book.
  1764. * ulAdrOffset = offset of the address line in the szAdrBuffer
  1765. * ulAdrSize = size of the address line in the szAdrBuffer
  1766. *
  1767. * RETURNS: HRESULT
  1768. ******************************************************************************/
  1769. HRESULT CreateAdrLineBuffer(LPTSTR *szAdrline, LPTSTR szAdrBuffer, ULONG ulAdrOffset,
  1770. ULONG ulAdrSize)
  1771. {
  1772. LPTSTR Temp = NULL;
  1773. ULONG ucount;
  1774. Temp = &szAdrBuffer[ulAdrOffset];
  1775. *szAdrline = (LPTSTR)LocalAlloc(LMEM_FIXED, (ulAdrSize + 2));
  1776. if (! (*szAdrline)) {
  1777. return(hrMemory);
  1778. }
  1779. // BUG 2120: to deal with only LF's and not CR/LF's
  1780. for (ucount = 0; ucount < ulAdrSize + 2; ucount++) {
  1781. // want to stop when get to LF and will check later if
  1782. // it was preceded by a CR
  1783. if (/*Temp[ucount] == '\r' && */Temp[ucount/*+1*/] == '\n') {
  1784. break;
  1785. }
  1786. (*szAdrline)[ucount] = Temp[ucount];
  1787. }
  1788. // if there was a CR before the LF remove it
  1789. if( (*szAdrline)[ucount-1] == '\r' )
  1790. (*szAdrline)[ucount-1] = '\0';
  1791. (*szAdrline)[ucount] = '\0';
  1792. return(S_OK);
  1793. }
  1794. /******************************************************************************
  1795. * FUNCTION NAME:ParseAdrLineBuffer
  1796. *
  1797. * PURPOSE: To parse each address line and fill the EUDADRBOOK structure.
  1798. *
  1799. * PARAMETERS: szAdrLine = pointer to the buffer containing an address line.
  1800. * szAliaspt = pointer to a two dimensional array containing
  1801. * all the nicknames.
  1802. * uToken = position of this address in the address book.
  1803. * EudAdrBook = pointer to the EUDADRBOOK structure.
  1804. *
  1805. * RETURNS: HRESULT
  1806. ******************************************************************************/
  1807. HRESULT ParseAdrLineBuffer(LPTSTR szAdrLine,LPTSTR *szAliasptr,ULONG uToken,
  1808. EUDADRBOOK *EudAdrBook)
  1809. {
  1810. LPTSTR szAdrEnd = NULL, szAdrStart = NULL, szAdrDummy = NULL;
  1811. LPTSTR szAdrCur = NULL;
  1812. INT uCount = 0;
  1813. LPEUDDISTLIST present = NULL, previous = NULL;
  1814. BOOL flag = TRUE;
  1815. UINT Parse = 0;
  1816. HRESULT hResult = S_OK;
  1817. szAdrStart = szAdrLine;
  1818. // Bug 44576 - this code below is assuming that a ',' in a string implies a group
  1819. // However, there can be "...text, text..." as one item in the input in which case
  1820. // this code really barfs ...
  1821. // The code also assumes that <spaces> are delimiters which also wont work with
  1822. // the strings as above ..
  1823. //
  1824. // Try changing ',' inside quoted strings to ';' so this code wont trip on them
  1825. // Looks like this code is also throwing away the info in quotes if the string is of
  1826. // the form alias XXX "YYY" zz@zz .. the part in ".." is discarded ??? Fix that as a
  1827. // seperate bug ...
  1828. {
  1829. LPTSTR lp = szAdrStart;
  1830. BOOL bWithinQuotes = FALSE;
  1831. while(lp && *lp)
  1832. {
  1833. if(*lp == '"')
  1834. bWithinQuotes = !bWithinQuotes;
  1835. if(*lp == ',' && bWithinQuotes)
  1836. *lp = ';';
  1837. lp = CharNext(lp);
  1838. }
  1839. }
  1840. //To check whether it is a dl or a simple address??
  1841. if ((szAdrDummy=strstr(szAdrStart,","))==NULL) {
  1842. flag=FALSE;
  1843. } else {
  1844. if ('\0'==szAdrDummy[1]) {
  1845. flag=FALSE;
  1846. }
  1847. }
  1848. szAdrCur=strtok(szAdrStart,", ");
  1849. if (NULL == szAdrCur) {
  1850. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1);
  1851. if (! EudAdrBook[uToken].NickName) {
  1852. hResult = hrMemory;
  1853. goto Error;
  1854. }
  1855. StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken],lstrlen(szAliasptr[uToken])+1);
  1856. EudAdrBook[uToken].lpDist=NULL;
  1857. EudAdrBook[uToken].Address = NULL;
  1858. return(S_OK);
  1859. }
  1860. while (szAdrCur!=NULL) {
  1861. if (SearchAdrName(szAdrCur)) {
  1862. if (flag) {
  1863. present = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED, sizeof(EUDDISTLIST));
  1864. if (! present) {
  1865. return(hrMemory);
  1866. }
  1867. memset(present,0,sizeof(EUDDISTLIST));
  1868. if (previous == NULL) {
  1869. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1);
  1870. if (! EudAdrBook[uToken].NickName) {
  1871. hResult = hrMemory;
  1872. goto Error;
  1873. }
  1874. StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1);
  1875. EudAdrBook[uToken].Address = NULL;
  1876. }
  1877. present->AliasID=uCount;
  1878. present->flag=TRUE;
  1879. present->Address = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1);
  1880. if (! present->Address) {
  1881. hResult = hrMemory;
  1882. goto Error;
  1883. }
  1884. StrCpyN(present->Address,szAdrCur, lstrlen(szAdrCur)+1);
  1885. present->NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1);
  1886. if (! present->NickName) {
  1887. hResult = hrMemory;
  1888. goto Error;
  1889. }
  1890. StrCpyN(present->NickName,szAdrCur, lstrlen(szAdrCur)+1);
  1891. if (previous!=NULL) {
  1892. previous->lpDist=present;
  1893. } else {
  1894. EudAdrBook[uToken].lpDist = present;
  1895. }
  1896. previous=present;
  1897. } else {
  1898. EudAdrBook[uToken].Address = (TCHAR *)LocalAlloc(LMEM_FIXED,
  1899. lstrlen(szAdrCur)+1);
  1900. if (! EudAdrBook[uToken].Address) {
  1901. hResult = hrMemory;
  1902. goto Error;
  1903. }
  1904. StrCpyN(EudAdrBook[uToken].Address,szAdrCur, lstrlen(szAdrCur)+1);
  1905. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1);
  1906. if (! EudAdrBook[uToken].NickName) {
  1907. hResult = hrMemory;
  1908. goto Error;
  1909. }
  1910. StrCpyN(EudAdrBook[uToken].NickName,szAliasptr[uToken], strlen(szAliasptr[uToken])+1);
  1911. EudAdrBook[uToken].lpDist=NULL;
  1912. }
  1913. } else {
  1914. if ((uCount=SearchName(szAliasptr,szAdrCur))>=0) {
  1915. if (flag) {
  1916. present = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED, sizeof(EUDDISTLIST));
  1917. if (! present) {
  1918. return(hrMemory);
  1919. }
  1920. memset(present,0,sizeof(EUDDISTLIST));
  1921. if (previous == NULL) {
  1922. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1);
  1923. if (!EudAdrBook[uToken].NickName) {
  1924. hResult = hrMemory;
  1925. goto Error;
  1926. }
  1927. StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1);
  1928. EudAdrBook[uToken].Address = NULL;
  1929. }
  1930. present->AliasID=uCount;
  1931. present->flag=FALSE;
  1932. if (previous!=NULL) {
  1933. previous->lpDist=present;
  1934. } else {
  1935. EudAdrBook[uToken].lpDist = present;
  1936. }
  1937. previous=present;
  1938. } else {
  1939. EudAdrBook[uToken].lpDist = (LPEUDDISTLIST)LocalAlloc(LMEM_FIXED,
  1940. sizeof(EUDDISTLIST));
  1941. if (! EudAdrBook[uToken].lpDist) {
  1942. return(hrMemory);
  1943. }
  1944. //memset(present,0,sizeof(EUDDISTLIST));
  1945. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED,
  1946. lstrlen(szAliasptr[uToken])+1);
  1947. if (! EudAdrBook[uToken].NickName) {
  1948. hResult = hrMemory;
  1949. goto Error;
  1950. }
  1951. StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1);
  1952. EudAdrBook[uToken].Address = NULL;
  1953. EudAdrBook[uToken].lpDist->AliasID=uCount;
  1954. EudAdrBook[uToken].lpDist->flag=FALSE;
  1955. EudAdrBook[uToken].lpDist->lpDist=NULL;
  1956. }
  1957. } else {
  1958. //not a valid email address or a valid nickname
  1959. if (FALSE==flag) {
  1960. if (! EudAdrBook[uToken].Address && SearchAdrName(szAdrCur)) {
  1961. EudAdrBook[uToken].Address = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAdrCur)+1);
  1962. if (! EudAdrBook[uToken].Address) {
  1963. hResult = hrMemory;
  1964. goto Error;
  1965. }
  1966. StrCpyN(EudAdrBook[uToken].Address, szAdrCur, lstrlen(szAdrCur)+1);
  1967. }
  1968. if (! EudAdrBook[uToken].NickName) {
  1969. EudAdrBook[uToken].NickName = (TCHAR *)LocalAlloc(LMEM_FIXED, lstrlen(szAliasptr[uToken])+1);
  1970. if (! EudAdrBook[uToken].NickName) {
  1971. hResult = hrMemory;
  1972. goto Error;
  1973. }
  1974. StrCpyN(EudAdrBook[uToken].NickName, szAliasptr[uToken], lstrlen(szAliasptr[uToken])+1);
  1975. }
  1976. EudAdrBook[uToken].lpDist=NULL;
  1977. }
  1978. }
  1979. }
  1980. szAdrCur=strtok(NULL,", ");
  1981. }
  1982. if (present!=NULL) {
  1983. present->lpDist=NULL;
  1984. }
  1985. return(hResult);
  1986. Error:
  1987. while (EudAdrBook[uToken].lpDist != NULL) {
  1988. EudAdrBook[uToken].lpDist = FreeEuddistlist(EudAdrBook[uToken].lpDist);
  1989. }
  1990. return(hResult);
  1991. }
  1992. /******************************************************************************
  1993. * FUNCTION NAME:SearchAdrName
  1994. *
  1995. * PURPOSE: To search if the token is an address or a name(whether it contains
  1996. * a @ or not).
  1997. *
  1998. * PARAMETERS: szAdrCur = pointer to the token.
  1999. *
  2000. * RETURNS: BOOL, TRUE if it contains @
  2001. ******************************************************************************/
  2002. BOOL SearchAdrName(LPTSTR szAdrCur)
  2003. {
  2004. if (strchr(szAdrCur, '@') == NULL) {
  2005. return(FALSE);
  2006. }
  2007. return(TRUE);
  2008. }
  2009. /******************************************************************************
  2010. * FUNCTION NAME:SearchName
  2011. *
  2012. * PURPOSE: To search for the token in the szAliasptr which conatins all
  2013. * the nick names.
  2014. *
  2015. * PARAMETERS: szAdrCur = pointer to the token to be searched.
  2016. * szAliaspt = pointer to a two dimensional array containing
  2017. * all the nicknames.
  2018. *
  2019. * RETURNS: INT, position of the token in the szAliaspt
  2020. ******************************************************************************/
  2021. INT SearchName(LPTSTR *szAliasptr, LPTSTR szAdrCur)
  2022. {
  2023. INT uCount=0;
  2024. while (szAliasptr[uCount]!=NULL) {
  2025. if (lstrcmpi(szAliasptr[uCount],szAdrCur) == 0) {
  2026. return(uCount);
  2027. }
  2028. uCount++;
  2029. }
  2030. return(-1);
  2031. }
  2032. /******************************************************************************
  2033. * FUNCTION NAME:ImportEudUsers
  2034. *
  2035. * PURPOSE:
  2036. *
  2037. * PARAMETERS: hwnd = Handle to the parent Window
  2038. * lpAdrBook = pointer to the IADRBOOK interface
  2039. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  2040. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  2041. * lpWabContainer = pointer to the IABCONT interface
  2042. * lpeudAdrBook = pointer to the EUDADRBOOK structure
  2043. * ulCount = counter value which holds the position of this address
  2044. * in the Eudora address book.
  2045. * sProp = pointer to SPropValue
  2046. *
  2047. * RETURNS: hresult
  2048. ******************************************************************************/
  2049. HRESULT ImportEudUsers(HWND hwnd, LPTSTR szFileName, LPABCONT lpWabContainer, LPSPropValue sProp,
  2050. LPEUDADRBOOK lpeudAdrBook, ULONG ulCount, LPWAB_IMPORT_OPTIONS lpOptions,
  2051. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  2052. {
  2053. HRESULT hResult = S_OK;
  2054. ULONG ul;
  2055. LPSBinary lpsbinary;
  2056. WAB_PROGRESS Progress;
  2057. lpsbinary = (LPSBinary)LocalAlloc(LMEM_FIXED, ((ulCount+1) * sizeof(SBinary)));
  2058. if (! lpsbinary) {
  2059. hResult = hrMemory;
  2060. goto Error;
  2061. }
  2062. memset(lpsbinary, 0, ((ulCount + 1) * sizeof(SBinary)));
  2063. Progress.denominator = ulCount;
  2064. Progress.numerator = 0;
  2065. Progress.lpText = szFileName; //NULL;
  2066. lpOptions->ReplaceOption = WAB_REPLACE_PROMPT;
  2067. for (ul = 0; ul < ulCount; ul++) {
  2068. if (lpeudAdrBook[ul].NickName == NULL) {
  2069. continue;
  2070. }
  2071. Progress.numerator = ul;
  2072. lpProgressCB(hwnd,&Progress);
  2073. if (lpeudAdrBook[ul].lpDist !=NULL) {
  2074. hResult = FillEudDistList(hwnd, lpWabContainer, sProp, lpOptions, lpeudAdrBook,
  2075. lpsbinary, lpAdrBook, ul);
  2076. switch (GetScode(hResult)) {
  2077. case MAPI_E_USER_CANCEL:
  2078. case MAPI_E_NOT_ENOUGH_MEMORY:
  2079. goto Error;
  2080. }
  2081. } else {
  2082. hResult = FillMailUser(hwnd, lpWabContainer, sProp, lpOptions,
  2083. (void *)lpeudAdrBook, lpsbinary, ul,EUDORA);
  2084. switch (GetScode(hResult)) {
  2085. case MAPI_E_USER_CANCEL:
  2086. case MAPI_E_NOT_ENOUGH_MEMORY:
  2087. goto Error;
  2088. }
  2089. }
  2090. }
  2091. Error:
  2092. if (lpsbinary) {
  2093. for (ul = 0; ul < ulCount; ul++) {
  2094. if (lpsbinary[ul].lpb) {
  2095. LocalFree((HLOCAL)lpsbinary[ul].lpb);
  2096. lpsbinary[ul].lpb = NULL;
  2097. }
  2098. }
  2099. LocalFree((HLOCAL)lpsbinary);
  2100. lpsbinary = NULL;
  2101. }
  2102. return(hResult);
  2103. }
  2104. /******************************************************************************
  2105. * FUNCTION NAME:FillEudDistList
  2106. *
  2107. * PURPOSE: To create a distribution list in the WAB.
  2108. *
  2109. * PARAMETERS: hWnd - hWnd of parent
  2110. * pAdrBook = pointer to the IADRBOOK interface
  2111. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  2112. * lpWabContainer = pointer to the IABCONT interface
  2113. * lpeudAdrBook = pointer to the EUDADRBOOK structure
  2114. * ul = counter value which holds the position of this address
  2115. * in the Eudora address book.
  2116. * sProp = pointer to SPropValue
  2117. * lpsbinary = pointer to the SBinary array.
  2118. *
  2119. * RETURNS: HRESULT
  2120. ******************************************************************************/
  2121. HRESULT FillEudDistList(HWND hwnd, LPABCONT lpWabContainer,LPSPropValue sProp,
  2122. LPWAB_IMPORT_OPTIONS lpOptions,
  2123. LPEUDADRBOOK lpeudAdrBook,LPSBinary lpsbinary,
  2124. LPADRBOOK lpAdrBook,ULONG ul)
  2125. {
  2126. LPSPropValue lpNewDLProps = NULL;
  2127. LPDISTLIST lpDistList = NULL;
  2128. ULONG cProps, ulObjType;
  2129. ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER;
  2130. ULONG iCreateTemplatedl = iconPR_DEF_CREATE_DL;
  2131. ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT;
  2132. int i;
  2133. HRESULT hResult;
  2134. static LPMAPIPROP lpMailUserWAB = NULL;
  2135. SPropValue rgProps[4];
  2136. LPMAPIPROP lpDlWAB = NULL;
  2137. LPSBinary lpsbEntry;
  2138. SBinary sbTemp;
  2139. BOOL flag = FALSE;
  2140. REPLACE_INFO RI = {0};
  2141. LPEUDDISTLIST lpTemp = lpeudAdrBook[ul].lpDist;
  2142. retry:
  2143. if (lpsbinary[ul].lpb == NULL) {
  2144. hResult = CreateDistEntry(lpWabContainer,sProp,ulCreateFlags,&lpMailUserWAB);
  2145. if (hResult != S_OK) {
  2146. goto error1;
  2147. }
  2148. }
  2149. else {
  2150. hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  2151. lpsbinary[ul].cb, (LPENTRYID)lpsbinary[ul].lpb, (LPIID)&IID_IMAPIProp,
  2152. MAPI_DEFERRED_ERRORS|MAPI_MODIFY, &ulObjType, (LPUNKNOWN *)&lpMailUserWAB);
  2153. if (hResult != S_OK) {
  2154. goto error1;
  2155. }
  2156. }
  2157. rgProps[0].ulPropTag = PR_DISPLAY_NAME;
  2158. rgProps[0].Value.lpszA = lpeudAdrBook[ul].NickName;
  2159. rgProps[1].Value.lpszA = lpeudAdrBook[ul].Description;
  2160. if (lpeudAdrBook[ul].Description) {
  2161. rgProps[1].ulPropTag = PR_COMMENT;
  2162. } else {
  2163. rgProps[1].ulPropTag = PR_NULL;
  2164. }
  2165. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB,
  2166. 2, rgProps, NULL))) {
  2167. goto error1;
  2168. }
  2169. if (0 != (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  2170. FORCE_SAVE|KEEP_OPEN_READWRITE)))
  2171. if (GetScode(hResult) == MAPI_E_COLLISION) {
  2172. if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) {
  2173. if (lpMailUserWAB) {
  2174. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2175. }
  2176. lpMailUserWAB = NULL;
  2177. ulCreateFlags |= CREATE_REPLACE;
  2178. goto retry;
  2179. }
  2180. if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) {
  2181. hResult = S_OK;
  2182. goto error1;
  2183. }
  2184. RI.lpszEmailAddress = NULL;
  2185. if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) {
  2186. if (lpeudAdrBook[ul].NickName) {
  2187. RI.lpszDisplayName = lpeudAdrBook[ul].NickName;
  2188. RI.lpszEmailAddress = lpeudAdrBook[ul].Address;
  2189. } else if (lpeudAdrBook[ul].Address) {
  2190. RI.lpszDisplayName = lpeudAdrBook[ul].Address;
  2191. } else if (lpeudAdrBook[ul].Description) {
  2192. RI.lpszDisplayName = lpeudAdrBook[ul].Description;
  2193. } else {
  2194. RI.lpszDisplayName = "";
  2195. }
  2196. RI.ConfirmResult = CONFIRM_ERROR;
  2197. RI.fExport = FALSE;
  2198. RI.lpImportOptions = lpOptions;
  2199. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd,
  2200. ReplaceDialogProc, (LPARAM)&RI);
  2201. switch (RI.ConfirmResult) {
  2202. case CONFIRM_YES:
  2203. case CONFIRM_YES_TO_ALL:
  2204. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2205. lpMailUserWAB = NULL;
  2206. ulCreateFlags |= CREATE_REPLACE;
  2207. goto retry;
  2208. break;
  2209. case CONFIRM_NO:
  2210. hResult = GetExistEntry(lpWabContainer,lpsbinary, ul,
  2211. lpeudAdrBook[ul].NickName,
  2212. NULL);
  2213. goto error1;
  2214. case CONFIRM_ABORT:
  2215. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  2216. goto error1;
  2217. default:
  2218. break;
  2219. }
  2220. }
  2221. }
  2222. if (0!= (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB,
  2223. (LPSPropTagArray)&ptaEid,
  2224. 0,
  2225. &cProps,
  2226. (LPSPropValue *)&lpNewDLProps))) {
  2227. if (hResult == MAPI_W_ERRORS_RETURNED) {
  2228. WABFreeBuffer(lpNewDLProps);
  2229. lpNewDLProps = NULL;
  2230. }
  2231. goto error1;
  2232. }
  2233. lpsbinary[ul].lpb = (LPBYTE)LocalAlloc(LMEM_FIXED,
  2234. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  2235. if (! lpsbinary[ul].lpb) {
  2236. hResult = hrMemory;
  2237. goto error1;
  2238. }
  2239. CopyMemory(lpsbinary[ul].lpb,
  2240. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,
  2241. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  2242. lpsbinary[ul].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
  2243. if (lpMailUserWAB) {
  2244. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2245. lpMailUserWAB = NULL;
  2246. }
  2247. hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  2248. lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb,
  2249. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,
  2250. (LPIID)&IID_IDistList,
  2251. MAPI_DEFERRED_ERRORS|MAPI_MODIFY,
  2252. &ulObjType,
  2253. (LPUNKNOWN *)&lpDistList);
  2254. if (hResult != S_OK) {
  2255. goto error1;
  2256. }
  2257. if (lpNewDLProps) {
  2258. WABFreeBuffer(lpNewDLProps);
  2259. lpNewDLProps = NULL;
  2260. }
  2261. do {
  2262. i = lpeudAdrBook[ul].lpDist->AliasID;
  2263. if (lpeudAdrBook[ul].lpDist->flag == TRUE) {
  2264. hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer,
  2265. sProp[iCreateTemplate].Value.bin.cb,
  2266. (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb,
  2267. ulCreateFlags,
  2268. &lpMailUserWAB);
  2269. if (FAILED(hResult)) {
  2270. goto error1;
  2271. }
  2272. FillEudDiststruct(rgProps,&lpeudAdrBook[ul]);
  2273. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB,
  2274. 3, rgProps, NULL))) {
  2275. goto error1;
  2276. }
  2277. if (hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  2278. KEEP_OPEN_READONLY | FORCE_SAVE)) {
  2279. if (GetScode(hResult) == MAPI_E_COLLISION) {
  2280. if (hResult = GetExistEntry(lpWabContainer,
  2281. &sbTemp,
  2282. 0,
  2283. lpeudAdrBook[ul].lpDist->NickName,
  2284. NULL)) {
  2285. goto error1;
  2286. } else {
  2287. lpsbEntry = &sbTemp;
  2288. }
  2289. } else {
  2290. goto error1;
  2291. }
  2292. } else {
  2293. if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB,
  2294. (LPSPropTagArray)&ptaEid, 0, &cProps, (LPSPropValue *)&lpNewDLProps))) {
  2295. if (hResult == MAPI_W_ERRORS_RETURNED) {
  2296. WABFreeBuffer(lpNewDLProps);
  2297. lpNewDLProps = NULL;
  2298. }
  2299. goto error1;
  2300. } else {
  2301. lpsbEntry = &(lpNewDLProps[ieidPR_ENTRYID].Value.bin);
  2302. }
  2303. }
  2304. if (lpMailUserWAB) {
  2305. // Done with this one
  2306. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2307. lpMailUserWAB = NULL;
  2308. }
  2309. if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList,
  2310. lpsbEntry->cb,
  2311. (LPENTRYID)lpsbEntry->lpb,
  2312. CREATE_CHECK_DUP_STRICT,
  2313. &lpDlWAB))) {
  2314. goto error1;
  2315. }
  2316. hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE);
  2317. goto disc;
  2318. }
  2319. if ((LPENTRYID)lpsbinary[i].lpb == NULL && lpeudAdrBook[i].lpDist!=NULL) {
  2320. FillEudDistList(hwnd, lpWabContainer, sProp, lpOptions, lpeudAdrBook,
  2321. lpsbinary, lpAdrBook, i);
  2322. } else {
  2323. FillMailUser(hwnd, lpWabContainer, sProp, lpOptions,
  2324. (void *)lpeudAdrBook, lpsbinary, i, EUDORA);
  2325. }
  2326. if (0 != (hResult = lpDistList->lpVtbl->CreateEntry(lpDistList,
  2327. lpsbinary[i].cb, (LPENTRYID)lpsbinary[i].lpb, CREATE_CHECK_DUP_STRICT,
  2328. &lpDlWAB))) {
  2329. goto error1;
  2330. }
  2331. if (0 != (hResult = lpDlWAB->lpVtbl->SaveChanges(lpDlWAB, FORCE_SAVE))) {
  2332. if (MAPI_E_FOLDER_CYCLE ==hResult) {
  2333. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_LOOPING), ARRAYSIZE(szGlobalTempAlloc));
  2334. MessageBox(NULL,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ENTRY_NOIMPORT),MB_OK);
  2335. }
  2336. hResult = S_OK;
  2337. goto error1;
  2338. }
  2339. disc:
  2340. if (lpNewDLProps) {
  2341. WABFreeBuffer(lpNewDLProps);
  2342. lpNewDLProps = NULL;
  2343. }
  2344. if (lpDlWAB) {
  2345. lpDlWAB->lpVtbl->Release(lpDlWAB);
  2346. lpDlWAB = NULL;
  2347. }
  2348. lpeudAdrBook[ul].lpDist=FreeEuddistlist(lpeudAdrBook[ul].lpDist);
  2349. } while (lpeudAdrBook[ul].lpDist != NULL);
  2350. error1:
  2351. if (lpNewDLProps) {
  2352. WABFreeBuffer(lpNewDLProps);
  2353. }
  2354. if (lpDistList) {
  2355. lpDistList->lpVtbl->Release(lpDistList);
  2356. lpDistList = NULL;
  2357. }
  2358. if (lpDlWAB) {
  2359. lpDlWAB->lpVtbl->Release(lpDlWAB);
  2360. lpDlWAB = NULL;
  2361. }
  2362. if (lpMailUserWAB) {
  2363. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2364. lpMailUserWAB = NULL;
  2365. }
  2366. return(hResult);
  2367. }
  2368. /******************************************************************************
  2369. * FUNCTION NAME:FillEudWABStruct
  2370. *
  2371. * PURPOSE: To fill the SpropValue array.
  2372. *
  2373. * PARAMETERS: eudAdrBook = pointer to the EUDADRBOOK structure.
  2374. * rgProps = pointer to the SpropValue array.
  2375. *
  2376. * RETURNS: HRESULT
  2377. ******************************************************************************/
  2378. HRESULT FillEudWABStruct(LPSPropValue rgProps, EUDADRBOOK *eudAdrBook)
  2379. {
  2380. HRESULT hr = S_OK;
  2381. rgProps[1].Value.lpszA = eudAdrBook->NickName;
  2382. if (eudAdrBook->NickName) {
  2383. rgProps[1].ulPropTag = PR_DISPLAY_NAME;
  2384. } else {
  2385. rgProps[1].ulPropTag = PR_NULL;
  2386. }
  2387. rgProps[0].Value.lpszA = eudAdrBook->Address;
  2388. if (eudAdrBook->Address) {
  2389. rgProps[0].ulPropTag = PR_EMAIL_ADDRESS;
  2390. rgProps[2].ulPropTag = PR_ADDRTYPE;
  2391. rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP);
  2392. } else {
  2393. rgProps[0].ulPropTag = PR_NULL;
  2394. rgProps[2].ulPropTag = PR_NULL;
  2395. rgProps[2].Value.lpszA = NULL;
  2396. }
  2397. rgProps[3].Value.lpszA = eudAdrBook->Description;
  2398. if (eudAdrBook->Description) {
  2399. rgProps[3].ulPropTag = PR_COMMENT;
  2400. } else {
  2401. rgProps[3].ulPropTag = PR_NULL;
  2402. }
  2403. rgProps[4].Value.lpszA = eudAdrBook->NickName;
  2404. if (eudAdrBook->NickName) {
  2405. rgProps[4].ulPropTag = PR_NICKNAME;
  2406. } else {
  2407. rgProps[4].ulPropTag = PR_NULL;
  2408. }
  2409. return(hr);
  2410. }
  2411. /******************************************************************************
  2412. * FUNCTION NAME:FillEudDiststruct
  2413. *
  2414. * PURPOSE: To fill the SpropValue array.
  2415. *
  2416. * PARAMETERS: eudAdrBook = pointer to the EUDADRBOOK structure.
  2417. * rgProps = pointer to the SpropValue array.
  2418. *
  2419. * RETURNS: none
  2420. ******************************************************************************/
  2421. void FillEudDiststruct(LPSPropValue rgProps, EUDADRBOOK *eudAdrBook)
  2422. {
  2423. rgProps[1].Value.lpszA = eudAdrBook->lpDist->NickName;
  2424. if (eudAdrBook->lpDist->NickName) {
  2425. rgProps[1].ulPropTag = PR_DISPLAY_NAME;
  2426. } else {
  2427. rgProps[1].ulPropTag = PR_NULL;
  2428. }
  2429. rgProps[0].Value.lpszA = eudAdrBook->lpDist->Address;
  2430. if (eudAdrBook->lpDist->Address) {
  2431. rgProps[0].ulPropTag = PR_EMAIL_ADDRESS;
  2432. rgProps[2].ulPropTag = PR_ADDRTYPE;
  2433. rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP);
  2434. } else {
  2435. rgProps[0].ulPropTag = PR_NULL;
  2436. rgProps[2].ulPropTag = PR_NULL;
  2437. rgProps[2].Value.lpszA = NULL;
  2438. }
  2439. }
  2440. /******************************************************************************
  2441. * FUNCTION NAME:FreeEuddistlist
  2442. *
  2443. * PURPOSE: To free one node from EUDDISTLIST(linked list)
  2444. *
  2445. * PARAMETERS: lpDist = pointer to the EUDDISTLIST structure.
  2446. *
  2447. * RETURNS: LPEUDDISTLIST , pointer to the next link.
  2448. ******************************************************************************/
  2449. LPEUDDISTLIST FreeEuddistlist(LPEUDDISTLIST lpDist)
  2450. {
  2451. LPEUDDISTLIST lpTemp = NULL;
  2452. if (lpDist == NULL) {
  2453. return(NULL);
  2454. }
  2455. lpTemp = lpDist->lpDist;
  2456. if (lpDist->NickName) {
  2457. LocalFree((HLOCAL)lpDist->NickName);
  2458. }
  2459. lpDist->NickName = NULL;
  2460. if (lpDist->Description) {
  2461. LocalFree((HLOCAL)lpDist->Description);
  2462. }
  2463. lpDist->Description = NULL;
  2464. if (lpDist->Address) {
  2465. LocalFree((HLOCAL)lpDist->Address);
  2466. }
  2467. lpDist->Address = NULL;
  2468. LocalFree((HLOCAL)lpDist);
  2469. lpDist = NULL;
  2470. return(lpTemp);
  2471. }
  2472. /******************************************************************************
  2473. * FUNCTION NAME:Getstr
  2474. *
  2475. * PURPOSE: Case insensitive equivalent of strstr
  2476. *
  2477. * PARAMETERS: szSource = string to search
  2478. * szToken = string to search for
  2479. *
  2480. * RETURNS: pointer to the first occurrence of szToken in szSource
  2481. ******************************************************************************/
  2482. TCHAR* Getstr(TCHAR* szSource, TCHAR* szToken)
  2483. {
  2484. int i,
  2485. nLength;
  2486. LPTSTR szdummy = NULL;
  2487. szdummy = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szToken)+1));
  2488. if (!szdummy)
  2489. return(NULL);
  2490. StrCpyN(szdummy, szToken, strlen(szToken)+1);
  2491. _strupr(szdummy) ;
  2492. nLength = lstrlen (szdummy) ;
  2493. while (*szSource && *(szSource + nLength-1)) {
  2494. for (i = 0 ;i < nLength ; i++) {
  2495. TCHAR k = ToUpper(szSource[i]) ;
  2496. if (szdummy[i] != k)
  2497. break ;
  2498. if (i == (nLength - 1)) {
  2499. LocalFree(szdummy);
  2500. return(szSource);
  2501. }
  2502. }
  2503. szSource ++ ;
  2504. }
  2505. LocalFree(szdummy);
  2506. return(NULL);
  2507. }
  2508. /******************************************************************************
  2509. * FUNCTION NAME:ShiftAdd
  2510. *
  2511. * PURPOSE: To get the address size from a binary file by reading four bytes.
  2512. * This function reads four consecutive bytes from a buffer and
  2513. * converts it to a ULONG value.
  2514. *
  2515. * PARAMETERS: offset = position in the buffer from where to read
  2516. * szBuffer = buffer
  2517. *
  2518. * RETURNS: ULONG, size
  2519. ******************************************************************************/
  2520. ULONG ShiftAdd(int offset, TCHAR *szBuffer)
  2521. {
  2522. ULONG ulSize = 0;
  2523. int iCounter = 0;
  2524. for (iCounter = 3; iCounter > 0; iCounter--) {
  2525. ulSize |= (unsigned long)((unsigned char)szBuffer[iCounter + offset]);
  2526. ulSize <<= 8;
  2527. }
  2528. ulSize |= (unsigned long)((unsigned char)szBuffer[iCounter + offset]);
  2529. return(ulSize);
  2530. }
  2531. /******************************************************************************
  2532. *********************Athena Functions*****************************************
  2533. ******************************************************************************
  2534. * FUNCTION NAME:MigrateAthUser
  2535. *
  2536. * PURPOSE: To get the installation path of the address book and starts
  2537. * processing the Athena address book
  2538. *
  2539. * PARAMETERS: hwnd = Handle to the parent Window
  2540. * lpAdrBook = pointer to the IADRBOOK interface
  2541. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  2542. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  2543. *
  2544. * RETURNS: HRESULT
  2545. ******************************************************************************/
  2546. HRESULT MigrateAthUser(HWND hwnd, LPWAB_IMPORT_OPTIONS lpOptions,
  2547. LPWAB_PROGRESS_CALLBACK lpProgressCB, LPADRBOOK lpAdrBook)
  2548. {
  2549. TCHAR szFileName[MAX_FILE_NAME];
  2550. HRESULT hResult;
  2551. if (FALSE == GetFileToImport(hwnd, szFileName, ARRAYSIZE(szFileName), ATHENA16)) {
  2552. return(ResultFromScode(MAPI_E_USER_CANCEL));
  2553. }
  2554. hResult = ParseAthAddressBook(hwnd, szFileName, lpOptions, lpProgressCB,
  2555. lpAdrBook);
  2556. return(hResult);
  2557. }
  2558. /*****************************************************************************
  2559. * FUNCTION NAME:ParseAthAddressBook
  2560. *
  2561. * PURPOSE: To get the address book in a file, process addresses and fill WAB.
  2562. *
  2563. * PARAMETERS: hwnd = Handle to the parent Window
  2564. * szFileName = path of the address book.
  2565. * lpProgressCB = pointer to the WAB_PROGRESS_CALLBACK function.
  2566. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  2567. * lpAdrBook = pointer to the IADRBOOK interface
  2568. *
  2569. * RETURNS: HRESULT
  2570. ******************************************************************************/
  2571. HRESULT ParseAthAddressBook(HWND hwnd,LPTSTR szFileName,
  2572. LPWAB_IMPORT_OPTIONS lpOptions, LPWAB_PROGRESS_CALLBACK lpProgressCB,
  2573. LPADRBOOK lpAdrBook)
  2574. {
  2575. ULONG ulCount=0, ulRead=0, ulFileSize, i, cProps, cError=0;
  2576. HANDLE hFile = NULL;
  2577. ABCREC abcrec;
  2578. TCHAR Buffer[ATHENASTRUCTURE];
  2579. LPABCONT lpWabContainer = NULL;
  2580. HRESULT hResult;
  2581. static LPSPropValue sProp;
  2582. WAB_PROGRESS Progress;
  2583. lpOptions->ReplaceOption = WAB_REPLACE_PROMPT;
  2584. /* Description of athena16 addressbook
  2585. Size of each recipient list - 190 bytes
  2586. Display Name : 81 bytes
  2587. Address : 81 bytes
  2588. starting from 28 bytes.
  2589. */
  2590. hFile = CreateFile(szFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
  2591. OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  2592. if (INVALID_HANDLE_VALUE == hFile) {
  2593. return(ResultFromScode(MAPI_E_NOT_FOUND));
  2594. }
  2595. ulFileSize = GetFileSize(hFile, NULL);
  2596. if ((ulFileSize % ATHENASTRUCTURE) != 0) {
  2597. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR_ADDRESSBOOK), ARRAYSIZE(szGlobalTempAlloc));
  2598. MessageBox(hwnd, szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR), MB_OK);
  2599. goto Error;
  2600. }
  2601. if (! ulFileSize) {
  2602. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_NO_ENTRY), ARRAYSIZE(szGlobalTempAlloc));
  2603. MessageBox(hwnd, szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_MESSAGE), MB_OK);
  2604. return(ResultFromScode(MAPI_E_CALL_FAILED));
  2605. }
  2606. ulCount = ulFileSize / ATHENASTRUCTURE;
  2607. Progress.denominator = ulCount;
  2608. Progress.numerator = 0;
  2609. Progress.lpText = NULL;
  2610. if (0 != (hResult = OpenWabContainer(&lpWabContainer, lpAdrBook))) {
  2611. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_WAB_ERROR), ARRAYSIZE(szGlobalTempAlloc));
  2612. MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK);
  2613. return(hResult);
  2614. }
  2615. if (0 != (hResult = lpWabContainer->lpVtbl->GetProps(lpWabContainer,
  2616. (LPSPropTagArray)&ptaCon, 0, &cProps, (LPSPropValue *)&sProp))) {
  2617. if (hResult == MAPI_W_ERRORS_RETURNED) {
  2618. WABFreeBuffer(sProp);
  2619. sProp = NULL;
  2620. }
  2621. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_WAB_ERROR), ARRAYSIZE(szGlobalTempAlloc));
  2622. MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK);
  2623. return(hResult);
  2624. }
  2625. for (i = 0; i < ulFileSize / ATHENASTRUCTURE; i++) {
  2626. Progress.numerator = i;
  2627. lpProgressCB(hwnd, &Progress);
  2628. if (! ReadFile(hFile, Buffer, ATHENASTRUCTURE, &ulRead, NULL)) {
  2629. goto Error;
  2630. }
  2631. if (NULL == StrCpyN(abcrec.DisplayName, Buffer + ATHENAADROFFSET,
  2632. MAX_NAME_SIZE + 1)) {
  2633. goto Error;
  2634. }
  2635. if (NULL == StrCpyN(abcrec.EmailAddress,
  2636. Buffer + ATHENAADROFFSET + MAX_NAME_SIZE + 1, MAX_EMA_SIZE + 1)) {
  2637. goto Error;
  2638. }
  2639. if (strlen(abcrec.DisplayName) == 0 || lstrlen(abcrec.EmailAddress) == 0) {
  2640. continue;
  2641. }
  2642. if (0 != FillAthenaUser(hwnd, lpWabContainer,sProp,lpOptions,&abcrec)) {
  2643. cError++;
  2644. }
  2645. }
  2646. Error:
  2647. if (sProp) {
  2648. WABFreeBuffer(sProp);
  2649. sProp = NULL;
  2650. }
  2651. if (lpWabContainer) {
  2652. lpWabContainer->lpVtbl->Release(lpWabContainer);
  2653. lpWabContainer = NULL;
  2654. }
  2655. if (hFile) {
  2656. CloseHandle(hFile);
  2657. }
  2658. if (cError) {
  2659. StrCpyN(szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_GERNERIC_ERROR), ARRAYSIZE(szGlobalTempAlloc));
  2660. MessageBox(hwnd,szGlobalTempAlloc, LoadStringToGlobalBuffer(IDS_ERROR),MB_OK);
  2661. }
  2662. return(hResult);
  2663. }
  2664. /*****************************************************************************
  2665. * FUNCTION NAME:FillAthenaUser
  2666. *
  2667. * PURPOSE: To create an entry for the athena16 mail user in the wab.
  2668. *
  2669. * PARAMETERS: hwnd - hwnd of parent
  2670. * lpWabContainer = pointer to the IABCONT interface
  2671. * sProp = pointer to SPropValue
  2672. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  2673. * lpabcrec = pointer to the ABCREC structure.
  2674. *
  2675. * RETURNS: HRESULT
  2676. ******************************************************************************/
  2677. HRESULT FillAthenaUser(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp,
  2678. LPWAB_IMPORT_OPTIONS lpOptions, LPABCREC lpabcrec)
  2679. {
  2680. ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT;
  2681. ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER;
  2682. LPMAPIPROP lpMailUserWAB = NULL;
  2683. HRESULT hResult;
  2684. REPLACE_INFO RI = {0};
  2685. SPropValue rgProps[3];
  2686. retry:
  2687. hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer,
  2688. sProp[ iCreateTemplate].Value.bin.cb,
  2689. (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb,
  2690. ulCreateFlags,
  2691. &lpMailUserWAB);
  2692. if (FAILED(hResult)) {
  2693. goto Error;
  2694. }
  2695. rgProps[1].ulPropTag = PR_DISPLAY_NAME;
  2696. rgProps[1].Value.lpszA = lpabcrec->DisplayName;
  2697. rgProps[0].Value.lpszA = lpabcrec->EmailAddress;
  2698. if (lpabcrec->EmailAddress) {
  2699. rgProps[0].ulPropTag = PR_EMAIL_ADDRESS;
  2700. rgProps[2].ulPropTag = PR_ADDRTYPE;
  2701. rgProps[2].Value.lpszA = LoadStringToGlobalBuffer(IDS_SMTP);
  2702. } else {
  2703. rgProps[0].ulPropTag = PR_NULL;
  2704. rgProps[2].ulPropTag = PR_NULL;
  2705. rgProps[2].Value.lpszA = NULL;
  2706. }
  2707. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 3,
  2708. rgProps, NULL))) {
  2709. goto Error;
  2710. }
  2711. hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  2712. KEEP_OPEN_READONLY | FORCE_SAVE);
  2713. if (GetScode(hResult) == MAPI_E_COLLISION) {
  2714. if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) {
  2715. if (lpMailUserWAB) {
  2716. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2717. }
  2718. lpMailUserWAB = NULL;
  2719. ulCreateFlags |= CREATE_REPLACE;
  2720. goto retry;
  2721. }
  2722. if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) {
  2723. hResult = S_OK;
  2724. goto Error;
  2725. }
  2726. if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) {
  2727. RI.lpszDisplayName = lpabcrec->DisplayName;
  2728. RI.lpszEmailAddress = lpabcrec->EmailAddress;
  2729. RI.ConfirmResult = CONFIRM_ERROR;
  2730. RI.fExport = FALSE;
  2731. RI.lpImportOptions = lpOptions;
  2732. DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_ImportReplace), hwnd,
  2733. ReplaceDialogProc, (LPARAM)&RI);
  2734. switch (RI.ConfirmResult) {
  2735. case CONFIRM_YES:
  2736. case CONFIRM_YES_TO_ALL:
  2737. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2738. lpMailUserWAB = NULL;
  2739. ulCreateFlags |= CREATE_REPLACE;
  2740. goto retry;
  2741. break;
  2742. case CONFIRM_NO_TO_ALL:
  2743. case CONFIRM_NO:
  2744. hResult = hrSuccess;
  2745. break;
  2746. case CONFIRM_ABORT:
  2747. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  2748. goto Error;
  2749. default:
  2750. break;
  2751. }
  2752. }
  2753. }
  2754. Error:
  2755. if (lpMailUserWAB) {
  2756. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  2757. lpMailUserWAB = NULL;
  2758. }
  2759. return(hResult);
  2760. }
  2761. /******************************************************************************
  2762. *********************Common Functions*****************************************
  2763. ******************************************************************************
  2764. * FUNCTION NAME:OpenWabContainer
  2765. *
  2766. * PURPOSE: To get the pointer to the IABCCONT interface using the
  2767. * IADRBOOK interface.
  2768. *
  2769. * PARAMETERS: lpAdrBook = pointer to the IADRBOOK interface.
  2770. * lppWabContainer = pointer to the IABCONT interface.
  2771. *
  2772. *
  2773. * RETURNS: HRESULT
  2774. ******************************************************************************/
  2775. HRESULT OpenWabContainer(LPABCONT *lppWabContainer, LPADRBOOK lpAdrBook)
  2776. {
  2777. LPENTRYID lpEntryID = NULL;
  2778. ULONG cbEntryID;
  2779. ULONG ulObjType;
  2780. HRESULT hResult;
  2781. hResult = lpAdrBook->lpVtbl->GetPAB(lpAdrBook, &cbEntryID, &lpEntryID);
  2782. if (FAILED(hResult)) {
  2783. goto Err;
  2784. }
  2785. hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook, cbEntryID, lpEntryID,
  2786. NULL, 0, &ulObjType, (LPUNKNOWN *)lppWabContainer);
  2787. Err:
  2788. if (lpEntryID) {
  2789. WABFreeBuffer(lpEntryID);
  2790. }
  2791. return(hResult);
  2792. }
  2793. /******************************************************************************
  2794. * FUNCTION NAME:GetFileToImport
  2795. *
  2796. * PURPOSE: To get the path of the address book file using the GetOpenFileName
  2797. *
  2798. * PARAMETERS: hwnd = Handle to the parent Window
  2799. * szFileName = path of the address book
  2800. * type = containing the value indicating whether it is a EUDORA or
  2801. * NETSCAPE or ATHENA16
  2802. *
  2803. * RETURNS: BOOL
  2804. ******************************************************************************/
  2805. BOOL GetFileToImport(HWND hwnd, LPTSTR szFileName, DWORD cchFileName, int type)
  2806. {
  2807. OPENFILENAME ofn;
  2808. BOOL ret;
  2809. TCHAR szFile[MAX_FILE_NAME];
  2810. TCHAR szFilter[MAX_FILE_NAME];
  2811. ULONG ulSize = 0;
  2812. switch (type) {
  2813. case NETSCAPE:
  2814. StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_NETSCAPE_PATH), ARRAYSIZE(szFile));
  2815. ulSize = SizeLoadStringToGlobalBuffer(IDS_NETSCAPE_FILE);
  2816. CopyMemory(szFilter, szGlobalAlloc, ulSize);
  2817. szFilter[ulSize]=szFilter[ulSize+1]='\0';
  2818. ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_NETSCAPE_TITLE);
  2819. break;
  2820. case ATHENA16:
  2821. StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_ATHENA16_PATH), ARRAYSIZE(szFile));
  2822. ulSize = SizeLoadStringToGlobalBuffer(IDS_ATHENA16_FILE);
  2823. CopyMemory(szFilter, szGlobalAlloc, ulSize);
  2824. szFilter[ulSize]=szFilter[ulSize+1]='\0';
  2825. ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_ATHENA16_TITLE);
  2826. break;
  2827. case EUDORA:
  2828. StrCpyN(szFile, LoadStringToGlobalBuffer(IDS_EUDORA_PATH), ARRAYSIZE(szFile));
  2829. ulSize = SizeLoadStringToGlobalBuffer(IDS_EUDORA_FILE);
  2830. CopyMemory(szFilter, szGlobalAlloc, ulSize);
  2831. szFilter[ulSize]=szFilter[ulSize+1]='\0';
  2832. ofn.lpstrTitle = LoadStringToGlobalBuffer(IDS_EUDORA_TITLE);
  2833. break;
  2834. }
  2835. ofn.lStructSize = sizeof(ofn);
  2836. ofn.hwndOwner = hwnd;
  2837. ofn.hInstance = NULL;
  2838. ofn.lpstrFilter = szFilter;
  2839. ofn.lpstrCustomFilter = NULL;
  2840. ofn.nMaxCustFilter = 0;
  2841. ofn.nFilterIndex = 0;
  2842. ofn.lpstrFile = szFile;
  2843. ofn.nMaxFile = sizeof(szFile);
  2844. ofn.lpstrFileTitle = NULL;
  2845. ofn.nMaxFileTitle = 0;
  2846. ofn.lpstrInitialDir = NULL;
  2847. ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_HIDEREADONLY;
  2848. ofn.nFileOffset = 0;
  2849. ofn.nFileExtension = 0;
  2850. ofn.lpstrDefExt = NULL;
  2851. ofn.lCustData = 0;
  2852. ofn.lpfnHook = ComDlg32DlgProc;
  2853. ofn.lpTemplateName = NULL;
  2854. ret = GetOpenFileName(&ofn);
  2855. if (ret) {
  2856. StrCpyN(szFileName, szFile, cchFileName);
  2857. }
  2858. return(ret);
  2859. }
  2860. INT_PTR CALLBACK ReplaceDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  2861. LPREPLACE_INFO lpRI = (LPREPLACE_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
  2862. switch (message) {
  2863. case WM_INITDIALOG:
  2864. {
  2865. TCHAR szFormat[MAX_RESOURCE_STRING + 1];
  2866. LPTSTR lpszMessage = NULL;
  2867. ULONG ids;
  2868. SetWindowLongPtr(hwnd, DWLP_USER, lParam); //Save this for future reference
  2869. lpRI = (LPREPLACE_INFO)lParam;
  2870. if (lpRI->fExport) {
  2871. ids = lpRI->lpszEmailAddress ?
  2872. IDS_REPLACE_MESSAGE_EXPORT_2 : IDS_REPLACE_MESSAGE_EXPORT_1;
  2873. } else {
  2874. ids = lpRI->lpszEmailAddress ?
  2875. IDS_REPLACE_MESSAGE_IMPORT_2 : IDS_REPLACE_MESSAGE_IMPORT_1;
  2876. }
  2877. if (LoadString(hInst,
  2878. ids,
  2879. szFormat, sizeof(szFormat))) {
  2880. LPTSTR lpszArg[2] = {lpRI->lpszDisplayName, lpRI->lpszEmailAddress};
  2881. if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  2882. szFormat,
  2883. 0, 0, //ignored
  2884. (LPTSTR)&lpszMessage,
  2885. 0,
  2886. (va_list *)lpszArg)) {
  2887. DebugTrace("FormatMessage -> %u\n", GetLastError());
  2888. } else {
  2889. DebugTrace("Status Message: %s\n", lpszMessage);
  2890. if (! SetDlgItemText(hwnd, IDC_Replace_Message, lpszMessage)) {
  2891. DebugTrace("SetDlgItemText -> %u\n", GetLastError());
  2892. }
  2893. LocalFree(lpszMessage);
  2894. }
  2895. }
  2896. return(TRUE);
  2897. }
  2898. case WM_COMMAND :
  2899. switch (wParam) {
  2900. case IDCANCEL:
  2901. lpRI->ConfirmResult = CONFIRM_ABORT;
  2902. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  2903. return(0);
  2904. case IDCLOSE:
  2905. case IDNO:
  2906. lpRI->ConfirmResult = CONFIRM_NO;
  2907. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  2908. return(0);
  2909. case IDOK:
  2910. case IDYES:
  2911. // Set the state of the parameter
  2912. lpRI->ConfirmResult = CONFIRM_YES;
  2913. SendMessage(hwnd, WM_CLOSE, 0, 0);
  2914. return(0);
  2915. case IDC_NoToAll:
  2916. lpRI->ConfirmResult = CONFIRM_NO_TO_ALL;
  2917. if (lpRI->fExport) {
  2918. lpRI->lpExportOptions->ReplaceOption = WAB_REPLACE_NEVER;
  2919. } else {
  2920. lpRI->lpImportOptions->ReplaceOption = WAB_REPLACE_NEVER;
  2921. }
  2922. SendMessage(hwnd, WM_CLOSE, 0, 0);
  2923. return(0);
  2924. case IDC_YesToAll:
  2925. lpRI->ConfirmResult = CONFIRM_YES_TO_ALL;
  2926. if (lpRI->fExport) {
  2927. lpRI->lpImportOptions->ReplaceOption = WAB_REPLACE_ALWAYS;
  2928. } else {
  2929. lpRI->lpExportOptions->ReplaceOption = WAB_REPLACE_ALWAYS;
  2930. }
  2931. SendMessage(hwnd, WM_CLOSE, 0, 0);
  2932. return(0);
  2933. case IDM_EXIT:
  2934. SendMessage(hwnd, WM_DESTROY, 0, 0L);
  2935. return(0);
  2936. }
  2937. break ;
  2938. case IDCANCEL:
  2939. SendMessage(hwnd, WM_CLOSE, 0, 0);
  2940. break;
  2941. case WM_CLOSE:
  2942. EndDialog(hwnd, FALSE);
  2943. return(0);
  2944. default:
  2945. return(FALSE);
  2946. }
  2947. return(TRUE);
  2948. }
  2949. INT_PTR CALLBACK ErrorDialogProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {
  2950. LPERROR_INFO lpEI = (LPERROR_INFO)GetWindowLongPtr(hwnd, DWLP_USER);
  2951. switch (message) {
  2952. case WM_INITDIALOG:
  2953. {
  2954. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  2955. LPTSTR lpszMessage;
  2956. SetWindowLongPtr(hwnd, DWLP_USER, lParam); // Save this for future reference
  2957. lpEI = (LPERROR_INFO)lParam;
  2958. if (LoadString(hInst,
  2959. lpEI->ids,
  2960. szBuffer, sizeof(szBuffer))) {
  2961. LPTSTR lpszArg[2] = {lpEI->lpszDisplayName, lpEI->lpszEmailAddress};
  2962. if (! FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  2963. szBuffer,
  2964. 0, 0, //ignored
  2965. (LPTSTR)&lpszMessage,
  2966. 0,
  2967. (va_list *)lpszArg)) {
  2968. DebugTrace("FormatMessage -> %u\n", GetLastError());
  2969. } else {
  2970. DebugTrace("Status Message: %s\n", lpszMessage);
  2971. if (! SetDlgItemText(hwnd, IDC_ErrorMessage, lpszMessage)) {
  2972. DebugTrace("SetDlgItemText -> %u\n", GetLastError());
  2973. }
  2974. LocalFree(lpszMessage);
  2975. }
  2976. }
  2977. return(TRUE);
  2978. }
  2979. case WM_COMMAND :
  2980. switch (wParam) {
  2981. case IDCANCEL:
  2982. lpEI->ErrorResult = ERROR_ABORT;
  2983. // fall through to close.
  2984. case IDCLOSE:
  2985. // Ignore the contents of the radio button
  2986. SendMessage(hwnd, WM_CLOSE, 0, 0L);
  2987. return(0);
  2988. case IDOK:
  2989. // Get the contents of the radio button
  2990. lpEI->lpImportOptions->fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1);
  2991. lpEI->lpExportOptions->fNoErrors = (IsDlgButtonChecked(hwnd, IDC_NoMoreError) == 1);
  2992. SendMessage(hwnd, WM_CLOSE, 0, 0);
  2993. return(0);
  2994. case IDM_EXIT:
  2995. SendMessage(hwnd, WM_DESTROY, 0, 0L);
  2996. return(0);
  2997. }
  2998. break ;
  2999. case IDCANCEL:
  3000. // treat it like a close
  3001. SendMessage(hwnd, WM_CLOSE, 0, 0);
  3002. break;
  3003. case WM_CLOSE:
  3004. EndDialog(hwnd, FALSE);
  3005. return(0);
  3006. default:
  3007. return(FALSE);
  3008. }
  3009. return(TRUE);
  3010. }
  3011. /******************************************************************************
  3012. * FUNCTION NAME:GetRegistryPath
  3013. *
  3014. * PURPOSE: To Get path for eudora and netscape installation
  3015. *
  3016. * PARAMETERS: szFileName = buffer containing the installation path
  3017. * type = containing the value indicating whether it is a EUDORA or
  3018. * NETSCAPE.
  3019. *
  3020. * RETURNS: HRESULT
  3021. ******************************************************************************/
  3022. HRESULT GetRegistryPath(LPTSTR szFileName, ULONG cchSize, int type)
  3023. {
  3024. HKEY phkResult = NULL;
  3025. LONG Registry;
  3026. BOOL bResult;
  3027. LPOSVERSIONINFO lpVersionInformation ;
  3028. TCHAR *lpData = NULL, *RegPath = NULL, *path = NULL;
  3029. unsigned long size = MAX_FILE_NAME;
  3030. HKEY hKey = (type == NETSCAPE ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER);
  3031. HRESULT hResult = S_OK;
  3032. lpData = (TCHAR *)LocalAlloc(LMEM_FIXED, 3*MAX_FILE_NAME);
  3033. if (!lpData) {
  3034. hResult = hrMemory;
  3035. goto error;
  3036. }
  3037. RegPath = (TCHAR *)LocalAlloc(LMEM_FIXED, MAX_FILE_NAME);
  3038. if (! RegPath) {
  3039. hResult = hrMemory;
  3040. goto error;
  3041. }
  3042. path = (TCHAR *)LocalAlloc(LMEM_FIXED, MAX_STRING_SIZE);
  3043. if (! path) {
  3044. hResult = hrMemory;
  3045. goto error;
  3046. }
  3047. switch (type) {
  3048. case(NETSCAPE):
  3049. StrCpyN(RegPath, LoadStringToGlobalBuffer(IDS_NETSCAPE_REGKEY), MAX_FILE_NAME);
  3050. StrCpyN(path, LoadStringToGlobalBuffer(IDS_NETSCAPE_ADDRESS_PATH), MAX_STRING_SIZE);
  3051. break;
  3052. case(EUDORA):
  3053. StrCpyN(RegPath, LoadStringToGlobalBuffer(IDS_EUDORA_32_REGKEY), MAX_FILE_NAME);
  3054. StrCpyN(path, LoadStringToGlobalBuffer(IDS_EUDORA_ADDRESS_PATH), MAX_STRING_SIZE);
  3055. break;
  3056. }
  3057. lpVersionInformation = (LPOSVERSIONINFO)LocalAlloc(LMEM_FIXED, sizeof(OSVERSIONINFO));
  3058. if (!lpVersionInformation) {
  3059. hResult = hrMemory;
  3060. goto error;
  3061. }
  3062. lpVersionInformation->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  3063. if ((bResult = GetVersionEx(lpVersionInformation)) == FALSE) {
  3064. hResult = E_FAIL;
  3065. goto error;
  3066. }
  3067. switch (lpVersionInformation->dwPlatformId) {
  3068. case (VER_PLATFORM_WIN32s):
  3069. hResult = E_FAIL;
  3070. goto error;
  3071. break;
  3072. case (VER_PLATFORM_WIN32_WINDOWS):
  3073. case (VER_PLATFORM_WIN32_NT):
  3074. Registry = RegOpenKeyEx(hKey,RegPath, 0, KEY_QUERY_VALUE, &phkResult);
  3075. // bug 35949 - not finding the correct key under HKLM for Netscape
  3076. // Try again under HKCU
  3077. if (type == NETSCAPE && Registry != ERROR_SUCCESS) {
  3078. Registry = RegOpenKeyEx(HKEY_CURRENT_USER, RegPath, 0, KEY_QUERY_VALUE,
  3079. &phkResult);
  3080. }
  3081. if (Registry != ERROR_SUCCESS) {
  3082. hResult = E_FAIL;
  3083. goto error;
  3084. }
  3085. break;
  3086. }
  3087. Registry = RegQueryValueEx(phkResult, path, NULL, NULL, (LPBYTE)lpData, &size);
  3088. if (Registry != ERROR_SUCCESS) {
  3089. hResult = E_FAIL;
  3090. goto error;
  3091. }
  3092. StrCpyN(szFileName,lpData, cchSize);
  3093. if (type == EUDORA) {
  3094. // this key value contains three items:
  3095. // Path-to-Eudora,exe<space>Path-to-Eudora-Dir<space>Path-to-ini-file
  3096. // We want the middle entry only
  3097. LPTSTR lp = szFileName;
  3098. while (*lp && ! IsSpace(lp)) {
  3099. lp = CharNext(lp);
  3100. }
  3101. if (IsSpace(lp)) {
  3102. // overwrite everything upto the first space
  3103. lp = CharNext(lp);
  3104. StrCpyN(szFileName, lp, cchSize);
  3105. // Find the next space and terminate the filename string there
  3106. lp = szFileName;
  3107. while (*lp && ! IsSpace(lp)) {
  3108. lp = CharNext(lp);
  3109. }
  3110. if (IsSpace(lp)) {
  3111. *lp = '\0';
  3112. }
  3113. }
  3114. }
  3115. error:
  3116. if (phkResult) {
  3117. RegCloseKey(phkResult);
  3118. }
  3119. if (hKey) {
  3120. RegCloseKey(hKey);
  3121. }
  3122. if (lpVersionInformation) {
  3123. LocalFree((HLOCAL)lpVersionInformation);
  3124. }
  3125. if (lpData) {
  3126. LocalFree((HLOCAL)lpData);
  3127. }
  3128. if (RegPath) {
  3129. LocalFree((HLOCAL)RegPath);
  3130. }
  3131. if (path) {
  3132. LocalFree((HLOCAL)path);
  3133. }
  3134. return(hResult);
  3135. }
  3136. /******************************************************************************
  3137. * FUNCTION NAME:GetExistEntry
  3138. *
  3139. * PURPOSE: To fill the Sbinary array for an already existig entry in the WAB
  3140. * for which user has selected NO as replace option.
  3141. *
  3142. * PARAMETERS: lpWabContainer = pointer to the IABCONT interface.
  3143. * lpsbinary = pointer to SBinary array.
  3144. * ucount = position in the SBinary array where the ENTRY_ID has
  3145. * to be filled.
  3146. * szDisplayName = display nmae of the user that has to be searched.
  3147. * szNickName = if no DisplayName, use NickName
  3148. *
  3149. * RETURNS: HRESULT
  3150. ******************************************************************************/
  3151. HRESULT GetExistEntry(LPABCONT lpWabContainer, LPSBinary lpsbinary, ULONG ucount,
  3152. LPTSTR szDisplayName, LPTSTR szNickName)
  3153. {
  3154. HRESULT hResult;
  3155. LPMAPITABLE lpMapiTable = NULL;
  3156. SRestriction Restriction;
  3157. SPropValue pProp;
  3158. LPSRowSet lpsrowset=NULL;
  3159. SPropertyRestriction PropertyRestriction;
  3160. BOOKMARK bkmark;
  3161. bkmark = BOOKMARK_BEGINNING;
  3162. pProp.ulPropTag = PR_DISPLAY_NAME;
  3163. if (szDisplayName && lstrlen(szDisplayName)) {
  3164. pProp.Value.lpszA = szDisplayName;
  3165. } else if (szNickName && lstrlen(szNickName)) {
  3166. pProp.Value.lpszA = szNickName;
  3167. }
  3168. PropertyRestriction.relop=RELOP_EQ;
  3169. PropertyRestriction.ulPropTag=PR_DISPLAY_NAME;
  3170. PropertyRestriction.lpProp=&pProp;
  3171. Restriction.rt=RES_PROPERTY;
  3172. Restriction.res.resProperty=PropertyRestriction;
  3173. if (0 != (hResult = lpWabContainer->lpVtbl->GetContentsTable(lpWabContainer,
  3174. MAPI_DEFERRED_ERRORS, &lpMapiTable))) {
  3175. goto error;
  3176. }
  3177. if (0 != (hResult = lpMapiTable->lpVtbl->FindRow(lpMapiTable, &Restriction, bkmark, 0))) {
  3178. goto error;
  3179. }
  3180. if (0 != (hResult = lpMapiTable->lpVtbl->SetColumns(lpMapiTable,
  3181. (LPSPropTagArray)&ptaEid, 0))) {
  3182. goto error;
  3183. }
  3184. if (0 != (hResult = lpMapiTable->lpVtbl->QueryRows(lpMapiTable, 1, 0, &lpsrowset))) {
  3185. goto error;
  3186. }
  3187. if (! (lpsbinary[ucount].lpb = (LPBYTE)LocalAlloc(LMEM_FIXED,
  3188. lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb))) {
  3189. hResult = hrMemory;
  3190. goto error;
  3191. }
  3192. CopyMemory(lpsbinary[ucount].lpb, lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb,
  3193. lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb);
  3194. lpsbinary[ucount].cb = lpsrowset->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb;
  3195. error:
  3196. if (lpsrowset) {
  3197. FreeRowSet(lpsrowset);
  3198. }
  3199. if (lpMapiTable) {
  3200. lpMapiTable->lpVtbl->Release(lpMapiTable);
  3201. lpMapiTable = NULL;
  3202. }
  3203. return(hResult);
  3204. }
  3205. /******************************************************************************
  3206. * FUNCTION NAME:FreeRowSet
  3207. *
  3208. * PURPOSE: To free the srowset structure.
  3209. *
  3210. * RETURNS: none.
  3211. ******************************************************************************/
  3212. void FreeRowSet(LPSRowSet lpRows)
  3213. {
  3214. ULONG cRows;
  3215. if (! lpRows) {
  3216. return;
  3217. }
  3218. for (cRows = 0; cRows < lpRows->cRows; ++cRows) {
  3219. WABFreeBuffer(lpRows->aRow[cRows].lpProps);
  3220. }
  3221. WABFreeBuffer(lpRows);
  3222. }
  3223. /******************************************************************************
  3224. * FUNCTION NAME:SizeLoadStringToGlobalBuffer
  3225. *
  3226. * PURPOSE: Loads a string resource into the globall alloc buffer
  3227. * and returns the size, not the string
  3228. *
  3229. * PARAMETERS: StringID - String identifier to load
  3230. *
  3231. * RETURNS: ULONG number of characters loaded
  3232. *
  3233. * created: Vikramm 02/04/97
  3234. * Bug: 17928 - trash in OpenFileDialog dropdown
  3235. * caused because StrCpyN cant copy strings with
  3236. * \0 in them. Need to do a copy memory
  3237. ******************************************************************************/
  3238. ULONG SizeLoadStringToGlobalBuffer(int StringID)
  3239. {
  3240. ULONG ulSize = 0;
  3241. ulSize = LoadString(hInst, StringID, szGlobalAlloc, sizeof(szGlobalAlloc));
  3242. return(ulSize);
  3243. }
  3244. /******************************************************************************
  3245. * FUNCTION NAME:LoadStringToGlobalBuffer
  3246. *
  3247. * PURPOSE: Loads a string resource
  3248. *
  3249. * PARAMETERS: StringID - String identifier to load
  3250. *
  3251. * RETURNS: LPTSTR, string that is loaded.
  3252. ******************************************************************************/
  3253. LPTSTR LoadStringToGlobalBuffer(int StringID)
  3254. {
  3255. ULONG ulSize = 0;
  3256. ulSize = LoadString(hInst, StringID, szGlobalAlloc, sizeof(szGlobalAlloc));
  3257. return(szGlobalAlloc);
  3258. }
  3259. /******************************************************************************
  3260. * FUNCTION NAME:FillMailUser
  3261. *
  3262. * PURPOSE: To create a mail user in the WAB for NetScape/Eudora .
  3263. *
  3264. * PARAMETERS: hwnd - hwnd of parent
  3265. * lpWabContainer = pointer to the IABCONT interface.
  3266. * sProp = pointer to SPropValue which contains ENTRY_ID.
  3267. * lpOptions = pointer to WAB_IMPORT_OPTIONS structure
  3268. * lpadrbook = pointer to NSADRBOOK/EUDADRBOOK typecasted to void*
  3269. * lpsbinary = pointer to an array of SBinary structure.
  3270. * type = containing the value indicating whether it is a EUDORA or
  3271. * NETSCAPE.
  3272. * ul = offset for Eudora in EUDADRBOOK array.
  3273. *
  3274. * RETURNS: HRESULT
  3275. ******************************************************************************/
  3276. HRESULT FillMailUser(HWND hwnd, LPABCONT lpWabContainer, LPSPropValue sProp,
  3277. LPWAB_IMPORT_OPTIONS lpOptions, void *lpadrbook, LPSBinary lpsbinary, ULONG ul, int type)
  3278. {
  3279. ULONG ulCreateFlags = CREATE_CHECK_DUP_STRICT;
  3280. ULONG iCreateTemplate = iconPR_DEF_CREATE_MAILUSER;
  3281. LPSPropValue lpNewDLProps = NULL;
  3282. LPMAPIPROP lpMailUserWAB = NULL;
  3283. ULONG cProps;
  3284. HRESULT hResult;
  3285. REPLACE_INFO RI;
  3286. SPropValue rgProps[5];
  3287. LPEUDADRBOOK lpEudAdrBook = NULL;
  3288. LPNSADRBOOK lpNsAdrBook = NULL;
  3289. if (NETSCAPE == type) {
  3290. lpNsAdrBook = (LPNSADRBOOK)lpadrbook;
  3291. } else {
  3292. lpEudAdrBook = (LPEUDADRBOOK)lpadrbook;
  3293. }
  3294. retry:
  3295. if (EUDORA == type) {
  3296. if (lpsbinary[ul].lpb != NULL) {
  3297. return(S_OK);
  3298. }
  3299. }
  3300. hResult = lpWabContainer->lpVtbl->CreateEntry(lpWabContainer,
  3301. sProp[iCreateTemplate].Value.bin.cb,
  3302. (LPENTRYID)sProp[iCreateTemplate].Value.bin.lpb,
  3303. ulCreateFlags,
  3304. &lpMailUserWAB);
  3305. if (FAILED(hResult)) {
  3306. goto Error;
  3307. }
  3308. if (NETSCAPE == type) {
  3309. FillWABStruct(rgProps,lpNsAdrBook);
  3310. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 5,
  3311. rgProps, NULL)))
  3312. goto Error;
  3313. } else {
  3314. FillEudWABStruct(rgProps,&lpEudAdrBook[ul]);
  3315. if (0 != (hResult = lpMailUserWAB->lpVtbl->SetProps(lpMailUserWAB, 4,
  3316. rgProps, NULL)))
  3317. goto Error;
  3318. }
  3319. hResult = lpMailUserWAB->lpVtbl->SaveChanges(lpMailUserWAB,
  3320. KEEP_OPEN_READONLY | FORCE_SAVE);
  3321. if (GetScode(hResult) == MAPI_E_COLLISION) {
  3322. if (lpOptions->ReplaceOption == WAB_REPLACE_ALWAYS) {
  3323. if (lpMailUserWAB) {
  3324. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  3325. }
  3326. lpMailUserWAB = NULL;
  3327. ulCreateFlags |= CREATE_REPLACE;
  3328. goto retry;
  3329. }
  3330. if (lpOptions->ReplaceOption == WAB_REPLACE_NEVER) {
  3331. hResult = S_OK;
  3332. goto Error;
  3333. }
  3334. if (lpOptions->ReplaceOption == WAB_REPLACE_PROMPT) {
  3335. RI.lpszEmailAddress = NULL;
  3336. if (NETSCAPE == type) {
  3337. if (lpNsAdrBook->Entry) {
  3338. RI.lpszDisplayName = lpNsAdrBook->Entry;
  3339. RI.lpszEmailAddress = lpNsAdrBook->Address;
  3340. } else if (lpNsAdrBook->NickName) {
  3341. RI.lpszDisplayName = lpNsAdrBook->NickName;
  3342. RI.lpszEmailAddress = lpNsAdrBook->Address;
  3343. } else if (lpNsAdrBook->Address) {
  3344. RI.lpszDisplayName = lpNsAdrBook->Address;
  3345. } else if (lpNsAdrBook->Description) {
  3346. RI.lpszDisplayName = lpNsAdrBook->Description;
  3347. } else {
  3348. RI.lpszDisplayName = "";
  3349. }
  3350. } else {
  3351. RI.lpszDisplayName = lpEudAdrBook[ul].NickName;
  3352. RI.lpszEmailAddress = lpEudAdrBook[ul].Address;
  3353. }
  3354. RI.ConfirmResult = CONFIRM_ERROR;
  3355. RI.lpImportOptions = lpOptions;
  3356. DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_ImportReplace), hwnd,
  3357. ReplaceDialogProc, (LPARAM)&RI);
  3358. switch (RI.ConfirmResult) {
  3359. case CONFIRM_YES:
  3360. case CONFIRM_YES_TO_ALL:
  3361. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  3362. lpMailUserWAB = NULL;
  3363. ulCreateFlags |= CREATE_REPLACE;
  3364. goto retry;
  3365. break;
  3366. case CONFIRM_ABORT:
  3367. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  3368. goto Error;
  3369. case CONFIRM_NO:
  3370. if (NETSCAPE == type) {
  3371. if (lpNsAdrBook->Sbinary == TRUE)
  3372. GetExistEntry(lpWabContainer,
  3373. lpsbinary,
  3374. lpNsAdrBook->AliasID,
  3375. lpNsAdrBook->Entry,
  3376. lpNsAdrBook->NickName);
  3377. } else
  3378. hResult = GetExistEntry(lpWabContainer,lpsbinary,ul,
  3379. lpEudAdrBook[ul].NickName,
  3380. NULL);
  3381. goto Error;
  3382. default:
  3383. break;
  3384. }
  3385. }
  3386. }
  3387. if (0 != (hResult = lpMailUserWAB->lpVtbl->GetProps(lpMailUserWAB,
  3388. (LPSPropTagArray)&ptaEid,
  3389. 0,
  3390. &cProps,
  3391. (LPSPropValue *)&lpNewDLProps))) {
  3392. if (hResult == MAPI_W_ERRORS_RETURNED) {
  3393. WABFreeBuffer(lpNewDLProps);
  3394. lpNewDLProps = NULL;
  3395. }
  3396. goto Error;
  3397. }
  3398. if (NETSCAPE == type) {
  3399. if (lpNsAdrBook->Sbinary == TRUE) {
  3400. lpsbinary[lpNsAdrBook->AliasID].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  3401. if (!lpsbinary[lpNsAdrBook->AliasID].lpb) {
  3402. hResult = hrMemory;
  3403. goto Error;
  3404. }
  3405. CopyMemory(lpsbinary[lpNsAdrBook->AliasID].lpb,
  3406. (LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  3407. lpsbinary[lpNsAdrBook->AliasID].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
  3408. }
  3409. } else {
  3410. lpsbinary[ul].lpb=(LPBYTE)LocalAlloc(LMEM_FIXED,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  3411. if (!lpsbinary[ul].lpb) {
  3412. hResult = hrMemory;
  3413. goto Error;
  3414. }
  3415. CopyMemory(lpsbinary[ul].lpb,(LPENTRYID)lpNewDLProps[ieidPR_ENTRYID].Value.bin.lpb,lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb);
  3416. lpsbinary[ul].cb=lpNewDLProps[ieidPR_ENTRYID].Value.bin.cb;
  3417. }
  3418. Error:
  3419. if (lpNewDLProps) {
  3420. WABFreeBuffer(lpNewDLProps);
  3421. lpNewDLProps = NULL;
  3422. }
  3423. if (lpMailUserWAB) {
  3424. lpMailUserWAB->lpVtbl->Release(lpMailUserWAB);
  3425. lpMailUserWAB = NULL;
  3426. }
  3427. return(hResult);
  3428. }
  3429. /******************************************************************************
  3430. * FUNCTION NAME:ComDlg32DlgProc
  3431. *
  3432. * PURPOSE: Change the title of open button to Import.
  3433. *
  3434. * PARAMETERS:
  3435. *
  3436. * RETURNS: BOOL
  3437. ******************************************************************************/
  3438. INT_PTR CALLBACK ComDlg32DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  3439. {
  3440. switch (uMsg) {
  3441. case WM_INITDIALOG:
  3442. {
  3443. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  3444. if (LoadString(hInst, IDS_IMPORT_BUTTON, szBuffer, sizeof(szBuffer))) {
  3445. SetDlgItemText(GetParent(hDlg), 1, szBuffer);
  3446. }
  3447. break;
  3448. }
  3449. default:
  3450. return(FALSE);
  3451. }
  3452. return(TRUE);
  3453. }
  3454. const static char c_szReg[] = "Reg";
  3455. const static char c_szUnReg[] = "UnReg";
  3456. const static char c_szAdvPackDll[] = "ADVPACK.DLL";
  3457. static char c_szWABIMP[] = "WABIMP";
  3458. HRESULT CallRegInstall(LPCSTR szSection)
  3459. {
  3460. HRESULT hr;
  3461. HINSTANCE hAdvPack;
  3462. REGINSTALL pfnri;
  3463. char szWabimpDll[MAX_PATH];
  3464. STRENTRY seReg;
  3465. STRTABLE stReg;
  3466. hr = E_FAIL;
  3467. hAdvPack = LoadLibraryA(c_szAdvPackDll);
  3468. if (hAdvPack != NULL) {
  3469. // Get Proc Address for registration util
  3470. pfnri = (REGINSTALL)GetProcAddress(hAdvPack, achREGINSTALL);
  3471. if (pfnri != NULL) {
  3472. GetModuleFileName(hInstApp, szWabimpDll, sizeof(szWabimpDll));
  3473. seReg.pszName = c_szWABIMP;
  3474. seReg.pszValue = szWabimpDll;
  3475. stReg.cEntries = 1;
  3476. stReg.pse = &seReg;
  3477. // Call the self-reg routine
  3478. hr = pfnri(hInstApp, szSection, &stReg);
  3479. }
  3480. FreeLibrary(hAdvPack);
  3481. }
  3482. return(hr);
  3483. }
  3484. STDAPI DllRegisterServer(void)
  3485. {
  3486. return(CallRegInstall(c_szReg));
  3487. }
  3488. STDAPI DllUnregisterServer(void)
  3489. {
  3490. return(CallRegInstall(c_szUnReg));
  3491. }
  3492. /***************************************************************************
  3493. Name : ShowMessageBoxParam
  3494. Purpose : Generic MessageBox displayer
  3495. Parameters: hWndParent - Handle of message box parent
  3496. MsgID - resource id of message string
  3497. ulFlags - MessageBox flags
  3498. ... - format parameters
  3499. Returns : MessageBox return code
  3500. ***************************************************************************/
  3501. int __cdecl ShowMessageBoxParam(HWND hWndParent, int MsgId, int ulFlags, ...)
  3502. {
  3503. TCHAR szBuf[MAX_RESOURCE_STRING + 1] = "";
  3504. TCHAR szCaption[MAX_PATH] = "";
  3505. LPTSTR lpszBuffer = NULL;
  3506. int iRet = 0;
  3507. va_list vl;
  3508. va_start(vl, ulFlags);
  3509. LoadString(hInst, MsgId, szBuf, sizeof(szBuf));
  3510. if (FormatMessage(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER,
  3511. szBuf,
  3512. 0,0, // ignored
  3513. (LPTSTR)&lpszBuffer,
  3514. sizeof(szBuf), // MAX_UI_STR
  3515. (va_list *)&vl)) {
  3516. TCHAR szCaption[MAX_PATH];
  3517. GetWindowText(hWndParent, szCaption, sizeof(szCaption));
  3518. if (! lstrlen(szCaption)) { // if no caption get the parents caption - this is necessary for property sheets
  3519. GetWindowText(GetParent(hWndParent), szCaption, sizeof(szCaption));
  3520. if (! lstrlen(szCaption)) //if still not caption, use empty title
  3521. szCaption[0] = (TCHAR)'\0';
  3522. }
  3523. iRet = MessageBox(hWndParent, lpszBuffer, szCaption, ulFlags);
  3524. LocalFree(lpszBuffer);
  3525. }
  3526. va_end(vl);
  3527. return(iRet);
  3528. }
  3529. //$$//////////////////////////////////////////////////////////////////////
  3530. //
  3531. // LoadAllocString - Loads a string resource and allocates enough
  3532. // memory to hold it.
  3533. //
  3534. // StringID - String identifier to load
  3535. //
  3536. // returns the LocalAlloc'd, null terminated string. Caller is responsible
  3537. // for LocalFree'ing this buffer. If the string can't be loaded or memory
  3538. // can't be allocated, returns NULL.
  3539. //
  3540. //////////////////////////////////////////////////////////////////////////
  3541. LPTSTR LoadAllocString(int StringID) {
  3542. ULONG ulSize = 0;
  3543. LPTSTR lpBuffer = NULL;
  3544. TCHAR szBuffer[MAX_RESOURCE_STRING + 1];
  3545. ulSize = LoadString(hInst, StringID, szBuffer, sizeof(szBuffer));
  3546. if (ulSize && (lpBuffer = LocalAlloc(LPTR, ulSize + 1))) {
  3547. StrCpyN(lpBuffer, szBuffer, ulSize + 1);
  3548. }
  3549. return(lpBuffer);
  3550. }
  3551. /***************************************************************************
  3552. Name : FormatAllocFilter
  3553. Purpose : Loads file filter name string resources and
  3554. formats them with their file extension filters
  3555. Parameters: StringID1 - String identifier to load (required)
  3556. szFilter1 - file name filter, ie, "*.vcf" (required)
  3557. StringID2 - String identifier (optional)
  3558. szFilter2 - file name filter (optional)
  3559. StringID3 - String identifier (optional)
  3560. szFilter3 - file name filter (optional)
  3561. Returns : LocalAlloc'd, Double null terminated string. Caller is
  3562. responsible for LocalFree'ing this buffer. If the string
  3563. can't be loaded or memory can't be allocated, returns NULL.
  3564. ***************************************************************************/
  3565. LPTSTR FormatAllocFilter(int StringID1, LPCTSTR lpFilter1,
  3566. int StringID2, LPCTSTR lpFilter2,
  3567. int StringID3, LPCTSTR lpFilter3) {
  3568. LPTSTR lpFileType1 = NULL, lpFileType2 = NULL, lpFileType3 = NULL;
  3569. LPTSTR lpTemp;
  3570. LPTSTR lpBuffer = NULL;
  3571. // All string sizes include null
  3572. ULONG cbFileType1 = 0, cbFileType2 = 0, cbFileType3 = 0;
  3573. ULONG cbFilter1 = 0, cbFilter2 = 0, cbFilter3 = 0;
  3574. ULONG cbBuffer;
  3575. cbBuffer = cbFilter1 = lstrlen(lpFilter1) + 1;
  3576. if (! (lpFileType1 = LoadAllocString(StringID1))) {
  3577. DebugTrace("LoadAllocString(%u) failed\n", StringID1);
  3578. return(NULL);
  3579. }
  3580. cbBuffer += (cbFileType1 = lstrlen(lpFileType1) + 1);
  3581. if (lpFilter2 && StringID2) {
  3582. cbBuffer += (cbFilter2 = lstrlen(lpFilter2) + 1);
  3583. if (! (lpFileType2 = LoadAllocString(StringID2))) {
  3584. DebugTrace("LoadAllocString(%u) failed\n", StringID2);
  3585. } else {
  3586. cbBuffer += (cbFileType2 = lstrlen(lpFileType2) + 1);
  3587. }
  3588. }
  3589. if (lpFilter3 && StringID3) {
  3590. cbBuffer += (cbFilter3 = lstrlen(lpFilter3) + 1);
  3591. if (! (lpFileType3 = LoadAllocString(StringID3))) {
  3592. DebugTrace("LoadAllocString(%u) failed\n", StringID3);
  3593. } else {
  3594. cbBuffer += (cbFileType3 = lstrlen(lpFileType3) + 1);
  3595. }
  3596. }
  3597. cbBuffer++;
  3598. Assert(cbBuffer == cbFilter1 + cbFilter2 + cbFilter3 + cbFileType1 + cbFileType2 + cbFileType3 + 1);
  3599. if (lpBuffer = LocalAlloc(LPTR, cbBuffer * sizeof(TCHAR))) {
  3600. lpTemp = lpBuffer;
  3601. StrCpyN(lpTemp, lpFileType1, cbBuffer);
  3602. lpTemp += cbFileType1;
  3603. cbBuffer -= cbFileType1;
  3604. StrCpyN(lpTemp, lpFilter1, cbBuffer);
  3605. lpTemp += cbFilter1;
  3606. cbBuffer -= cbFilter1;
  3607. LocalFree(lpFileType1);
  3608. if (cbFileType2 && cbFilter2) {
  3609. StrCpyN(lpTemp, lpFileType2, cbBuffer);
  3610. lpTemp += cbFileType2;
  3611. cbBuffer -= cbFileType2;
  3612. StrCpyN(lpTemp, lpFilter2, cbBuffer);
  3613. lpTemp += cbFilter2;
  3614. cbBuffer -= cbFilter2;
  3615. LocalFree(lpFileType2);
  3616. }
  3617. if (cbFileType3 && cbFilter3) {
  3618. StrCpyN(lpTemp, lpFileType3, cbBuffer);
  3619. lpTemp += cbFileType3;
  3620. cbBuffer -= cbFileType3;
  3621. StrCpyN(lpTemp, lpFilter3, cbBuffer);
  3622. lpTemp += cbFilter3;
  3623. cbBuffer -= cbFilter3;
  3624. LocalFree(lpFileType3);
  3625. }
  3626. *lpTemp = '\0';
  3627. }
  3628. return(lpBuffer);
  3629. }
  3630. /***************************************************************************
  3631. Name : SaveFileDialog
  3632. Purpose : Presents a Save filename dialog
  3633. Parameters: hWnd = parent window handle
  3634. szFileName = in/out filename buffer (must be MAX_PATH + 1)
  3635. lpFilter1 = First filename filter string
  3636. idsFileType1 = First filename type string id
  3637. lpFilter2 = Second filename filter string (or NULL)
  3638. idsFileType2 = Second filename type string id
  3639. lpFilter3 = Third filename filter string (or NULL)
  3640. idsFileType3 = Third filename type string id
  3641. lpDefExt = default extension string
  3642. ulFlags = GetSaveFileName flags
  3643. hInst = instance handle
  3644. idsTitle = dialog title string id
  3645. idsSaveButton = Save button string id (0 = default)
  3646. Returns : HRESULT
  3647. ***************************************************************************/
  3648. HRESULT SaveFileDialog(HWND hWnd,
  3649. LPTSTR szFileName,
  3650. LPCTSTR lpFilter1,
  3651. ULONG idsFileType1,
  3652. LPCTSTR lpFilter2,
  3653. ULONG idsFileType2,
  3654. LPCTSTR lpFilter3,
  3655. ULONG idsFileType3,
  3656. LPCTSTR lpDefExt,
  3657. ULONG ulFlags,
  3658. HINSTANCE hInst,
  3659. ULONG idsTitle,
  3660. ULONG idsSaveButton) {
  3661. LPTSTR lpFilterName;
  3662. OPENFILENAME ofn;
  3663. HRESULT hResult = hrSuccess;
  3664. if (! (lpFilterName = FormatAllocFilter(idsFileType1, lpFilter1,
  3665. idsFileType2, lpFilter2, idsFileType3, lpFilter3))) {
  3666. return(ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY));
  3667. }
  3668. ofn.lStructSize = sizeof(ofn);
  3669. ofn.hwndOwner = hWnd;
  3670. ofn.hInstance = hInst;
  3671. ofn.lpstrFilter = lpFilterName;
  3672. ofn.lpstrCustomFilter = NULL;
  3673. ofn.nMaxCustFilter = 0;
  3674. ofn.nFilterIndex = 0;
  3675. ofn.lpstrFile = szFileName;
  3676. ofn.nMaxFile = MAX_PATH;
  3677. ofn.lpstrFileTitle = NULL;
  3678. ofn.nMaxFileTitle = 0;
  3679. ofn.lpstrInitialDir = NULL;
  3680. ofn.lpstrTitle = NULL; // lpTitle;
  3681. ofn.Flags = ulFlags;
  3682. ofn.nFileOffset = 0;
  3683. ofn.nFileExtension = 0;
  3684. ofn.lpstrDefExt = lpDefExt;
  3685. ofn.lCustData = 0;
  3686. ofn.lpfnHook = NULL;
  3687. ofn.lpTemplateName = NULL;
  3688. if (! GetSaveFileName(&ofn)) {
  3689. DebugTrace("GetSaveFileName cancelled\n");
  3690. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  3691. }
  3692. if(lpFilterName)
  3693. LocalFree(lpFilterName);
  3694. return(hResult);
  3695. }
  3696. /***************************************************************************
  3697. Name : OpenFileDialog
  3698. Purpose : Presents a open filename dialog
  3699. Parameters: hWnd = parent window handle
  3700. szFileName = in/out filename buffer (must be MAX_PATH + 1)
  3701. lpFilter1 = First filename filter string
  3702. idsFileType1 = First filename type string id
  3703. lpFilter2 = Second filename filter string (or NULL)
  3704. idsFileType2 = Second filename type string id
  3705. lpFilter3 = Third filename filter string (or NULL)
  3706. idsFileType3 = Third filename type string id
  3707. lpDefExt = default extension string
  3708. ulFlags = GetOpenFileName flags
  3709. hInst = instance handle
  3710. idsTitle = dialog title string id
  3711. idsSaveButton = Save button string id (0 = default)
  3712. Returns : HRESULT
  3713. ***************************************************************************/
  3714. HRESULT OpenFileDialog(HWND hWnd,
  3715. LPTSTR szFileName,
  3716. LPCTSTR lpFilter1,
  3717. ULONG idsFileType1,
  3718. LPCTSTR lpFilter2,
  3719. ULONG idsFileType2,
  3720. LPCTSTR lpFilter3,
  3721. ULONG idsFileType3,
  3722. LPCTSTR lpDefExt,
  3723. ULONG ulFlags,
  3724. HINSTANCE hInst,
  3725. ULONG idsTitle,
  3726. ULONG idsOpenButton) {
  3727. LPTSTR lpFilterName;
  3728. OPENFILENAME ofn;
  3729. HRESULT hResult = hrSuccess;
  3730. if (! (lpFilterName = FormatAllocFilter(idsFileType1, lpFilter1,
  3731. idsFileType2, lpFilter2, idsFileType3, lpFilter3))) {
  3732. return(ResultFromScode(MAPI_E_NOT_ENOUGH_MEMORY));
  3733. }
  3734. ofn.lStructSize = sizeof(ofn);
  3735. ofn.hwndOwner = hWnd;
  3736. ofn.hInstance = hInst;
  3737. ofn.lpstrFilter = lpFilterName;
  3738. ofn.lpstrCustomFilter = NULL;
  3739. ofn.nMaxCustFilter = 0;
  3740. ofn.nFilterIndex = 0;
  3741. ofn.lpstrFile = szFileName;
  3742. ofn.nMaxFile = MAX_PATH;
  3743. ofn.lpstrFileTitle = NULL;
  3744. ofn.nMaxFileTitle = 0;
  3745. ofn.lpstrInitialDir = NULL;
  3746. ofn.lpstrTitle = NULL; // lpTitle;
  3747. ofn.Flags = ulFlags;
  3748. ofn.nFileOffset = 0;
  3749. ofn.nFileExtension = 0;
  3750. ofn.lpstrDefExt = lpDefExt;
  3751. ofn.lCustData = 0;
  3752. ofn.lpfnHook = NULL;
  3753. ofn.lpTemplateName = NULL;
  3754. if (! GetOpenFileName(&ofn)) {
  3755. DebugTrace("GetOpenFileName cancelled\n");
  3756. hResult = ResultFromScode(MAPI_E_USER_CANCEL);
  3757. }
  3758. if(lpFilterName)
  3759. LocalFree(lpFilterName);
  3760. return(hResult);
  3761. }
  3762. /***************************************************************************
  3763. Name : CountRows
  3764. Purpose : Count the rows in a table (restriction aware)
  3765. Parameters: lpTable = table object
  3766. fMAPI = TRUE if MAPI table, FALSE if WAB table
  3767. Returns : returns number of rows in the restricted table
  3768. Comment : Leaves the table pointer at the beginning.
  3769. I'd use GetRowCount, but it is not aware of restrictions.
  3770. ***************************************************************************/
  3771. #define COUNT_BATCH 50
  3772. ULONG CountRows(LPMAPITABLE lpTable, BOOL fMAPI) {
  3773. ULONG cRows;
  3774. ULONG cTotal = 0;
  3775. HRESULT hResult;
  3776. LPSRowSet lpRow = NULL;
  3777. #ifdef DEBUG
  3778. DWORD dwTickCount = GetTickCount();
  3779. DebugTrace(">>>>> Counting Table Rows...\n");
  3780. #endif // DEBUG
  3781. cRows = 1;
  3782. while (cRows) {
  3783. if (hResult = lpTable->lpVtbl->QueryRows(lpTable,
  3784. COUNT_BATCH, // 50 row's at a time
  3785. 0, // ulFlags
  3786. &lpRow)) {
  3787. DebugTrace("CountRows:QueryRows -> %x\n", GetScode(hResult));
  3788. break;
  3789. }
  3790. if (lpRow) {
  3791. if (cRows = lpRow->cRows) { // yes, single '='
  3792. cTotal += cRows;
  3793. } // else, drop out of loop, we're done.
  3794. if (fMAPI) {
  3795. FreeProws(lpRow);
  3796. } else {
  3797. WABFreeProws(lpRow);
  3798. }
  3799. lpRow = NULL;
  3800. } else {
  3801. cRows = 0; // done
  3802. }
  3803. }
  3804. if (HR_FAILED(hResult = lpTable->lpVtbl->SeekRow(lpTable,
  3805. BOOKMARK_BEGINNING,
  3806. 0,
  3807. NULL))) {
  3808. DebugTrace("CountRows:SeekRow -> %x\n", GetScode(hResult));
  3809. }
  3810. #ifdef DEBUG
  3811. DebugTrace(">>>>> Done Counting Table Rows... %u milliseconds\n", GetTickCount() - dwTickCount);
  3812. #endif
  3813. return(cTotal);
  3814. }
  3815. /***************************************************************************
  3816. Name : WABFreePadrlist
  3817. Purpose : Free an adrlist and it's property arrays
  3818. Parameters: lpBuffer = buffer to free
  3819. Returns : SCODE
  3820. Comment :
  3821. ***************************************************************************/
  3822. void WABFreePadrlist(LPADRLIST lpAdrList) {
  3823. ULONG iEntry;
  3824. if (lpAdrList) {
  3825. for (iEntry = 0; iEntry < lpAdrList->cEntries; ++iEntry) {
  3826. if (lpAdrList->aEntries[iEntry].rgPropVals) {
  3827. WABFreeBuffer(lpAdrList->aEntries[iEntry].rgPropVals);
  3828. }
  3829. }
  3830. WABFreeBuffer(lpAdrList);
  3831. }
  3832. }
  3833. /***************************************************************************
  3834. Name : WABFreeProws
  3835. Purpose : Destroys an SRowSet structure.
  3836. Parameters: prows -> SRowSet to free
  3837. Returns : none
  3838. Comment :
  3839. ***************************************************************************/
  3840. void WABFreeProws(LPSRowSet prows) {
  3841. register ULONG irow;
  3842. if (! prows) {
  3843. return;
  3844. }
  3845. for (irow = 0; irow < prows->cRows; ++irow) {
  3846. WABFreeBuffer(prows->aRow[irow].lpProps);
  3847. }
  3848. WABFreeBuffer(prows);
  3849. }
  3850. /***************************************************************************
  3851. Name : FindAdrEntryID
  3852. Purpose : Find the PR_ENTRYID in the Nth ADRENTRY of an ADRLIST
  3853. Parameters: lpAdrList -> AdrList
  3854. index = which ADRENTRY to look at
  3855. Returns : return pointer to the SBinary structure of the ENTRYID value
  3856. Comment :
  3857. ***************************************************************************/
  3858. LPSBinary FindAdrEntryID(LPADRLIST lpAdrList, ULONG index) {
  3859. LPADRENTRY lpAdrEntry;
  3860. ULONG i;
  3861. if (lpAdrList && index < lpAdrList->cEntries) {
  3862. lpAdrEntry = &(lpAdrList->aEntries[index]);
  3863. for (i = 0; i < lpAdrEntry->cValues; i++) {
  3864. if (lpAdrEntry->rgPropVals[i].ulPropTag == PR_ENTRYID) {
  3865. return((LPSBinary)&lpAdrEntry->rgPropVals[i].Value);
  3866. }
  3867. }
  3868. }
  3869. return(NULL);
  3870. }
  3871. /***************************************************************************
  3872. Name : FindProperty
  3873. Purpose : Finds a property in a proparray
  3874. Parameters: cProps = number of props in the array
  3875. lpProps = proparray
  3876. ulPropTag = property tag to look for
  3877. Returns : array index of property or NOT_FOUND
  3878. Comment :
  3879. ***************************************************************************/
  3880. ULONG FindProperty(ULONG cProps, LPSPropValue lpProps, ULONG ulPropTag) {
  3881. register ULONG i;
  3882. for (i = 0; i < cProps; i++) {
  3883. if (lpProps[i].ulPropTag == ulPropTag) {
  3884. return(i);
  3885. }
  3886. }
  3887. return(NOT_FOUND);
  3888. }
  3889. /***************************************************************************
  3890. Name : FindStringInProps
  3891. Purpose : Find the string property in the property value array
  3892. Parameters: lpspv -> property value array
  3893. ulcProps = size of array
  3894. ulPropTag
  3895. Returns : return pointer to the string pointer in the array. If
  3896. the property doesn't exist or has error value, return NULL.
  3897. Comment :
  3898. ***************************************************************************/
  3899. LPTSTR FindStringInProps(LPSPropValue lpspv, ULONG ulcProps, ULONG ulPropTag) {
  3900. ULONG i;
  3901. if (lpspv) {
  3902. for (i = 0; i < ulcProps; i++) {
  3903. if (lpspv[i].ulPropTag == ulPropTag) {
  3904. return(lpspv[i].Value.LPSZ);
  3905. }
  3906. }
  3907. }
  3908. return(NULL);
  3909. }
  3910. /***************************************************************************
  3911. Name : PropStringOrNULL
  3912. Purpose : Returns the value of a property or NULL if it is an error
  3913. Parameters: lpspv -> property value to check and return
  3914. Returns : pointer to value string or NULL
  3915. ***************************************************************************/
  3916. LPTSTR PropStringOrNULL(LPSPropValue lpspv) {
  3917. return(PROP_ERROR((*lpspv)) ? NULL : lpspv->Value.LPSZ);
  3918. }
  3919. /***************************************************************************
  3920. Name : FreeSeenList
  3921. Purpose : Frees the SeenList
  3922. Parameters: none
  3923. Returns : none
  3924. Comment :
  3925. ***************************************************************************/
  3926. void FreeSeenList(void) {
  3927. ULONG i;
  3928. Assert((lpEntriesSeen && ulEntriesSeen) || (! lpEntriesSeen && ! ulEntriesSeen));
  3929. for (i = 0; i < ulEntriesSeen; i++) {
  3930. if (lpEntriesSeen[i].sbinPAB.lpb) {
  3931. LocalFree(lpEntriesSeen[i].sbinPAB.lpb);
  3932. }
  3933. if (lpEntriesSeen[i].sbinWAB.lpb) {
  3934. LocalFree(lpEntriesSeen[i].sbinWAB.lpb);
  3935. }
  3936. }
  3937. if (lpEntriesSeen) {
  3938. LocalFree(lpEntriesSeen);
  3939. }
  3940. lpEntriesSeen = NULL;
  3941. ulEntriesSeen = 0;
  3942. ulMaxEntries = 0;
  3943. }
  3944. /***************************************************************************
  3945. Name : GetEMSSMTPAddress
  3946. Purpose : Get the Exchange SMTP address for this object
  3947. Parameters: lpObject -> Object
  3948. Returns : lpSMTP -> returned buffer containing SMTP address (must be MAPIFree'd
  3949. by caller.)
  3950. lpBase = base allocation to alloc more onto
  3951. Comment : What a mess! EMS changed their name id's and guids between 4.0 and 4.5.
  3952. They also added a fixed ID property containing just the SMTP address in 4.5.
  3953. ***************************************************************************/
  3954. const GUID guidEMS_AB_40 = { // GUID for EMS 4.0 addresses
  3955. 0x48862a09,
  3956. 0xf786,
  3957. 0x0114,
  3958. {0x02, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  3959. };
  3960. const GUID guidEMS_AB_45 = { // GUID for EMS 4.5 addresses
  3961. 0x48862a08,
  3962. 0xf786,
  3963. 0x0114,
  3964. {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
  3965. };
  3966. #define ID_EMS_AB_PROXY_ADDRESSES_40 0x10052
  3967. #define ID_EMS_AB_PROXY_ADDRESSES_45 0x25281
  3968. // New MAPI property, found on EX 4.5 and later
  3969. #define PR_PRIMARY_SMTP_ADDRESS PROP_TAG(PT_TSTRING, 0x39FE)
  3970. LPTSTR GetEMSSMTPAddress(LPMAPIPROP lpObject, LPVOID lpBase) {
  3971. ULONG ulPropTag40 = 0, ulPropTag45 = 0;
  3972. MAPINAMEID mnidT[2];
  3973. LPMAPINAMEID lpmnid = (LPMAPINAMEID)&mnidT;
  3974. LPSPropTagArray lptaga = NULL;
  3975. HRESULT hResult;
  3976. LPTSTR lpSMTP = NULL, lpAddr;
  3977. LPSPropValue lpspv = NULL;
  3978. ULONG i, i40 = 0, i45 = 0;
  3979. SLPSTRArray MVString;
  3980. SizedSPropTagArray(3, spta);
  3981. ULONG cValues;
  3982. SCODE sc;
  3983. #ifdef TEST_STUFF
  3984. MAPIDebugNamedProps(lpObject, "Exchange Address");
  3985. #endif
  3986. mnidT[0].lpguid = (LPGUID)&guidEMS_AB_40;
  3987. mnidT[0].ulKind = MNID_ID;
  3988. mnidT[0].Kind.lID = ID_EMS_AB_PROXY_ADDRESSES_40;
  3989. if (HR_FAILED(hResult = lpObject->lpVtbl->GetIDsFromNames(lpObject,
  3990. 1, // Just one name
  3991. &lpmnid, // &-of because this is an array
  3992. 0, // This is where MAPI_CREATE might go
  3993. &lptaga))) {
  3994. DebugTrace("GetEMSNamedPropTag:GetIDsFromNames -> %x", GetScode(hResult));
  3995. }
  3996. if (lptaga) {
  3997. if (lptaga->cValues >= 1 && (PROP_TYPE(lptaga->aulPropTag[0]) != PT_ERROR)) {
  3998. ulPropTag40 = lptaga->aulPropTag[0];
  3999. }
  4000. MAPIFreeBuffer(lptaga);
  4001. }
  4002. // Yes, I should be doing them both at once, but the PAB fails if you call
  4003. // GetIDsFromNames with ulCount > 1!
  4004. mnidT[0].lpguid = (LPGUID)&guidEMS_AB_45;
  4005. mnidT[0].ulKind = MNID_ID;
  4006. mnidT[0].Kind.lID = ID_EMS_AB_PROXY_ADDRESSES_45;
  4007. if (HR_FAILED(hResult = lpObject->lpVtbl->GetIDsFromNames(lpObject,
  4008. 1, // Just one name
  4009. &lpmnid, // &-of because this is an array
  4010. 0, // This is where MAPI_CREATE might go
  4011. &lptaga))) {
  4012. DebugTrace("GetEMSNamedPropTag:GetIDsFromNames -> %x", GetScode(hResult));
  4013. }
  4014. if (lptaga) {
  4015. if (lptaga->cValues >= 1 && (PROP_TYPE(lptaga->aulPropTag[0]) != PT_ERROR)) {
  4016. ulPropTag45 = lptaga->aulPropTag[0];
  4017. }
  4018. MAPIFreeBuffer(lptaga);
  4019. }
  4020. spta.aulPropTag[0] = PR_PRIMARY_SMTP_ADDRESS;
  4021. i = 1;
  4022. if (ulPropTag40) {
  4023. i40 = i++;
  4024. spta.aulPropTag[i40] = CHANGE_PROP_TYPE(ulPropTag40, PT_MV_TSTRING);
  4025. }
  4026. if (ulPropTag45) {
  4027. i45 = i++;
  4028. spta.aulPropTag[i45] = CHANGE_PROP_TYPE(ulPropTag45, PT_MV_TSTRING);
  4029. }
  4030. spta.cValues = i;
  4031. // Now, get the props from the object
  4032. if (! HR_FAILED(hResult = lpObject->lpVtbl->GetProps(lpObject,
  4033. (LPSPropTagArray)&spta, 0, &cValues, &lpspv))) {
  4034. // Found one or more of the properties. Look up the SMTP address.
  4035. if (! PROP_ERROR(lpspv[0])) {
  4036. if (sc = MAPIAllocateMore((lstrlen(lpspv[0].Value.LPSZ) + 1)* sizeof(TCHAR), lpBase, &lpSMTP)) {
  4037. DebugTrace("GetEMSSMTPAddress:MAPIAllocateMore -> %x\n", sc);
  4038. hResult = ResultFromScode(sc);
  4039. goto done;
  4040. }
  4041. StrCpyN(lpSMTP, lpspv[0].Value.LPSZ, lstrlen(lpspv[0].Value.LPSZ) + 1);
  4042. goto done;
  4043. } else if (i40 && ! PROP_ERROR(lpspv[i40])) { // 4.0 version
  4044. MVString = lpspv[i40].Value.MVSZ;
  4045. } else if (i45 && ! PROP_ERROR(lpspv[i45])) { // 4.5 version
  4046. MVString = lpspv[i45].Value.MVSZ;
  4047. } else {
  4048. goto done;
  4049. }
  4050. for (i = 0; i < MVString.cValues; i++) {
  4051. lpAddr = MVString.LPPSZ[i];
  4052. if ((lpAddr[0] == 'S') &&
  4053. (lpAddr[1] == 'M') &&
  4054. (lpAddr[2] == 'T') &&
  4055. (lpAddr[3] == 'P') &&
  4056. (lpAddr[4] == ':')) {
  4057. // This is IT!
  4058. lpAddr += 5; // point to the string
  4059. // Allocate string
  4060. if (FAILED(sc = MAPIAllocateMore((lstrlen(lpAddr) + 1) * sizeof(TCHAR), lpBase, (&lpSMTP)))) {
  4061. DebugTrace("GetEMSSMTPAddress:MAPIAllocateMore -> %x\n", sc);
  4062. hResult = ResultFromScode(sc);
  4063. goto done;
  4064. }
  4065. StrCpyN(lpSMTP, lpAddr, lstrlen(lpAddr) + 1);
  4066. break;
  4067. }
  4068. }
  4069. done:
  4070. if (lpspv) {
  4071. MAPIFreeBuffer(lpspv);
  4072. }
  4073. }
  4074. return(lpSMTP);
  4075. }
  4076. /***************************************************************************
  4077. Name : LoadWABEIDs
  4078. Purpose : Load the WAB's PAB create EIDs
  4079. Parameters: lpAdrBook -> lpAdrBook object
  4080. lppContainer -> returned PAB container, caller must Release
  4081. Returns : HRESULT
  4082. Comment : Allocates global lpCreateEIDsWAB. Caller should WABFreeBuffer.
  4083. ***************************************************************************/
  4084. HRESULT LoadWABEIDs(LPADRBOOK lpAdrBook, LPABCONT * lppContainer) {
  4085. LPENTRYID lpWABEID = NULL;
  4086. ULONG cbWABEID;
  4087. HRESULT hResult;
  4088. ULONG ulObjType;
  4089. ULONG cProps;
  4090. if (hResult = lpAdrBook->lpVtbl->GetPAB(lpAdrBook,
  4091. &cbWABEID,
  4092. &lpWABEID)) {
  4093. DebugTrace("WAB GetPAB -> %x\n", GetScode(hResult));
  4094. goto exit;
  4095. } else {
  4096. if (hResult = lpAdrBook->lpVtbl->OpenEntry(lpAdrBook,
  4097. cbWABEID, // size of EntryID to open
  4098. lpWABEID, // EntryID to open
  4099. NULL, // interface
  4100. 0, // flags
  4101. &ulObjType,
  4102. (LPUNKNOWN *)lppContainer)) {
  4103. DebugTrace("WAB OpenEntry(PAB) -> %x\n", GetScode(hResult));
  4104. goto exit;
  4105. }
  4106. }
  4107. // Get the WAB's creation entryids
  4108. if ((hResult = (*lppContainer)->lpVtbl->GetProps(*lppContainer,
  4109. (LPSPropTagArray)&ptaCon,
  4110. 0,
  4111. &cProps,
  4112. &lpCreateEIDsWAB))) {
  4113. DebugTrace("Can't get container properties for WAB\n");
  4114. // Bad stuff here!
  4115. goto exit;
  4116. }
  4117. // Validate the properites
  4118. if (lpCreateEIDsWAB[iconPR_DEF_CREATE_MAILUSER].ulPropTag != PR_DEF_CREATE_MAILUSER ||
  4119. lpCreateEIDsWAB[iconPR_DEF_CREATE_DL].ulPropTag != PR_DEF_CREATE_DL) {
  4120. DebugTrace("WAB: Container property errors\n");
  4121. goto exit;
  4122. }
  4123. exit:
  4124. if (hResult) {
  4125. if (lpCreateEIDsWAB) {
  4126. WABFreeBuffer(lpCreateEIDsWAB);
  4127. lpCreateEIDsWAB = NULL;
  4128. }
  4129. }
  4130. if (lpWABEID) {
  4131. WABFreeBuffer(lpWABEID); // bad object?
  4132. }
  4133. return(hResult);
  4134. }
  4135. /////////////////////////////////////////////////////////////////////////
  4136. // GetWABDllPath - loads the WAB DLL path from the registry
  4137. // szPath - ptr to buffer
  4138. // cb - sizeof buffer
  4139. //
  4140. void GetWABDllPath(LPTSTR szPath, ULONG cb)
  4141. {
  4142. DWORD dwType = 0;
  4143. HKEY hKey = NULL;
  4144. TCHAR szPathT[MAX_PATH];
  4145. ULONG cbData = sizeof(szPathT);
  4146. if(szPath)
  4147. {
  4148. *szPath = '\0';
  4149. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
  4150. {
  4151. if(ERROR_SUCCESS == RegQueryValueEx( hKey, "", NULL, &dwType, (LPBYTE) szPathT, &cbData))
  4152. {
  4153. if (dwType == REG_EXPAND_SZ)
  4154. cbData = ExpandEnvironmentStrings(szPathT, szPath, cb / sizeof(TCHAR));
  4155. else
  4156. {
  4157. if(GetFileAttributes(szPathT) != 0xFFFFFFFF)
  4158. StrCpyN(szPath, szPathT, cb);
  4159. }
  4160. }
  4161. }
  4162. }
  4163. if(hKey) RegCloseKey(hKey);
  4164. return;
  4165. }
  4166. typedef HINSTANCE (STDAPICALLTYPE *PFNMLLOADLIBARY)(LPCTSTR lpLibFileName, HMODULE hModule, DWORD dwCrossCodePage);
  4167. static const TCHAR c_szShlwapiDll[] = TEXT("shlwapi.dll");
  4168. static const char c_szDllGetVersion[] = "DllGetVersion";
  4169. static const TCHAR c_szWABResourceDLL[] = TEXT("wab32res.dll");
  4170. static const TCHAR c_szWABDLL[] = TEXT("wab32.dll");
  4171. HINSTANCE LoadWABResourceDLL(HINSTANCE hInstWAB32)
  4172. {
  4173. TCHAR szPath[MAX_PATH];
  4174. HINSTANCE hinstShlwapi;
  4175. PFNMLLOADLIBARY pfn;
  4176. DLLGETVERSIONPROC pfnVersion;
  4177. int iEnd;
  4178. DLLVERSIONINFO info;
  4179. HINSTANCE hInst = NULL;
  4180. hinstShlwapi = LoadLibrary(c_szShlwapiDll);
  4181. if (hinstShlwapi != NULL)
  4182. {
  4183. pfnVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstShlwapi, c_szDllGetVersion);
  4184. if (pfnVersion != NULL)
  4185. {
  4186. info.cbSize = sizeof(DLLVERSIONINFO);
  4187. if (SUCCEEDED(pfnVersion(&info)))
  4188. {
  4189. if (info.dwMajorVersion >= 5)
  4190. {
  4191. #ifdef UNICODE
  4192. pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)378);
  4193. #else
  4194. pfn = (PFNMLLOADLIBARY)GetProcAddress(hinstShlwapi, (LPCSTR)377);
  4195. #endif // UNICODE
  4196. if (pfn != NULL)
  4197. hInst = pfn(c_szWABResourceDLL, hInstWAB32, 0);
  4198. }
  4199. }
  4200. }
  4201. FreeLibrary(hinstShlwapi);
  4202. }
  4203. if (NULL == hInst)
  4204. {
  4205. GetWABDllPath(szPath, sizeof(szPath));
  4206. iEnd = lstrlen(szPath);
  4207. if (iEnd > lstrlen(c_szWABDLL))
  4208. {
  4209. iEnd = iEnd - lstrlen(c_szWABDLL);
  4210. StrCpyN(&szPath[iEnd], c_szWABResourceDLL, sizeof(szPath)/sizeof(TCHAR)-iEnd);
  4211. hInst = LoadLibrary(szPath);
  4212. }
  4213. }
  4214. AssertSz(hInst, TEXT("Failed to LoadLibrary Lang Dll"));
  4215. return(hInst);
  4216. }
  4217. /*
  4218. * DLL entry point for Win32
  4219. */
  4220. BOOL WINAPI DllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved) {
  4221. switch ((short)dwReason) {
  4222. case DLL_PROCESS_ATTACH:
  4223. hInstApp = hInstance; // set global DLL instance
  4224. hInst = LoadWABResourceDLL(hInstApp);
  4225. // We don't need these, so tell the OS to stop 'em
  4226. DisableThreadLibraryCalls(hInstApp);
  4227. break;
  4228. case DLL_PROCESS_DETACH:
  4229. if( hInst )
  4230. FreeLibrary(hInst);
  4231. hInst = NULL;
  4232. break;
  4233. }
  4234. return(TRUE);
  4235. }