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.

1794 lines
49 KiB

  1. #include <pch.hxx>
  2. #include "demand.h"
  3. #include <bmapi.h>
  4. #define FBadCh(c) ((c) - ' ' > 64)
  5. #define DEC(c) ((BYTE) (((c) - ' ') & 0x3f))
  6. /* uuencode/decode a binary string */
  7. #define ENC(c) ((BYTE) ((c) ? ((c) & 0x3f) + ' ': '`'))
  8. int rgLeft[3] = { 0, 2, 3 };
  9. typedef USHORT CCH;
  10. STDAPI_(BOOL) FDecodeID(LPTSTR sz, LPBYTE pb, ULONG *pcb);
  11. STDAPI_(int) CchEncodedLine(int cb);
  12. STDAPI_(ULONG) CbOfEncoded(LPTSTR sz);
  13. ERR ErrSzToBinaryEID( LPSTR lpstrEID, ULONG * lpcbEID, LPVOID * lppvEID );
  14. LPSTR FAR PASCAL LpstrFromBstrA( BSTR bstrSrc, LPSTR lpstrDest );
  15. LPSTR FAR PASCAL LpstrFromBstr( BSTR bstrSrc, LPSTR lpstrDest );
  16. int FAR PASCAL FBMAPIFreeStruct (LPVOID lpMapiIn, ULONG uCount, USHORT usFlag);
  17. ULONG PASCAL VB2Mapi( LPVOID lpVBIn, LPVOID lpMapiIn, ULONG uCount, USHORT usFlag );
  18. LPMAPI_MESSAGE FAR PASCAL vbmsg2mapimsg( LPVB_MESSAGE lpVBMessage, LPSAFEARRAY lpsaVBRecips, LPSAFEARRAY lpsaVBFiles, ULONG * pulErr );
  19. ERR FAR PASCAL ErrLpstrToBstrA( LPSTR cstr, BSTR * lpBstr );
  20. ERR FAR PASCAL ErrLpstrToBstr( LPSTR cstr, BSTR * lpBstr );
  21. STDAPI_(void) EncodeID(LPBYTE pb, ULONG cb, LPTSTR sz);
  22. STDAPI_(ULONG) CchOfEncoding(ULONG cbBinary);
  23. ERR ErrBinaryToSzEID( LPVOID lpvEID, ULONG cbEID, LPSTR * lppstrEID );
  24. ULONG PASCAL Mapi2VB (LPVOID lpMapiIn, LPVOID lpVBIn, ULONG uCount, USHORT usFlag);
  25. /*---------------------------------------------------------------------
  26. *
  27. * Copyright Microsoft Corporation, 1992
  28. * _______________________________________________________________
  29. *
  30. * PROGRAM: BMAPI.CPP
  31. *
  32. * PURPOSE: Contains library routines VB MAPI wrappers
  33. *
  34. * FUNCTIONS:
  35. * BMAPISendMail
  36. * BMAPIFindNext
  37. * BMAPIReadMail
  38. * BMAPIGetReadMail
  39. * BMAPISaveMail
  40. * BMAPIAddress
  41. * BMAPIGetAddress
  42. * BMAPIResolveName
  43. * BMAPIDetails
  44. *
  45. * MISCELLANEOUS:
  46. *
  47. * - All BMAPI procedures basically follow the same structure as
  48. * follows;
  49. *
  50. * BMAPI_ENTRY BMAPIRoutine (...)
  51. * {
  52. * Allocate C Structures
  53. * Translate VB structures to C structures
  54. * Call MAPI Procedure
  55. * Translate C structures to VB Structures
  56. * DeAllocate C Structures
  57. * Return
  58. * }
  59. *
  60. *
  61. * REVISION HISTORY:
  62. *
  63. * - Last modified by v-snatar
  64. *
  65. *
  66. * _____________________________________________________________
  67. *
  68. * Copyright Microsoft Corporation, 1992-1997
  69. *
  70. *----------------------------------------------------------------------*/
  71. //---------------------------------------------------------------------------
  72. // Name: BMAPISendMail()
  73. //
  74. // Description:
  75. // 32 bit support for VB MAPISendMail().
  76. //
  77. // Parameters:
  78. // Returns:
  79. // Effects:
  80. // Notes:
  81. // Revision:
  82. //---------------------------------------------------------------------------
  83. BMAPI_ENTRY BMAPISendMail (LHANDLE hSession,
  84. ULONG_PTR ulUIParam,
  85. LPVB_MESSAGE lpM,
  86. LPSAFEARRAY * lppsaRecips,
  87. LPSAFEARRAY * lppsaFiles,
  88. ULONG flFlags,
  89. ULONG ulReserved)
  90. {
  91. ULONG ulRet = SUCCESS_SUCCESS;
  92. LPMAPI_MESSAGE lpMail = NULL;
  93. // Translate VB data into C data.
  94. if ((lpMail = vbmsg2mapimsg( lpM, *lppsaRecips, *lppsaFiles, &ulRet )) == NULL)
  95. return ulRet;
  96. // Call MAPI Procedure
  97. ulRet = MAPISendMail( hSession, // session
  98. ulUIParam, // UIParam
  99. lpMail, // Mail
  100. flFlags, // Flags
  101. ulReserved ); // Reserved
  102. // Free up data allocated by call to vbmsg2mapimsg
  103. FBMAPIFreeStruct(lpMail, 1, MESSAGE);
  104. return ulRet;
  105. }
  106. //---------------------------------------------------------------------------
  107. // Name: BMAPIFindNext()
  108. //
  109. // Description:
  110. // Implements FindNext MAPI API.
  111. //
  112. // Parameters:
  113. // Returns:
  114. // Effects:
  115. // Notes:
  116. // Revision:
  117. //---------------------------------------------------------------------------
  118. BMAPI_ENTRY BMAPIFindNext( LHANDLE hSession, // Session
  119. ULONG_PTR ulUIParam, // UIParam
  120. BSTR * lpbstrType, // MessageType
  121. BSTR * lpbstrSeed, // Seed message Id
  122. ULONG flFlags, // Flags
  123. ULONG ulReserved, // Reserved
  124. BSTR * lpbstrId) // Message Id (in/out)
  125. {
  126. ULONG ulRet;
  127. LPSTR lpID = NULL;
  128. LPSTR lpSeed;
  129. LPSTR lpTypeArg;
  130. // Translate VB strings into C strings. We'll deallocate
  131. // the strings before we return.
  132. // Always allocate the MessageID string. This way we can redimension
  133. // it to fit the returned size. We'll never use the caller's buffer.
  134. // It turns out the VBSetHlstr call (from ErrLpstrToHlstr) will reassign
  135. // the string for us.
  136. if (!MemAlloc((LPVOID*)&lpID, 513))
  137. return MAPI_E_INSUFFICIENT_MEMORY;
  138. lpSeed = LpstrFromBstrA( *lpbstrSeed, NULL);
  139. lpTypeArg = LpstrFromBstrA( *lpbstrType, NULL);
  140. // Call MAPI Procedure
  141. ulRet = MAPIFindNext( hSession, // Session
  142. ulUIParam, // UIParam
  143. lpTypeArg, // Message Type
  144. lpSeed, // Seed Message Id
  145. flFlags, // Flags,
  146. ulReserved, // Reserved
  147. lpID ); // Message ID
  148. // Translate Message ID into VB string
  149. if ( ulRet == SUCCESS_SUCCESS )
  150. ErrLpstrToBstrA( lpID, lpbstrId);
  151. // Free up C strings allocated by call to LpstrFromHlstr
  152. SafeMemFree( lpID );
  153. SafeMemFree( lpSeed );
  154. SafeMemFree( lpTypeArg );
  155. return ulRet;
  156. }
  157. //---------------------------------------------------------------------------
  158. // Name: BMAPIReadMail()
  159. //
  160. // Description:
  161. //
  162. // Implements MAPIReadMail VB API. The memory allocated by
  163. // MAPIReadMail is NOT deallocated (with MAPIFreeBuffer) until
  164. // the caller calls BMAPIGetReadMail. The recipient and file
  165. // count is returned so that the caller can Re-dimension buffers
  166. // before calling BMAPI GetReadMail. A long pointer to the
  167. // ReadMail data is also returned since it is required in the
  168. // BAMPIGetReadMail call.
  169. // Parameters:
  170. // Returns:
  171. // Effects:
  172. // Notes:
  173. // Revision:
  174. //---------------------------------------------------------------------------
  175. BMAPI_ENTRY BMAPIReadMail( PULONG_PTR lpulMessage, // pointer to output data (out)
  176. LPULONG nRecips, // number of recipients (out)
  177. LPULONG nFiles, // number of file attachments (out)
  178. LHANDLE hSession, // Session
  179. ULONG_PTR ulUIParam, // UIParam
  180. BSTR * lpbstrID, // Message Id
  181. ULONG flFlags, // Flags
  182. ULONG ulReserved ) // Reserved
  183. {
  184. LPSTR lpID;
  185. ULONG ulRet;
  186. LPMAPI_MESSAGE lpMail = NULL;
  187. // Translate VB String to C String
  188. lpID = LpstrFromBstrA( *lpbstrID, NULL );
  189. // Read the message, lpMail is set by MAPI to point
  190. // to the memory allocated by MAPI.
  191. ulRet = MAPIReadMail( hSession, // Session
  192. ulUIParam, // UIParam
  193. lpID, // Message Id
  194. flFlags, // Flags
  195. ulReserved, // Reserved
  196. &lpMail ); // Pointer to MAPI Data (returned)
  197. // Check for read error return code
  198. if ( ulRet != SUCCESS_SUCCESS )
  199. {
  200. // Clean up. Set return message to zero
  201. *lpulMessage = 0L;
  202. SafeMemFree( lpID );
  203. return ulRet;
  204. }
  205. // Pull out the recipient and file array re-dim info
  206. *nFiles = lpMail->nFileCount;
  207. *nRecips = lpMail->nRecipCount;
  208. *lpulMessage = (ULONG_PTR) (LPVOID) lpMail;
  209. SafeMemFree( lpID );
  210. return ulRet;
  211. }
  212. //---------------------------------------------------------------------------
  213. // Name: BMAPIGetReadMail()
  214. //
  215. // Description:
  216. //
  217. // Copies data stored by MAPI ReadMail (see BMAPIReadMail)
  218. // into a VB Buffer passed by the caller. It is up to the
  219. // caller to make sure the buffer passed is large enough to
  220. // accomodate the data.
  221. //
  222. // Parameters:
  223. // Returns:
  224. // Effects:
  225. // Notes:
  226. // Revision:
  227. //---------------------------------------------------------------------------
  228. BMAPI_ENTRY BMAPIGetReadMail( ULONG lpMessage, // Pointer to MAPI Mail
  229. LPVB_MESSAGE lpvbMessage, // Pointer to VB Message Buffer (out)
  230. LPSAFEARRAY * lppsaRecips, // Pointer to VB Recipient Buffer (out)
  231. LPSAFEARRAY * lppsaFiles, // Pointer to VB File attachment Buffer (out)
  232. LPVB_RECIPIENT lpvbOrig) // Pointer to VB Originator Buffer (out)
  233. {
  234. ULONG ulRet = SUCCESS_SUCCESS;
  235. ERR errVBrc;
  236. LPMAPI_MESSAGE lpMail;
  237. lpMail = (LPMAPI_MESSAGE)((ULONG_PTR)lpMessage);
  238. if ( !lpMail )
  239. return MAPI_E_INSUFFICIENT_MEMORY;
  240. // copy Attachment info to callers VB Buffer
  241. if (ulRet = Mapi2VB( lpMail->lpFiles, *lppsaFiles, lpMail->nFileCount, FILE ))
  242. {
  243. MAPIFreeBuffer(lpMail);
  244. return ulRet;
  245. }
  246. // copy Recipient info to callers VB Buffer
  247. if ( ulRet = Mapi2VB( lpMail->lpRecips, *lppsaRecips, lpMail->nRecipCount, RECIPIENT | USESAFEARRAY ) )
  248. {
  249. MAPIFreeBuffer( lpMail );
  250. return ulRet;
  251. }
  252. // Copy MAPI Message to callers VB Buffer
  253. errVBrc = 0;
  254. if ( lpMail->lpOriginator )
  255. {
  256. lpvbOrig->ulReserved = lpMail->lpOriginator->ulReserved;
  257. lpvbOrig->ulRecipClass = MAPI_ORIG;
  258. if ( lpMail->lpOriginator->lpszName )
  259. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpOriginator->lpszName, &lpvbOrig->bstrName ));
  260. if ( lpMail->lpOriginator->lpszAddress )
  261. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpOriginator->lpszAddress, &lpvbOrig->bstrAddress ));
  262. if (lpMail->lpOriginator->ulEIDSize)
  263. {
  264. LPSTR lpStrEID;
  265. // Hexize recipient EID and convert to OLE BSTR
  266. if ( ErrBinaryToSzEID( lpMail->lpOriginator->lpEntryID,
  267. lpMail->lpOriginator->ulEIDSize, &lpStrEID ) )
  268. {
  269. errVBrc = TRUE;
  270. goto exit;
  271. }
  272. // To figure out size first convert to UNICODE
  273. errVBrc = ErrLpstrToBstr( lpStrEID, &lpvbOrig->bstrEID );
  274. if ( errVBrc )
  275. {
  276. goto exit_orig;
  277. }
  278. lpvbOrig->ulEIDSize = SysStringByteLen( lpvbOrig->bstrEID )
  279. + sizeof(OLECHAR);
  280. SysFreeString( lpvbOrig->bstrEID );
  281. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpStrEID, &lpvbOrig->bstrEID ));
  282. exit_orig:
  283. SafeMemFree( lpStrEID );
  284. }
  285. }
  286. lpvbMessage->flFlags = lpMail->flFlags;
  287. lpvbMessage->ulReserved = lpMail->ulReserved;
  288. lpvbMessage->nRecipCount = lpMail->nRecipCount;
  289. lpvbMessage->nFileCount = lpMail->nFileCount;
  290. if (lpMail->lpszSubject)
  291. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszSubject, &lpvbMessage->bstrSubject));
  292. if (lpMail->lpszNoteText)
  293. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszNoteText, &lpvbMessage->bstrNoteText));
  294. if (lpMail->lpszMessageType)
  295. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszMessageType, &lpvbMessage->bstrMessageType));
  296. if (lpMail->lpszDateReceived)
  297. errVBrc = (ERR)(errVBrc + ErrLpstrToBstrA( lpMail->lpszDateReceived, &lpvbMessage->bstrDate));
  298. exit:
  299. MAPIFreeBuffer( lpMail );
  300. if ( errVBrc )
  301. ulRet = MAPI_E_FAILURE;
  302. return ulRet;
  303. }
  304. //---------------------------------------------------------------------------
  305. // Name: BMAPISaveMail()
  306. //
  307. // Description:
  308. // Implements MAPISaveMail API.
  309. //
  310. // Parameters:
  311. // Returns:
  312. // Effects:
  313. // Notes:
  314. // Revision:
  315. //---------------------------------------------------------------------------
  316. BMAPI_ENTRY BMAPISaveMail( LHANDLE hSession, // Session
  317. ULONG_PTR ulUIParam, // UIParam
  318. LPVB_MESSAGE lpM, // Pointer to VB Message Buffer
  319. LPSAFEARRAY * lppsaRecips, // Pointer to VB Recipient Buffer
  320. LPSAFEARRAY * lppsaFiles, // Pointer to VB File Attacment Buffer
  321. ULONG flFlags, // Flags
  322. ULONG ulReserved, // Reserved
  323. BSTR * lpbstrID) // Message ID
  324. {
  325. LPSTR lpID;
  326. ULONG ulRet= SUCCESS_SUCCESS;
  327. LPMAPI_MESSAGE lpMail;
  328. // Translate VB data to MAPI data
  329. lpID = LpstrFromBstrA( *lpbstrID, NULL );
  330. // If we allocate Message ID then we can set the flag.
  331. // otherwise for backward compatability assume the callers buffer size.
  332. if ( lpID == NULL )
  333. {
  334. if (!MemAlloc((LPVOID*)&lpID, 513))
  335. return MAPI_E_INSUFFICIENT_MEMORY;
  336. }
  337. if ( (lpMail = vbmsg2mapimsg( lpM, *lppsaRecips, *lppsaFiles, &ulRet )) == NULL )
  338. {
  339. SafeMemFree( lpID );
  340. return ulRet;
  341. }
  342. ulRet = MAPISaveMail( hSession,
  343. ulUIParam,
  344. lpMail,
  345. flFlags,
  346. ulReserved,
  347. lpID );
  348. if ( ulRet )
  349. goto exit;
  350. if ( ErrLpstrToBstrA( lpID, lpbstrID ) )
  351. ulRet = MAPI_E_INSUFFICIENT_MEMORY;
  352. exit:
  353. SafeMemFree( lpID );
  354. FBMAPIFreeStruct( lpMail, 1, MESSAGE );
  355. return ulRet;
  356. }
  357. //---------------------------------------------------------------------------
  358. // Name: BMAPIAddress()
  359. //
  360. // Description:
  361. //
  362. // Purpose: Allows Visual Basic to call MAPIAddress. The
  363. // Recipient data is stored in a global memory block. To
  364. // retrieve the data the caller must call BMAPIGetAddress.
  365. //
  366. // Parameters:
  367. // Returns:
  368. // Effects:
  369. // Notes:
  370. // Revision:
  371. //---------------------------------------------------------------------------
  372. BMAPI_ENTRY BMAPIAddress( PULONG_PTR lpulRecip, // Pointer to New Recipient Buffer (out)
  373. LHANDLE hSession, // Session
  374. ULONG_PTR ulUIParam, // UIParam
  375. BSTR * lpbstrCaption, // Caption string
  376. ULONG ulEditFields, // Number of Edit Controls
  377. BSTR * lpbstrLabel, // Label string
  378. LPULONG lpulRecipients, // Pointer to number of Recipients (in/out)
  379. LPSAFEARRAY * lppsaRecip, // Pointer to Initial Recipients VB_RECIPIENT
  380. ULONG ulFlags, // Flags
  381. ULONG ulReserved ) // Reserve
  382. {
  383. LPSTR lpLabel = NULL;
  384. LPSTR lpCaption = NULL;
  385. ULONG ulRet;
  386. ULONG nRecipients = 0;
  387. LPMAPI_RECIPIENT lpMapi = NULL;
  388. LPMAPI_RECIPIENT lpNewRecipients = NULL;
  389. // Convert VB Strings to C strings
  390. lpLabel = LpstrFromBstrA( *lpbstrLabel, NULL );
  391. lpCaption = LpstrFromBstrA( *lpbstrCaption, NULL );
  392. // Allocate memory and translate VB_RECIPIENTS to MAPI_RECIPIENTS.
  393. if ( *lpulRecipients )
  394. {
  395. if (!MemAlloc((LPVOID*)&lpMapi, (*lpulRecipients * sizeof (MAPI_RECIPIENT))))
  396. return MAPI_E_INSUFFICIENT_MEMORY;
  397. }
  398. if ( ulRet = VB2Mapi( (LPVOID)*lppsaRecip, (LPVOID)lpMapi, *lpulRecipients, RECIPIENT | USESAFEARRAY ) )
  399. {
  400. SafeMemFree( lpLabel );
  401. SafeMemFree( lpCaption );
  402. FBMAPIFreeStruct( lpMapi, *lpulRecipients, RECIPIENT );
  403. return ulRet;
  404. }
  405. // Call the MAPIAddress function
  406. ulRet = MAPIAddress( hSession, // Session
  407. ulUIParam, // UIParam
  408. lpCaption, // Caption
  409. ulEditFields, // Number of edit fields
  410. lpLabel, // Label
  411. *lpulRecipients, // Number of Recipients
  412. lpMapi, // Pointer to recipients
  413. ulFlags, // Flags
  414. ulReserved, // Reserved
  415. (LPULONG) &nRecipients, // Address for new recipient count
  416. (lpMapiRecipDesc far *)&lpNewRecipients); // Address of new recipient data
  417. // Free up MAPI structures created in this procedure
  418. SafeMemFree( lpLabel );
  419. SafeMemFree( lpCaption );
  420. FBMAPIFreeStruct( lpMapi, *lpulRecipients, RECIPIENT );
  421. // Set the returned parameters and return
  422. if ( ulRet == SUCCESS_SUCCESS )
  423. {
  424. *lpulRecipients = nRecipients;
  425. *lpulRecip = (ULONG_PTR) (LPVOID) lpNewRecipients;
  426. }
  427. return ulRet;
  428. }
  429. //---------------------------------------------------------------------------
  430. // Name: BMAPIGetAddress()
  431. //
  432. // Description:
  433. // Converts a MapiRecipDesc array into an OLE 2.0 SAFEARRAY.
  434. //
  435. // Parameters:
  436. // Returns:
  437. // Effects:
  438. // Notes:
  439. // Revision:
  440. //---------------------------------------------------------------------------
  441. BMAPI_ENTRY BMAPIGetAddress (ULONG ulRecipientData, // Pointer to recipient data
  442. ULONG cRecipients, // Number of recipients
  443. LPSAFEARRAY * lppsaRecips ) // VB recipient array
  444. {
  445. ULONG ulRet = SUCCESS_SUCCESS;
  446. LPMAPI_RECIPIENT lpData = NULL;
  447. if (cRecipients == 0)
  448. {
  449. MAPIFreeBuffer( (LPVOID)((ULONG_PTR)ulRecipientData) );
  450. return SUCCESS_SUCCESS;
  451. }
  452. lpData = (LPMAPI_RECIPIENT)((ULONG_PTR)ulRecipientData);
  453. // Translate MAPI Address data to VB buffer
  454. ulRet = Mapi2VB( lpData, *lppsaRecips, cRecipients, RECIPIENT | USESAFEARRAY );
  455. // Free up MAPI recipient data since it got copied over.
  456. MAPIFreeBuffer( lpData );
  457. return ulRet;
  458. }
  459. //---------------------------------------------------------------------------
  460. // Name: BMAPIDetails()
  461. //
  462. // Description:
  463. // Allows VB to call MAPIDetails procedure.
  464. //
  465. // Parameters:
  466. // Returns:
  467. // Effects:
  468. // Notes:
  469. // Revision:
  470. //---------------------------------------------------------------------------
  471. BMAPI_ENTRY BMAPIDetails (LHANDLE hSession, // Session
  472. ULONG_PTR ulUIParam, // UIParam
  473. LPVB_RECIPIENT lpVB, // Pointer to VB recipient stucture
  474. ULONG ulFlags, // Flags
  475. ULONG ulReserved) // Reserved
  476. {
  477. ULONG ulRet;
  478. LPMAPI_RECIPIENT lpMapi = NULL;
  479. // Translate VB_RECIPIENTS to MAPI_RECIPIENTS.
  480. if (!MemAlloc((LPVOID*)&lpMapi,sizeof (MAPI_RECIPIENT)))
  481. return MAPI_E_INSUFFICIENT_MEMORY;
  482. if ( ulRet = VB2Mapi( lpVB, lpMapi, 1, RECIPIENT ) )
  483. {
  484. FBMAPIFreeStruct( lpMapi, 1, RECIPIENT );
  485. return ulRet;
  486. }
  487. // Call the Simple MAPI function
  488. ulRet = MAPIDetails( hSession, // Session
  489. ulUIParam, // UIParam
  490. lpMapi, // Pointer to MAPI Recipient structure
  491. ulFlags, // Flags
  492. ulReserved ); // Reserved
  493. FBMAPIFreeStruct( lpMapi, 1L, RECIPIENT );
  494. return ulRet;
  495. }
  496. //---------------------------------------------------------------------------
  497. // Name: BMAPIResolveName
  498. //
  499. // Description:
  500. // Implements VB MAPIResolveName
  501. //
  502. // Parameters:
  503. // Returns:
  504. // Effects:
  505. // Notes:
  506. // Revision:
  507. //---------------------------------------------------------------------------
  508. BMAPI_ENTRY BMAPIResolveName (LHANDLE hSession, // Session
  509. ULONG_PTR ulUIParam, // UIParam
  510. BSTR bstrMapiName, // Name to be resolved
  511. ULONG ulFlags, // Flags
  512. ULONG ulReserved, // Reserved
  513. LPVB_RECIPIENT lpVB) // Pointer to VB recipient structure (out)
  514. {
  515. LPMAPI_RECIPIENT lpMapi = NULL;
  516. ULONG ulRet;
  517. LPSTR lpszMapiName;
  518. lpszMapiName = LpstrFromBstrA( bstrMapiName, NULL );
  519. // Call the MAPIResolveName function
  520. ulRet = MAPIResolveName( hSession, // Session
  521. ulUIParam, // UIParam
  522. lpszMapiName, // Pointer to resolve name
  523. ulFlags, // Flags
  524. ulReserved, // Reserved
  525. (LPPMAPI_RECIPIENT) &lpMapi ); // Pointer to Recipient (returned)
  526. if (ulRet != SUCCESS_SUCCESS)
  527. return ulRet;
  528. // Translate MAPI data to VB data
  529. ulRet = Mapi2VB( lpMapi, lpVB, 1, RECIPIENT );
  530. MAPIFreeBuffer( lpMapi );
  531. return ulRet;
  532. }
  533. // Helper Functions
  534. //---------------------------------------------------------------------------
  535. // Name: vbmsg2mapimsg()
  536. //
  537. // Description:
  538. // Translates VB Message structure to MAPI Message structure
  539. //
  540. // Parameters:
  541. // Returns:
  542. // Effects:
  543. // Notes:
  544. // Revision:
  545. //---------------------------------------------------------------------------
  546. LPMAPI_MESSAGE FAR PASCAL vbmsg2mapimsg( LPVB_MESSAGE lpVBMessage, LPSAFEARRAY lpsaVBRecips,
  547. LPSAFEARRAY lpsaVBFiles, ULONG * pulErr )
  548. {
  549. LPMAPI_FILE lpMapiFile=NULL;
  550. LPMAPI_MESSAGE lpMapiMessage=NULL;
  551. LPMAPI_RECIPIENT lpMapiRecipient=NULL;
  552. if (lpVBMessage == (LPVB_MESSAGE) NULL)
  553. {
  554. *pulErr = MAPI_E_FAILURE;
  555. return NULL;
  556. }
  557. // Allocate MAPI Message, Recipient and File structures
  558. // NOTE: Don't move the following lines of code without
  559. // making sure you de-allocate memory properly if the
  560. // calls fail.
  561. if (!MemAlloc((LPVOID*)&lpMapiMessage,sizeof(MapiMessage)))
  562. {
  563. *pulErr = MAPI_E_INSUFFICIENT_MEMORY;
  564. return NULL;
  565. }
  566. if (lpVBMessage->nFileCount > 0)
  567. {
  568. if (!MemAlloc((LPVOID*)&lpMapiFile, sizeof(MAPI_FILE)*lpVBMessage->nFileCount))
  569. {
  570. FBMAPIFreeStruct( (LPVOID*)&lpMapiMessage, 1, MESSAGE );
  571. *pulErr = MAPI_E_INSUFFICIENT_MEMORY;
  572. return NULL;
  573. }
  574. }
  575. if (lpVBMessage->nRecipCount > 0)
  576. {
  577. if (!MemAlloc((LPVOID*)&lpMapiRecipient, sizeof(MAPI_RECIPIENT)*lpVBMessage->nRecipCount))
  578. {
  579. FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE );
  580. FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE );
  581. *pulErr = MAPI_E_INSUFFICIENT_MEMORY;
  582. return NULL;
  583. }
  584. }
  585. // Translate structures from VB to MAPI
  586. if ( *pulErr = VB2Mapi( lpsaVBFiles, lpMapiFile, lpVBMessage->nFileCount, FILE | USESAFEARRAY ) )
  587. {
  588. FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE );
  589. FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT );
  590. FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE );
  591. return NULL;
  592. }
  593. if ( *pulErr = VB2Mapi( lpsaVBRecips, lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT | USESAFEARRAY ) )
  594. {
  595. FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE );
  596. FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT );
  597. FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE );
  598. return NULL;
  599. }
  600. if ( *pulErr = VB2Mapi( lpVBMessage, lpMapiMessage, 1, MESSAGE ) )
  601. {
  602. FBMAPIFreeStruct( lpMapiFile, lpVBMessage->nFileCount, FILE );
  603. FBMAPIFreeStruct( lpMapiRecipient, lpVBMessage->nRecipCount, RECIPIENT );
  604. FBMAPIFreeStruct( lpMapiMessage, 1, MESSAGE );
  605. return NULL;
  606. }
  607. // Chain File and Recipient structures to Message structure
  608. lpMapiMessage->lpFiles = lpMapiFile;
  609. lpMapiMessage->lpRecips = lpMapiRecipient;
  610. return lpMapiMessage;
  611. }
  612. //---------------------------------------------------------------------------
  613. // Name: VB2Mapi()
  614. //
  615. // Description:
  616. // Converts VB structures to MAPI structures. Arrays from
  617. // VB 4.0 arrive as OLE SAFEARRAYs.
  618. //
  619. // Parameters:
  620. // Returns:
  621. // Simple MAPI error code
  622. //
  623. // Effects:
  624. // Notes:
  625. // originally FALSE for failure, TRUE for success.
  626. // Revision:
  627. //---------------------------------------------------------------------------
  628. ULONG PASCAL VB2Mapi( LPVOID lpVBIn, LPVOID lpMapiIn, ULONG uCount, USHORT usFlag )
  629. {
  630. ULONG u;
  631. HRESULT hr = 0;
  632. ULONG ulErr = SUCCESS_SUCCESS;
  633. ERR Err = FALSE;
  634. LPVB_RECIPIENT lpVBR;
  635. LPMAPI_RECIPIENT lpMapiR;
  636. LPVB_MESSAGE lpVBM;
  637. LPMAPI_MESSAGE lpMapiM;
  638. LPVB_FILE lpVBF;
  639. LPMAPI_FILE lpMapiF;
  640. LPSAFEARRAY lpsa = NULL;
  641. if (lpVBIn == (LPVOID)NULL)
  642. {
  643. lpMapiIn = NULL;
  644. return SUCCESS_SUCCESS;
  645. }
  646. if (uCount <= 0)
  647. {
  648. lpMapiIn = NULL;
  649. return SUCCESS_SUCCESS;
  650. }
  651. if ( lpMapiIn == (LPVOID)NULL )
  652. return MAPI_E_FAILURE;
  653. switch ( usFlag & ~(USESAFEARRAY) )
  654. {
  655. case RECIPIENT:
  656. if ( usFlag & USESAFEARRAY )
  657. {
  658. lpsa = (LPSAFEARRAY)lpVBIn;
  659. hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBR );
  660. if (hr)
  661. {
  662. ulErr = MAPI_E_FAILURE;
  663. goto exit;
  664. }
  665. if (!lpVBR || lpsa->rgsabound[0].cElements < uCount)
  666. {
  667. (void)SafeArrayUnaccessData( lpsa );
  668. ulErr = MAPI_E_INVALID_RECIPS;
  669. goto exit;
  670. }
  671. }
  672. else
  673. {
  674. lpVBR = (LPVB_RECIPIENT)lpVBIn;
  675. }
  676. lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
  677. for ( u = 0L; u < uCount; u++, lpMapiR++, lpVBR++ )
  678. {
  679. lpMapiR->ulReserved = lpVBR->ulReserved;
  680. lpMapiR->ulRecipClass = lpVBR->ulRecipClass;
  681. if ( usFlag & USESAFEARRAY )
  682. {
  683. lpMapiR->lpszName = LpstrFromBstr( lpVBR->bstrName, NULL );
  684. lpMapiR->lpszAddress = LpstrFromBstr( lpVBR->bstrAddress, NULL );
  685. }
  686. else
  687. {
  688. lpMapiR->lpszName = LpstrFromBstrA( lpVBR->bstrName, NULL );
  689. lpMapiR->lpszAddress = LpstrFromBstrA( lpVBR->bstrAddress, NULL );
  690. }
  691. if (lpVBR->ulEIDSize > 0L)
  692. {
  693. LPSTR lpStrT;
  694. // Convert EID string from OLE Bstr...
  695. if ( usFlag & USESAFEARRAY )
  696. {
  697. if ( IsBadReadPtr( lpVBR->bstrEID, lpVBR->ulEIDSize ) )
  698. {
  699. ulErr = MAPI_E_INVALID_RECIPS;
  700. goto exit;
  701. }
  702. lpStrT = LpstrFromBstr( lpVBR->bstrEID, NULL );
  703. }
  704. else
  705. {
  706. // VB 4.0 took care of translating Wide Char to Multibyte.
  707. // ulEIDSize is still based on UNICODE byte size. Take
  708. // smallest approximation.
  709. if ( IsBadReadPtr( lpVBR->bstrEID, lpVBR->ulEIDSize / 2 ) )
  710. {
  711. ulErr = MAPI_E_INVALID_RECIPS;
  712. goto exit;
  713. }
  714. lpStrT = LpstrFromBstrA( lpVBR->bstrEID, NULL );
  715. }
  716. // and UnHexize.
  717. if ( lpStrT )
  718. {
  719. Err = ErrSzToBinaryEID( lpStrT, &lpMapiR->ulEIDSize,
  720. &lpMapiR->lpEntryID );
  721. SafeMemFree(lpStrT );
  722. if ( Err )
  723. {
  724. ulErr = MAPI_E_INVALID_RECIPS;
  725. goto exit;
  726. }
  727. }
  728. }
  729. else
  730. lpMapiR->lpEntryID = (LPVOID) NULL;
  731. }
  732. if ( usFlag & USESAFEARRAY )
  733. (void)SafeArrayUnaccessData( lpsa );
  734. break;
  735. case FILE:
  736. lpsa = (LPSAFEARRAY)lpVBIn;
  737. hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBF );
  738. if ( hr )
  739. {
  740. ulErr = MAPI_E_FAILURE;
  741. goto exit;
  742. }
  743. if ( !lpVBF || lpsa->rgsabound[0].cElements < uCount )
  744. {
  745. (void)SafeArrayUnaccessData( lpsa );
  746. ulErr = MAPI_E_ATTACHMENT_NOT_FOUND;
  747. goto exit;
  748. }
  749. lpMapiF = (LPMAPI_FILE)lpMapiIn;
  750. for (u = 0L; u < uCount; u++, lpMapiF++, lpVBF++)
  751. {
  752. lpMapiF->ulReserved = lpVBF->ulReserved;
  753. lpMapiF->flFlags = lpVBF->flFlags;
  754. lpMapiF->nPosition = lpVBF->nPosition;
  755. lpMapiF->lpszPathName = LpstrFromBstr( lpVBF->bstrPathName, NULL );
  756. lpMapiF->lpszFileName = LpstrFromBstr( lpVBF->bstrFileName, NULL );
  757. lpMapiF->lpFileType = LpstrFromBstr( lpVBF->bstrFileType, NULL);
  758. }
  759. (void)SafeArrayUnaccessData( lpsa );
  760. break;
  761. case MESSAGE:
  762. lpVBM = (LPVB_MESSAGE) lpVBIn;
  763. lpMapiM = (LPMAPI_MESSAGE) lpMapiIn;
  764. lpMapiM->ulReserved = lpVBM->ulReserved;
  765. lpMapiM->flFlags = lpVBM->flFlags;
  766. lpMapiM->nRecipCount = lpVBM->nRecipCount;
  767. lpMapiM->lpOriginator = NULL;
  768. lpMapiM->nFileCount = lpVBM->nFileCount;
  769. lpMapiM->lpRecips = NULL;
  770. lpMapiM->lpFiles = NULL;
  771. // errors are ignored
  772. lpMapiM->lpszSubject = LpstrFromBstrA( lpVBM->bstrSubject, NULL );
  773. lpMapiM->lpszNoteText = LpstrFromBstrA( lpVBM->bstrNoteText, NULL );
  774. lpMapiM->lpszConversationID = LpstrFromBstrA( lpVBM->bstrConversationID, NULL );
  775. lpMapiM->lpszDateReceived = LpstrFromBstrA( lpVBM->bstrDate, NULL );
  776. lpMapiM->lpszMessageType = LpstrFromBstrA( lpVBM->bstrMessageType, NULL );
  777. break;
  778. default:
  779. ulErr = MAPI_E_FAILURE;
  780. goto exit;
  781. }
  782. exit:
  783. return ulErr;
  784. }
  785. //---------------------------------------------------------------------------
  786. // Name: Mapi2VB
  787. //
  788. // Description:
  789. // Converts MAPI RECIPIENT, FILE, or MESSAGE structures to VB
  790. // Recipients and Files are handled as OLE SAFEARRAYs.
  791. //
  792. // Parameters:
  793. // Returns:
  794. // Simple Mapi error code
  795. //
  796. // Effects:
  797. // Notes:
  798. // originally FALSE for failure, TRUE for success.
  799. // Revision:
  800. //---------------------------------------------------------------------------
  801. ULONG PASCAL Mapi2VB (LPVOID lpMapiIn, LPVOID lpVBIn, ULONG uCount, USHORT usFlag)
  802. {
  803. HRESULT hr = 0;
  804. ERR Err = FALSE;
  805. ULONG ulErr = SUCCESS_SUCCESS;
  806. ULONG u;
  807. LPVB_MESSAGE lpVBM;
  808. LPMAPI_MESSAGE lpMapiM;
  809. LPVB_RECIPIENT lpVBR;
  810. LPMAPI_RECIPIENT lpMapiR;
  811. LPVB_FILE lpVBF;
  812. LPMAPI_FILE lpMapiF;
  813. LPSAFEARRAY lpsa = NULL;
  814. // If lpVBIn is NULL, this is a bad thing
  815. if (lpVBIn == (LPVOID) NULL)
  816. return MAPI_E_FAILURE;
  817. // if lpMapiIn is NULL then set
  818. // lpVBIn to NULL and return success
  819. if (lpMapiIn == NULL)
  820. {
  821. lpVBIn = NULL;
  822. return SUCCESS_SUCCESS;
  823. }
  824. switch ( usFlag & ~(USESAFEARRAY) )
  825. {
  826. case RECIPIENT:
  827. if ( usFlag & USESAFEARRAY )
  828. {
  829. lpsa = (LPSAFEARRAY)lpVBIn;
  830. hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBR );
  831. if (hr)
  832. {
  833. ulErr = MAPI_E_FAILURE;
  834. goto exit;
  835. }
  836. if ( !lpVBR || lpsa->rgsabound[0].cElements < uCount )
  837. {
  838. (void)SafeArrayUnaccessData(lpsa);
  839. ulErr = MAPI_E_INVALID_RECIPS;
  840. goto exit;
  841. }
  842. }
  843. else
  844. {
  845. lpVBR = (LPVB_RECIPIENT)lpVBIn;
  846. }
  847. lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
  848. for (u = 0L; u < uCount; u++, lpMapiR++, lpVBR++)
  849. {
  850. lpVBR->ulReserved = lpMapiR->ulReserved;
  851. lpVBR->ulRecipClass = lpMapiR->ulRecipClass;
  852. if (usFlag & USESAFEARRAY)
  853. {
  854. if ( ErrLpstrToBstr( lpMapiR->lpszName, &lpVBR->bstrName ) )
  855. {
  856. ulErr = MAPI_E_INVALID_RECIPS;
  857. goto exit;
  858. }
  859. if (Err = ErrLpstrToBstr( lpMapiR->lpszAddress, &lpVBR->bstrAddress ) )
  860. {
  861. ulErr = MAPI_E_INVALID_RECIPS;
  862. goto exit;
  863. }
  864. }
  865. else
  866. {
  867. if ( ErrLpstrToBstrA( lpMapiR->lpszName, &lpVBR->bstrName ) )
  868. {
  869. ulErr = MAPI_E_INVALID_RECIPS;
  870. goto exit;
  871. }
  872. if ( ErrLpstrToBstrA( lpMapiR->lpszAddress, &lpVBR->bstrAddress ) )
  873. {
  874. ulErr = MAPI_E_INVALID_RECIPS;
  875. goto exit;
  876. }
  877. }
  878. if ( lpMapiR->ulEIDSize > 0L)
  879. {
  880. LPSTR lpStrEID;
  881. // Convert Recip EID to a hexized string
  882. if ( ErrBinaryToSzEID( lpMapiR->lpEntryID, lpMapiR->ulEIDSize, &lpStrEID ) )
  883. {
  884. ulErr = MAPI_E_INVALID_RECIPS;
  885. goto exit;
  886. }
  887. // Convert to a BSTR
  888. // and figure out the size
  889. if ( usFlag & USESAFEARRAY )
  890. {
  891. Err = ErrLpstrToBstr( lpStrEID, &lpVBR->bstrEID );
  892. SafeMemFree( lpStrEID );
  893. if (Err)
  894. {
  895. ulErr = MAPI_E_INVALID_RECIPS;
  896. goto exit;
  897. }
  898. lpVBR->ulEIDSize = SysStringByteLen( lpVBR->bstrEID )
  899. + sizeof(OLECHAR);
  900. }
  901. else
  902. {
  903. // To figure out size first convert to UNICODE
  904. if ( ErrLpstrToBstr( lpStrEID, &lpVBR->bstrEID ) )
  905. {
  906. SafeMemFree( lpStrEID );
  907. ulErr = MAPI_E_INVALID_RECIPS;
  908. goto exit;
  909. }
  910. lpVBR->ulEIDSize = SysStringByteLen( lpVBR->bstrEID )
  911. + sizeof(OLECHAR);
  912. SysFreeString( lpVBR->bstrEID );
  913. Err = ErrLpstrToBstrA( lpStrEID, &lpVBR->bstrEID );
  914. SafeMemFree( lpStrEID );
  915. if ( Err )
  916. {
  917. ulErr = MAPI_E_INVALID_RECIPS;
  918. goto exit;
  919. }
  920. }
  921. }
  922. }
  923. if ( usFlag & USESAFEARRAY )
  924. (void)SafeArrayUnaccessData( lpsa );
  925. break;
  926. case FILE:
  927. lpsa = (LPSAFEARRAY)lpVBIn;
  928. hr = SafeArrayAccessData( lpsa, (LPVOID*)&lpVBF );
  929. if ( hr )
  930. {
  931. ulErr = MAPI_E_FAILURE;
  932. goto exit;
  933. }
  934. if ( !lpVBF || lpsa->rgsabound[0].cElements < uCount )
  935. {
  936. (void)SafeArrayUnaccessData( lpsa );
  937. ulErr = MAPI_E_FAILURE;
  938. goto exit;
  939. }
  940. lpMapiF = (LPMAPI_FILE) lpMapiIn;
  941. for (u = 0L; u < uCount; u++, lpMapiF++, lpVBF++)
  942. {
  943. lpVBF->ulReserved = lpMapiF->ulReserved;
  944. lpVBF->flFlags = lpMapiF->flFlags;
  945. lpVBF->nPosition = lpMapiF->nPosition;
  946. if ( ErrLpstrToBstr( lpMapiF->lpszPathName, &lpVBF->bstrPathName ) )
  947. {
  948. ulErr = MAPI_E_ATTACHMENT_NOT_FOUND;
  949. goto exit;
  950. }
  951. if ( ErrLpstrToBstr( lpMapiF->lpszFileName, &lpVBF->bstrFileName ) )
  952. {
  953. ulErr = MAPI_E_ATTACHMENT_NOT_FOUND;
  954. goto exit;
  955. }
  956. // this is something to keep VBAPI from faulting
  957. if ( ErrLpstrToBstr( (LPSTR) "", &lpVBF->bstrFileType ) )
  958. {
  959. ulErr = MAPI_E_ATTACHMENT_NOT_FOUND;
  960. goto exit;
  961. }
  962. }
  963. (void)SafeArrayUnaccessData( lpsa );
  964. break;
  965. case MESSAGE:
  966. lpVBM = (LPVB_MESSAGE)lpVBIn;
  967. lpMapiM = (LPMAPI_MESSAGE)lpMapiIn;
  968. lpVBM->ulReserved = lpMapiM->ulReserved;
  969. lpVBM->flFlags = lpMapiM->flFlags;
  970. lpVBM->nRecipCount = lpMapiM->nRecipCount;
  971. lpVBM->nFileCount = lpMapiM->nFileCount;
  972. if ( ErrLpstrToBstr( lpMapiM->lpszSubject, &lpVBM->bstrSubject ) )
  973. {
  974. ulErr = MAPI_E_INVALID_MESSAGE;
  975. goto exit;
  976. }
  977. if ( ErrLpstrToBstr( lpMapiM->lpszNoteText, &lpVBM->bstrNoteText ) )
  978. {
  979. ulErr = MAPI_E_INVALID_MESSAGE;
  980. goto exit;
  981. }
  982. if ( ErrLpstrToBstr( lpMapiM->lpszConversationID, &lpVBM->bstrConversationID ) )
  983. {
  984. ulErr = MAPI_E_INVALID_MESSAGE;
  985. goto exit;
  986. }
  987. if ( ErrLpstrToBstr( lpMapiM->lpszDateReceived, &lpVBM->bstrDate ) )
  988. {
  989. ulErr = MAPI_E_INVALID_MESSAGE;
  990. goto exit;
  991. }
  992. if ( ErrLpstrToBstr( lpMapiM->lpszMessageType, &lpVBM->bstrMessageType ) )
  993. {
  994. ulErr = MAPI_E_INVALID_MESSAGE;
  995. goto exit;
  996. }
  997. break;
  998. default:
  999. ulErr = MAPI_E_FAILURE;
  1000. goto exit;
  1001. }
  1002. exit:
  1003. return ulErr;
  1004. }
  1005. //---------------------------------------------------------------------------
  1006. // Name: FBMAPIFreeStruct()
  1007. //
  1008. // Description:
  1009. // DeAllocates MAPI structure created in VB2MAPI
  1010. //
  1011. // Parameters:
  1012. // Returns:
  1013. // Effects:
  1014. // Notes:
  1015. // Revision:
  1016. //---------------------------------------------------------------------------
  1017. int FAR PASCAL FBMAPIFreeStruct (LPVOID lpMapiIn, ULONG uCount, USHORT usFlag)
  1018. {
  1019. ULONG u;
  1020. LPMAPI_RECIPIENT lpMapiR;
  1021. LPMAPI_FILE lpMapiF;
  1022. LPMAPI_MESSAGE lpMapiM;
  1023. if (lpMapiIn == (LPVOID) NULL)
  1024. return TRUE;
  1025. switch ( usFlag )
  1026. {
  1027. case RECIPIENT:
  1028. lpMapiR = (LPMAPI_RECIPIENT)lpMapiIn;
  1029. for ( u = 0L; u < uCount; u++, lpMapiR++ )
  1030. {
  1031. SafeMemFree(lpMapiR->lpszName);
  1032. SafeMemFree(lpMapiR->lpszAddress);
  1033. SafeMemFree(lpMapiR->lpEntryID);
  1034. }
  1035. SafeMemFree(lpMapiIn);
  1036. break;
  1037. case FILE:
  1038. lpMapiF = (LPMAPI_FILE) lpMapiIn;
  1039. for ( u = 0L; u < uCount; u++, lpMapiF++ )
  1040. {
  1041. SafeMemFree(lpMapiF->lpszPathName);
  1042. SafeMemFree(lpMapiF->lpszFileName);
  1043. SafeMemFree(lpMapiF->lpFileType);
  1044. }
  1045. SafeMemFree(lpMapiIn);
  1046. break;
  1047. case MESSAGE:
  1048. lpMapiM = ( LPMAPI_MESSAGE ) lpMapiIn;
  1049. if (lpMapiM->lpRecips)
  1050. FBMAPIFreeStruct((LPVOID)lpMapiM->lpRecips, lpMapiM->nRecipCount, RECIPIENT);
  1051. if (lpMapiM->lpFiles)
  1052. FBMAPIFreeStruct((LPVOID) lpMapiM->lpFiles, lpMapiM->nFileCount, FILE);
  1053. SafeMemFree( lpMapiM->lpszSubject );
  1054. SafeMemFree( lpMapiM->lpszNoteText );
  1055. SafeMemFree( lpMapiM->lpszMessageType );
  1056. SafeMemFree( lpMapiM->lpszDateReceived );
  1057. SafeMemFree( lpMapiM->lpszConversationID );
  1058. SafeMemFree( lpMapiM );
  1059. break;
  1060. default:
  1061. return FALSE;
  1062. }
  1063. return TRUE;
  1064. }
  1065. //---------------------------------------------------------------------------
  1066. // Name: LpstrFromBstr()
  1067. //
  1068. // Description:
  1069. // Copies and converts OLE Bstr from UNICODE to an ANSI
  1070. // C string.
  1071. //
  1072. // Parameters:
  1073. // Returns:
  1074. // String if successful
  1075. // NULL if failure
  1076. // Effects:
  1077. // Notes:
  1078. // Note that this function returns NULL for failure as well as
  1079. // a NULL bstr. This was how the original VB 3.0 implementation
  1080. // worked.
  1081. //
  1082. // Revision:
  1083. //---------------------------------------------------------------------------
  1084. LPSTR FAR PASCAL LpstrFromBstr( BSTR bstrSrc, LPSTR lpstrDest )
  1085. {
  1086. USHORT cbSrc;
  1087. if ( !bstrSrc )
  1088. return NULL;
  1089. // Copy over the bstr string to a 'C' string
  1090. cbSrc = (USHORT)SysStringLen((OLECHAR *)bstrSrc);
  1091. if (cbSrc == 0)
  1092. return NULL;
  1093. // make sure we handle truly multi byte character sets when
  1094. // we convert from UNICODE to MultiByte.
  1095. cbSrc = (USHORT)((cbSrc + 1) * sizeof(OLECHAR));
  1096. // If Destination is NULL then we'll allocate
  1097. // memory to hold the string. The caller must
  1098. // deallocate this at some time.
  1099. if ( lpstrDest == NULL )
  1100. {
  1101. if(!MemAlloc((LPVOID*)&lpstrDest, cbSrc))
  1102. return NULL;
  1103. }
  1104. if (!WideCharToMultiByte(CP_ACP, 0, bstrSrc, -1, lpstrDest, cbSrc, NULL, NULL))
  1105. {
  1106. SafeMemFree(lpstrDest);
  1107. lpstrDest = NULL;
  1108. }
  1109. return lpstrDest;
  1110. }
  1111. //---------------------------------------------------------------------------
  1112. // Name: LpstrFromBstrA
  1113. //
  1114. // Description:
  1115. // Copies OLE Bstre ANSI string to C string. Allocates string space
  1116. // from the global heap and returns a long
  1117. // pointer to memory. The memory must be freed by the caller
  1118. // with a call to BMAPIFree.
  1119. //
  1120. // Parameters:
  1121. // Returns:
  1122. // String if successful
  1123. // NULL if failure
  1124. //
  1125. // Effects:
  1126. // Notes:
  1127. // Revision:
  1128. //---------------------------------------------------------------------------
  1129. LPSTR FAR PASCAL LpstrFromBstrA( BSTR bstrSrc, LPSTR lpstrDest )
  1130. {
  1131. USHORT cbSrc;
  1132. // If Destination is NULL then we'll allocate memory to hold the
  1133. // string. The caller must deallocate this at some time.
  1134. cbSrc = (USHORT)SysStringByteLen((OLECHAR *)bstrSrc);
  1135. // Copy over the hlstr string to a 'C' string
  1136. if ( cbSrc == 0 )
  1137. return NULL;
  1138. if ( lpstrDest == NULL )
  1139. {
  1140. if (!MemAlloc((LPVOID*)&lpstrDest, cbSrc + 1))
  1141. return NULL;
  1142. }
  1143. memcpy( lpstrDest, bstrSrc, cbSrc );
  1144. lpstrDest[cbSrc] = '\0';
  1145. return lpstrDest;
  1146. }
  1147. //---------------------------------------------------------------------------
  1148. // Name: ErrSzToBinaryEID()
  1149. //
  1150. // Description:
  1151. // Converts a hexized binary string to binary returning
  1152. // the binary data and the size of the data.
  1153. //
  1154. // Parameters:
  1155. // Returns:
  1156. // FALSE if success.
  1157. // TRUE if failure.
  1158. // Effects:
  1159. // Notes:
  1160. // Revision:
  1161. //---------------------------------------------------------------------------
  1162. ERR ErrSzToBinaryEID( LPSTR lpstrEID, ULONG * lpcbEID, LPVOID * lppvEID )
  1163. {
  1164. ERR Err = FALSE;
  1165. ULONG cbEID;
  1166. cbEID = CbOfEncoded( lpstrEID );
  1167. if (!MemAlloc(lppvEID, cbEID))
  1168. {
  1169. Err = TRUE;
  1170. goto exit;
  1171. }
  1172. if (!FDecodeID( lpstrEID, (LPBYTE)*lppvEID, lpcbEID ) )
  1173. {
  1174. Err = TRUE;
  1175. SafeMemFree( *lppvEID );
  1176. *lppvEID = NULL;
  1177. goto exit;
  1178. }
  1179. exit:
  1180. return Err;
  1181. }
  1182. /*
  1183. * Given an string that encodes some binary data, returns the
  1184. * maximal size of the binary data.
  1185. */
  1186. STDAPI_(ULONG) CbOfEncoded(LPTSTR sz)
  1187. {
  1188. return (lstrlen(sz) / 4 + 1) * 3; // slightly fat
  1189. }
  1190. /*
  1191. * Given a byte count, returns the number of characters necessary
  1192. * to encode that many bytes.
  1193. */
  1194. STDAPI_(int) CchEncodedLine(int cb)
  1195. {
  1196. Assert(cb <= 45);
  1197. return (cb / 3) * 4 + rgLeft[cb % 3];
  1198. }
  1199. /*
  1200. - FDecodeID
  1201. -
  1202. * Purpose:
  1203. * Turns a character string produced by EncodeID back to a
  1204. * byte string. Some validation of the input string is done.
  1205. *
  1206. * Arguments:
  1207. * sz in The input character string.
  1208. * pb out The decoded byte string. The output
  1209. * string is not length-checked.
  1210. * pcb out The size of the byte string
  1211. *
  1212. * Returns:
  1213. * FALSE => the encoded string was garbled in some way
  1214. * TRUE => all OK
  1215. */
  1216. STDAPI_(BOOL) FDecodeID(LPTSTR sz, LPBYTE pb, ULONG *pcb)
  1217. {
  1218. int cchLine;
  1219. int ich;
  1220. CCH cch = (CCH)lstrlen(sz);
  1221. LPTSTR szT = sz;
  1222. AssertSz(!IsBadStringPtr(sz, INFINITE), "FDecodeID: sz fails address check");
  1223. AssertSz(!IsBadWritePtr(pb, 1), "FDecodeID: pb fails address check");
  1224. AssertSz(!IsBadWritePtr(pcb, sizeof(ULONG)), "FDecodeID: pcb fails address check");
  1225. *pcb = 0;
  1226. while (*szT)
  1227. {
  1228. // Process line header
  1229. if (FBadCh(*szT))
  1230. return FALSE;
  1231. ich = DEC(*szT); // Byte count for "line"
  1232. *pcb += ich; // running total of decoded info
  1233. cchLine = CchEncodedLine(ich); // Length-check this "line"
  1234. if (szT + cchLine + 1 > sz + cch)
  1235. return FALSE;
  1236. ++szT;
  1237. // Process line contents
  1238. for (ich = 0; ich < cchLine; ++ich)
  1239. {
  1240. if (FBadCh(*szT))
  1241. return FALSE;
  1242. switch (ich % 4)
  1243. {
  1244. case 0:
  1245. *pb = (BYTE) (DEC(*szT) << 2);
  1246. break;
  1247. case 1:
  1248. *pb |= (DEC(*szT) >> 4) & 0x03;
  1249. ++pb;
  1250. *pb = (BYTE) (DEC(*szT) << 4);
  1251. break;
  1252. case 2:
  1253. *pb |= (DEC(*szT) >> 2) & 0x0f;
  1254. ++pb;
  1255. *pb = (BYTE) (DEC(*szT) << 6);
  1256. break;
  1257. case 3:
  1258. *pb |= DEC(*szT);
  1259. ++pb;
  1260. break;
  1261. }
  1262. ++szT;
  1263. }
  1264. }
  1265. return TRUE;
  1266. }
  1267. //---------------------------------------------------------------------------
  1268. // Name: ErrLpstrToBstrA()
  1269. //
  1270. // Description:
  1271. // Copies C string to OLE BSTR. Note that the bstr
  1272. // contains an ANSI string. VB 4.0 will automatically
  1273. // convert this ANSI string to unicode when the string if
  1274. // this string is a member of a UDT and declared as a UDT.
  1275. // Arrays of UDTs are handled as SAFEARRAYS.
  1276. //
  1277. //
  1278. // Parameters:
  1279. // Returns:
  1280. // FALSE if successful
  1281. // TRUE if failure
  1282. // Effects:
  1283. // Notes:
  1284. // Revision:
  1285. //---------------------------------------------------------------------------
  1286. ERR FAR PASCAL ErrLpstrToBstrA( LPSTR cstr, BSTR * lpBstr )
  1287. {
  1288. UINT uiLen;
  1289. if ( *lpBstr )
  1290. SysFreeString( *lpBstr );
  1291. uiLen = lstrlen( cstr );
  1292. *lpBstr = SysAllocStringByteLen( cstr, (uiLen) ? uiLen : 0 );
  1293. return (ERR)((*lpBstr) ? FALSE : TRUE);
  1294. }
  1295. //---------------------------------------------------------------------------
  1296. // Name: ErrBinaryToSzEID()
  1297. //
  1298. // Description:
  1299. // Converts binary data to a hexized string.
  1300. //
  1301. // Parameters:
  1302. // Returns:
  1303. // FALSE if success.
  1304. // TRUE if failure.
  1305. //
  1306. // Effects:
  1307. // Notes:
  1308. // Revision:
  1309. //---------------------------------------------------------------------------
  1310. ERR ErrBinaryToSzEID( LPVOID lpvEID, ULONG cbEID, LPSTR * lppstrEID )
  1311. {
  1312. ERR Err = FALSE;
  1313. ULONG cbStr;
  1314. cbStr = CchOfEncoding( cbEID );
  1315. if (!MemAlloc((LPVOID*)lppstrEID, cbStr))
  1316. {
  1317. Err = TRUE;
  1318. goto exit;
  1319. }
  1320. EncodeID( (LPBYTE)lpvEID, cbEID, *lppstrEID );
  1321. exit:
  1322. return Err;
  1323. }
  1324. /*
  1325. * Given the size of a binary string, returns the size of its
  1326. * ASCII encoding.
  1327. */
  1328. STDAPI_(ULONG) CchOfEncoding(ULONG cbBinary)
  1329. {
  1330. return
  1331. (cbBinary / 3) * 4 // 3 bytes -> 4 characters
  1332. + rgLeft[cbBinary % 3] // Leftover bytes -> N characters
  1333. + ((cbBinary / 45) + 1) // overhead: 1 byte per line
  1334. + 1; // null
  1335. }
  1336. /*
  1337. - EncodeID
  1338. -
  1339. * Purpose:
  1340. * Turns a byte string into a character string, using the
  1341. * uuencode algorithm.
  1342. *
  1343. * Three bytes are mapped into 6 bits each of 4 characters, in
  1344. * the range 0x21 - 0x60. The encoding is broken up into lines
  1345. * of 60 characters or less. Each line begins with a count
  1346. * byte (which specifies the number of bytes encoded, not
  1347. * characters) and ends with a CRLF pair.
  1348. *
  1349. * Note that this encoding is sub-optimal for UNICODE: the
  1350. * characters used still fall into the 7-bit ASCII range.
  1351. *
  1352. * Arguments:
  1353. * pb in the byte string to encode
  1354. * cb in length of the input string
  1355. * sz out the encoded character string. No
  1356. * length checking is performed on the
  1357. * output.
  1358. *
  1359. */
  1360. STDAPI_(void) EncodeID(LPBYTE pb, ULONG cb, LPTSTR sz)
  1361. {
  1362. int cbLine;
  1363. int ib;
  1364. BYTE b;
  1365. #ifdef DEBUG
  1366. LPTSTR szBase = sz;
  1367. ULONG cchTot = CchOfEncoding(cb);
  1368. #endif
  1369. AssertSz(!IsBadReadPtr(pb, (UINT) cb), "EncodeID: pb fails address check");
  1370. AssertSz(!IsBadWritePtr(sz, (UINT) cchTot), "EncodeID: sz fails address check");
  1371. while (cb)
  1372. {
  1373. cbLine = min(45, (int)cb);
  1374. Assert(sz < szBase + cchTot);
  1375. *sz++ = ENC(cbLine);
  1376. for (ib = 0; ib < cbLine; ++ib)
  1377. {
  1378. Assert(sz < szBase + cchTot);
  1379. b = 0;
  1380. switch (ib % 3)
  1381. {
  1382. case 0:
  1383. *sz++ = ENC(*pb >> 2);
  1384. if (ib+1 < cbLine)
  1385. b = (BYTE) ((pb[1] >> 4) & 0x0f);
  1386. *sz++ = ENC((*pb << 4) & 0x30 | b);
  1387. break;
  1388. case 1:
  1389. if (ib+1 < cbLine)
  1390. b = (BYTE) ((pb[1] >> 6) & 0x03);
  1391. *sz++ = ENC((*pb << 2) & 0x3c | b);
  1392. break;
  1393. case 2:
  1394. *sz++ = ENC(*pb & 0x3f);
  1395. break;
  1396. }
  1397. pb++;
  1398. }
  1399. cb -= cbLine;
  1400. Assert(cb == 0 || sz + 1 < szBase + cchTot);
  1401. }
  1402. Assert(sz + 1 == szBase + cchTot);
  1403. *sz = 0;
  1404. }
  1405. //---------------------------------------------------------------------------
  1406. // Name: ErrLpstrToBstr()
  1407. //
  1408. // Description:
  1409. // Copies and converts a C string to an OLE BSTR. This
  1410. // routine will convert MultiByte to WideChar.
  1411. // Parameters:
  1412. // Returns:
  1413. // FALSE if successful
  1414. // TRUE if failure
  1415. //
  1416. // Effects:
  1417. // Notes:
  1418. // SysReallocString returns FALSE if memory failure.
  1419. // Revision:
  1420. //---------------------------------------------------------------------------
  1421. ERR FAR PASCAL ErrLpstrToBstr( LPSTR cstr, BSTR * lpBstr )
  1422. {
  1423. OLECHAR * lpszWC = NULL;
  1424. INT cch = 0;
  1425. ERR Err = FALSE;
  1426. if ( !cstr )
  1427. {
  1428. *lpBstr = NULL;
  1429. return FALSE;
  1430. }
  1431. cch = lstrlen( cstr );
  1432. if (!MemAlloc((LPVOID*)&lpszWC, (cch + 1) * sizeof(OLECHAR)))
  1433. return TRUE ;
  1434. // convert ANSI to WideChar
  1435. if ( !MultiByteToWideChar( GetACP(), 0, cstr, -1, lpszWC, cch + 1 ) )
  1436. {
  1437. Err = TRUE;
  1438. goto exit;
  1439. }
  1440. if ( *lpBstr )
  1441. {
  1442. Err = (ERR)!SysReAllocString( lpBstr, lpszWC );
  1443. if ( Err )
  1444. goto exit;
  1445. }
  1446. else
  1447. {
  1448. *lpBstr = SysAllocString( lpszWC );
  1449. if ( !*lpBstr )
  1450. {
  1451. Err = TRUE;
  1452. goto exit;
  1453. }
  1454. }
  1455. exit:
  1456. SafeMemFree(lpszWC);
  1457. return Err;
  1458. }