1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 #pragma warning(disable : 4996)  // MAPILogoff is deprecated
6 
7 #include <windows.h>
8 #include <mapidefs.h>
9 #include <mapi.h>
10 #include "msgMapi.h"
11 
12 // Ensure that our COM structs match MS MAPI structs - thoroughly check each
13 // struct layout This needs that MAPI.h is not used from
14 // https://www.microsoft.com/en-us/download/details.aspx?id=12905 because the
15 // newer MAPI.h is the part of Windows SDK, and it includes MapiFileDescW and
16 // friends.
17 
18 static_assert(sizeof(nsMapiFileDesc) == sizeof(MapiFileDesc), "Size mismatch!");
19 static_assert(offsetof(nsMapiFileDesc, ulReserved) ==
20                   offsetof(MapiFileDesc, ulReserved),
21               "Member offset mismatch!");
22 static_assert(offsetof(nsMapiFileDesc, flFlags) ==
23                   offsetof(MapiFileDesc, flFlags),
24               "Member offset mismatch!");
25 static_assert(offsetof(nsMapiFileDesc, nPosition_NotUsed) ==
26                   offsetof(MapiFileDesc, nPosition),
27               "Member offset mismatch!");
28 static_assert(offsetof(nsMapiFileDesc, lpszPathName) ==
29                   offsetof(MapiFileDesc, lpszPathName),
30               "Member offset mismatch!");
31 static_assert(offsetof(nsMapiFileDesc, lpszFileName) ==
32                   offsetof(MapiFileDesc, lpszFileName),
33               "Member offset mismatch!");
34 static_assert(offsetof(nsMapiFileDesc, lpFileType_NotUsed) ==
35                   offsetof(MapiFileDesc, lpFileType),
36               "Member offset mismatch!");
37 
38 static_assert(sizeof(nsMapiRecipDesc) == sizeof(MapiRecipDesc),
39               "Size mismatch!");
40 static_assert(offsetof(nsMapiRecipDesc, ulReserved) ==
41                   offsetof(MapiRecipDesc, ulReserved),
42               "Member offset mismatch!");
43 static_assert(offsetof(nsMapiRecipDesc, ulRecipClass) ==
44                   offsetof(MapiRecipDesc, ulRecipClass),
45               "Member offset mismatch!");
46 static_assert(offsetof(nsMapiRecipDesc, lpszName) ==
47                   offsetof(MapiRecipDesc, lpszName),
48               "Member offset mismatch!");
49 static_assert(offsetof(nsMapiRecipDesc, lpszAddress) ==
50                   offsetof(MapiRecipDesc, lpszAddress),
51               "Member offset mismatch!");
52 static_assert(offsetof(nsMapiRecipDesc, ulEIDSize_NotUsed) ==
53                   offsetof(MapiRecipDesc, ulEIDSize),
54               "Member offset mismatch!");
55 static_assert(offsetof(nsMapiRecipDesc, lpEntryID_NotUsed) ==
56                   offsetof(MapiRecipDesc, lpEntryID),
57               "Member offset mismatch!");
58 
59 static_assert(sizeof(nsMapiMessage) == sizeof(MapiMessage), "Size mismatch!");
60 static_assert(offsetof(nsMapiMessage, ulReserved) ==
61                   offsetof(MapiMessage, ulReserved),
62               "Member offset mismatch!");
63 static_assert(offsetof(nsMapiMessage, lpszSubject) ==
64                   offsetof(MapiMessage, lpszSubject),
65               "Member offset mismatch!");
66 static_assert(offsetof(nsMapiMessage, lpszNoteText) ==
67                   offsetof(MapiMessage, lpszNoteText),
68               "Member offset mismatch!");
69 static_assert(offsetof(nsMapiMessage, lpszMessageType) ==
70                   offsetof(MapiMessage, lpszMessageType),
71               "Member offset mismatch!");
72 static_assert(offsetof(nsMapiMessage, lpszDateReceived) ==
73                   offsetof(MapiMessage, lpszDateReceived),
74               "Member offset mismatch!");
75 static_assert(offsetof(nsMapiMessage, lpszConversationID_NotUsed) ==
76                   offsetof(MapiMessage, lpszConversationID),
77               "Member offset mismatch!");
78 static_assert(offsetof(nsMapiMessage, flFlags) ==
79                   offsetof(MapiMessage, flFlags),
80               "Member offset mismatch!");
81 static_assert(offsetof(nsMapiMessage, lpOriginator) ==
82                   offsetof(MapiMessage, lpOriginator),
83               "Member offset mismatch!");
84 static_assert(offsetof(nsMapiMessage, nRecipCount) ==
85                   offsetof(MapiMessage, nRecipCount),
86               "Member offset mismatch!");
87 static_assert(offsetof(nsMapiMessage, lpRecips) ==
88                   offsetof(MapiMessage, lpRecips),
89               "Member offset mismatch!");
90 static_assert(offsetof(nsMapiMessage, nFileCount) ==
91                   offsetof(MapiMessage, nFileCount),
92               "Member offset mismatch!");
93 static_assert(offsetof(nsMapiMessage, lpFiles) ==
94                   offsetof(MapiMessage, lpFiles),
95               "Member offset mismatch!");
96 
97 static_assert(sizeof(nsMapiFileDescW) == sizeof(MapiFileDescW),
98               "Size mismatch!");
99 static_assert(offsetof(nsMapiFileDescW, ulReserved) ==
100                   offsetof(MapiFileDescW, ulReserved),
101               "Member offset mismatch!");
102 static_assert(offsetof(nsMapiFileDescW, flFlags) ==
103                   offsetof(MapiFileDescW, flFlags),
104               "Member offset mismatch!");
105 static_assert(offsetof(nsMapiFileDescW, nPosition_NotUsed) ==
106                   offsetof(MapiFileDescW, nPosition),
107               "Member offset mismatch!");
108 static_assert(offsetof(nsMapiFileDescW, lpszPathName) ==
109                   offsetof(MapiFileDescW, lpszPathName),
110               "Member offset mismatch!");
111 static_assert(offsetof(nsMapiFileDescW, lpszFileName) ==
112                   offsetof(MapiFileDescW, lpszFileName),
113               "Member offset mismatch!");
114 static_assert(offsetof(nsMapiFileDescW, lpFileType_NotUsed) ==
115                   offsetof(MapiFileDescW, lpFileType),
116               "Member offset mismatch!");
117 
118 static_assert(sizeof(nsMapiRecipDescW) == sizeof(MapiRecipDescW),
119               "Size mismatch!");
120 static_assert(offsetof(nsMapiRecipDescW, ulReserved) ==
121                   offsetof(MapiRecipDescW, ulReserved),
122               "Member offset mismatch!");
123 static_assert(offsetof(nsMapiRecipDescW, ulRecipClass) ==
124                   offsetof(MapiRecipDescW, ulRecipClass),
125               "Member offset mismatch!");
126 static_assert(offsetof(nsMapiRecipDescW, lpszName) ==
127                   offsetof(MapiRecipDescW, lpszName),
128               "Member offset mismatch!");
129 static_assert(offsetof(nsMapiRecipDescW, lpszAddress) ==
130                   offsetof(MapiRecipDescW, lpszAddress),
131               "Member offset mismatch!");
132 static_assert(offsetof(nsMapiRecipDescW, ulEIDSize_NotUsed) ==
133                   offsetof(MapiRecipDescW, ulEIDSize),
134               "Member offset mismatch!");
135 static_assert(offsetof(nsMapiRecipDescW, lpEntryID_NotUsed) ==
136                   offsetof(MapiRecipDescW, lpEntryID),
137               "Member offset mismatch!");
138 
139 static_assert(sizeof(nsMapiMessageW) == sizeof(MapiMessageW), "Size mismatch!");
140 static_assert(offsetof(nsMapiMessageW, ulReserved) ==
141                   offsetof(MapiMessageW, ulReserved),
142               "Member offset mismatch!");
143 static_assert(offsetof(nsMapiMessageW, lpszSubject) ==
144                   offsetof(MapiMessageW, lpszSubject),
145               "Member offset mismatch!");
146 static_assert(offsetof(nsMapiMessageW, ulReserved) ==
147                   offsetof(MapiMessageW, ulReserved),
148               "Member offset mismatch!");
149 static_assert(offsetof(nsMapiMessageW, lpszSubject) ==
150                   offsetof(MapiMessageW, lpszSubject),
151               "Member offset mismatch!");
152 static_assert(offsetof(nsMapiMessageW, lpszNoteText) ==
153                   offsetof(MapiMessageW, lpszNoteText),
154               "Member offset mismatch!");
155 static_assert(offsetof(nsMapiMessageW, lpszMessageType) ==
156                   offsetof(MapiMessageW, lpszMessageType),
157               "Member offset mismatch!");
158 static_assert(offsetof(nsMapiMessageW, lpszDateReceived) ==
159                   offsetof(MapiMessageW, lpszDateReceived),
160               "Member offset mismatch!");
161 static_assert(offsetof(nsMapiMessageW, lpszConversationID_NotUsed) ==
162                   offsetof(MapiMessageW, lpszConversationID),
163               "Member offset mismatch!");
164 static_assert(offsetof(nsMapiMessageW, flFlags) ==
165                   offsetof(MapiMessageW, flFlags),
166               "Member offset mismatch!");
167 static_assert(offsetof(nsMapiMessageW, lpOriginator) ==
168                   offsetof(MapiMessageW, lpOriginator),
169               "Member offset mismatch!");
170 static_assert(offsetof(nsMapiMessageW, nRecipCount) ==
171                   offsetof(MapiMessageW, nRecipCount),
172               "Member offset mismatch!");
173 static_assert(offsetof(nsMapiMessageW, lpRecips) ==
174                   offsetof(MapiMessageW, lpRecips),
175               "Member offset mismatch!");
176 static_assert(offsetof(nsMapiMessageW, nFileCount) ==
177                   offsetof(MapiMessageW, nFileCount),
178               "Member offset mismatch!");
179 static_assert(offsetof(nsMapiMessageW, lpFiles) ==
180                   offsetof(MapiMessageW, lpFiles),
181               "Member offset mismatch!");
182 
183 #define MAX_RECIPS 2000
184 #define MAX_FILES 100
185 
186 #define MAX_NAME_LEN 256
187 #define MAX_PW_LEN 256
188 #define MAX_MSGINFO_LEN 512
189 #define MAX_POINTERS 32
190 
191 const CLSID CLSID_CMapiImp = {0x29f458be,
192                               0x8866,
193                               0x11d5,
194                               {0xa3, 0xdd, 0x0, 0xb0, 0xd0, 0xf3, 0xba, 0xa7}};
195 const IID IID_nsIMapi = {0x6EDCD38E,
196                          0x8861,
197                          0x11d5,
198                          {0xA3, 0xDD, 0x00, 0xB0, 0xD0, 0xF3, 0xBA, 0xA7}};
199 
200 DWORD tId = 0;
201 
202 #define MAPI_MESSAGE_TYPE 0
203 #define MAPI_RECIPIENT_TYPE 1
204 
205 typedef struct {
206   LPVOID lpMem;
207   UCHAR memType;
208 } memTrackerType;
209 
210 // this can't be right.
211 memTrackerType memArray[MAX_POINTERS];
212 
213 //
214 // For remembering memory...how ironic.
215 //
SetPointerArray(LPVOID ptr,BYTE type)216 void SetPointerArray(LPVOID ptr, BYTE type) {
217   int i;
218 
219   for (i = 0; i < MAX_POINTERS; i++) {
220     if (memArray[i].lpMem == NULL) {
221       memArray[i].lpMem = ptr;
222       memArray[i].memType = type;
223       break;
224     }
225   }
226 }
227 
DllMain(HINSTANCE aInstance,DWORD aReason,LPVOID aReserved)228 BOOL WINAPI DllMain(HINSTANCE aInstance, DWORD aReason, LPVOID aReserved) {
229   switch (aReason) {
230     case DLL_PROCESS_ATTACH:
231       tId = TlsAlloc();
232       if (tId == 0xFFFFFFFF) return FALSE;
233       break;
234 
235     case DLL_PROCESS_DETACH:
236       TlsFree(tId);
237       break;
238   }
239   return TRUE;
240 }
241 
InitMozillaReference(nsIMapi ** aRetValue)242 BOOL InitMozillaReference(nsIMapi** aRetValue) {
243   // Check whether this thread has a valid Interface
244   // by looking into thread-specific-data variable
245 
246   *aRetValue = (nsIMapi*)TlsGetValue(tId);
247 
248   // Check whether the pointer actually resolves to
249   // a valid method call; otherwise mozilla is not running
250 
251   if ((*aRetValue) && (*aRetValue)->IsValid() == S_OK) return TRUE;
252 
253   HRESULT hRes = ::CoInitialize(NULL);
254 
255   hRes = ::CoCreateInstance(CLSID_CMapiImp, NULL, CLSCTX_LOCAL_SERVER,
256                             IID_nsIMapi, (LPVOID*)aRetValue);
257 
258   if (hRes == S_OK && (*aRetValue)->Initialize() == S_OK)
259     if (TlsSetValue(tId, (LPVOID)(*aRetValue))) return TRUE;
260 
261   // Either CoCreate or TlsSetValue failed; so return FALSE
262 
263   if ((*aRetValue)) (*aRetValue)->Release();
264 
265   ::CoUninitialize();
266   return FALSE;
267 }
268 
269 /////////////////////////////////////////////////////////////////////////////
270 // The MAPILogon function begins a Simple MAPI session, loading the default
271 // message store and address book providers
272 /////////////////////////////////////////////////////////////////////////////
273 
MAPILogon(ULONG aUIParam,LPSTR aProfileName,LPSTR aPassword,FLAGS aFlags,ULONG aReserved,LPLHANDLE aSession)274 ULONG FAR PASCAL MAPILogon(ULONG aUIParam, LPSTR aProfileName, LPSTR aPassword,
275                            FLAGS aFlags, ULONG aReserved, LPLHANDLE aSession) {
276   HRESULT hr = 0;
277   ULONG nSessionId = 0;
278   nsIMapi* pNsMapi = NULL;
279 
280   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
281 
282   hr = pNsMapi->Login(aUIParam, aProfileName, aPassword, aFlags, &nSessionId);
283   if (hr == S_OK)
284     (*aSession) = (LHANDLE)nSessionId;
285   else
286     return nSessionId;
287 
288   return SUCCESS_SUCCESS;
289 }
290 
MAPILogoff(LHANDLE aSession,ULONG aUIParam,FLAGS aFlags,ULONG aReserved)291 ULONG FAR PASCAL MAPILogoff(LHANDLE aSession, ULONG aUIParam, FLAGS aFlags,
292                             ULONG aReserved) {
293   nsIMapi* pNsMapi = (nsIMapi*)TlsGetValue(tId);
294   if (pNsMapi != NULL) {
295     if (pNsMapi->Logoff((ULONG)aSession) == S_OK) pNsMapi->Release();
296     pNsMapi = NULL;
297   }
298 
299   TlsSetValue(tId, NULL);
300 
301   ::CoUninitialize();
302 
303   return SUCCESS_SUCCESS;
304 }
305 
MAPISendMail(LHANDLE lhSession,ULONG ulUIParam,nsMapiMessage * lpMessage,FLAGS flFlags,ULONG ulReserved)306 ULONG FAR PASCAL MAPISendMail(LHANDLE lhSession, ULONG ulUIParam,
307                               nsMapiMessage* lpMessage, FLAGS flFlags,
308                               ULONG ulReserved) {
309   HRESULT hr = 0;
310   BOOL bTempSession = FALSE;
311   nsIMapi* pNsMapi = NULL;
312 
313   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
314 
315   if (lpMessage->nRecipCount > MAX_RECIPS) return MAPI_E_TOO_MANY_RECIPIENTS;
316 
317   if (lpMessage->nFileCount > MAX_FILES) return MAPI_E_TOO_MANY_FILES;
318 
319   if ((!(flFlags & MAPI_DIALOG)) && (lpMessage->lpRecips == NULL))
320     return MAPI_E_UNKNOWN_RECIPIENT;
321 
322   if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK) {
323     FLAGS LoginFlag = flFlags & (MAPI_LOGON_UI | MAPI_NEW_SESSION);
324     hr = MAPILogon(ulUIParam, nullptr, nullptr, LoginFlag, 0, &lhSession);
325     if (hr != SUCCESS_SUCCESS) return MAPI_E_LOGIN_FAILURE;
326     bTempSession = TRUE;
327   }
328 
329   hr = pNsMapi->SendMail(lhSession, lpMessage, flFlags, ulReserved);
330 
331   // we are seeing a problem when using Word, although we return success from
332   // the MAPI support MS COM interface in mozilla, we are getting this error
333   // here. This is a temporary hack !!
334   if (hr == 0x800703e6) hr = SUCCESS_SUCCESS;
335 
336   if (bTempSession) MAPILogoff(lhSession, ulUIParam, 0, 0);
337 
338   return hr;
339 }
340 
MAPISendMailW(LHANDLE lhSession,ULONG ulUIParam,nsMapiMessageW * lpMessage,FLAGS flFlags,ULONG ulReserved)341 ULONG FAR PASCAL MAPISendMailW(LHANDLE lhSession, ULONG ulUIParam,
342                                nsMapiMessageW* lpMessage, FLAGS flFlags,
343                                ULONG ulReserved) {
344   HRESULT hr = 0;
345   BOOL bTempSession = FALSE;
346   nsIMapi* pNsMapi = nullptr;
347 
348   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
349 
350   if (lpMessage->nRecipCount > MAX_RECIPS) return MAPI_E_TOO_MANY_RECIPIENTS;
351 
352   if (lpMessage->nFileCount > MAX_FILES) return MAPI_E_TOO_MANY_FILES;
353 
354   if ((!(flFlags & MAPI_DIALOG)) && (lpMessage->lpRecips == nullptr))
355     return MAPI_E_UNKNOWN_RECIPIENT;
356 
357   if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK) {
358     FLAGS LoginFlag = flFlags & (MAPI_LOGON_UI | MAPI_NEW_SESSION);
359     hr = MAPILogon(ulUIParam, nullptr, nullptr, LoginFlag, 0, &lhSession);
360     if (hr != SUCCESS_SUCCESS) return MAPI_E_LOGIN_FAILURE;
361     bTempSession = TRUE;
362   }
363 
364   hr = pNsMapi->SendMailW(lhSession, lpMessage, flFlags, ulReserved);
365 
366   // we are seeing a problem when using Word, although we return success from
367   // the MAPI support MS COM interface in mozilla, we are getting this error
368   // here. This is a temporary hack !!
369   if (hr == 0x800703e6) hr = SUCCESS_SUCCESS;
370 
371   if (bTempSession) MAPILogoff(lhSession, ulUIParam, 0, 0);
372 
373   return hr;
374 }
375 
MAPISendDocuments(ULONG ulUIParam,LPSTR lpszDelimChar,LPSTR lpszFilePaths,LPSTR lpszFileNames,ULONG ulReserved)376 ULONG FAR PASCAL MAPISendDocuments(ULONG ulUIParam, LPSTR lpszDelimChar,
377                                    LPSTR lpszFilePaths, LPSTR lpszFileNames,
378                                    ULONG ulReserved) {
379   LHANDLE lhSession;
380   nsIMapi* pNsMapi = NULL;
381 
382   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
383 
384   unsigned long result =
385       MAPILogon(ulUIParam, nullptr, nullptr, MAPI_LOGON_UI, 0, &lhSession);
386   if (result != SUCCESS_SUCCESS) return MAPI_E_LOGIN_FAILURE;
387 
388   HRESULT hr;
389 
390   hr = pNsMapi->SendDocuments(lhSession, lpszDelimChar, lpszFilePaths,
391                               lpszFileNames, ulReserved);
392 
393   MAPILogoff(lhSession, ulUIParam, 0, 0);
394 
395   return hr;
396 }
397 
MAPIFindNext(LHANDLE lhSession,ULONG ulUIParam,const LPSTR lpszMessageType,const LPSTR lpszSeedMessageID,FLAGS flFlags,ULONG ulReserved,unsigned char lpszMessageID[64])398 ULONG FAR PASCAL MAPIFindNext(LHANDLE lhSession, ULONG ulUIParam,
399                               const LPSTR lpszMessageType,
400                               const LPSTR lpszSeedMessageID, FLAGS flFlags,
401                               ULONG ulReserved,
402                               unsigned char lpszMessageID[64]) {
403   nsIMapi* pNsMapi = NULL;
404 
405   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
406 
407   if (lhSession == 0) return MAPI_E_INVALID_SESSION;
408 
409   return pNsMapi->FindNext(lhSession, ulUIParam, lpszMessageType,
410                            lpszSeedMessageID, flFlags, ulReserved,
411                            lpszMessageID);
412 }
413 
MAPIReadMail(LHANDLE lhSession,ULONG ulUIParam,LPSTR lpszMessageID,FLAGS flFlags,ULONG ulReserved,nsMapiMessage ** lppMessage)414 ULONG FAR PASCAL MAPIReadMail(LHANDLE lhSession, ULONG ulUIParam,
415                               LPSTR lpszMessageID, FLAGS flFlags,
416                               ULONG ulReserved, nsMapiMessage** lppMessage) {
417   nsIMapi* pNsMapi = NULL;
418 
419   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
420 
421   if (lhSession == 0) return MAPI_E_INVALID_SESSION;
422 
423   return pNsMapi->ReadMail(lhSession, ulUIParam, lpszMessageID, flFlags,
424                            ulReserved, lppMessage);
425 }
426 
MAPISaveMail(LHANDLE lhSession,ULONG ulUIParam,lpnsMapiMessage lpMessage,FLAGS flFlags,ULONG ulReserved,LPSTR lpszMessageID)427 ULONG FAR PASCAL MAPISaveMail(LHANDLE lhSession, ULONG ulUIParam,
428                               lpnsMapiMessage lpMessage, FLAGS flFlags,
429                               ULONG ulReserved, LPSTR lpszMessageID) {
430   nsIMapi* pNsMapi = NULL;
431 
432   if (lhSession == 0) return MAPI_E_INVALID_SESSION;
433 
434   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
435 
436   return MAPI_E_FAILURE;
437 }
438 
MAPIDeleteMail(LHANDLE lhSession,ULONG ulUIParam,LPSTR lpszMessageID,FLAGS flFlags,ULONG ulReserved)439 ULONG FAR PASCAL MAPIDeleteMail(LHANDLE lhSession, ULONG ulUIParam,
440                                 LPSTR lpszMessageID, FLAGS flFlags,
441                                 ULONG ulReserved) {
442   nsIMapi* pNsMapi = NULL;
443 
444   if (lhSession == 0) return MAPI_E_INVALID_SESSION;
445 
446   if (!InitMozillaReference(&pNsMapi)) return MAPI_E_FAILURE;
447 
448   return pNsMapi->DeleteMail(lhSession, ulUIParam, lpszMessageID, flFlags,
449                              ulReserved);
450 }
451 
MAPIAddress(LHANDLE lhSession,ULONG ulUIParam,LPSTR lpszCaption,ULONG nEditFields,LPSTR lpszLabels,ULONG nRecips,lpMapiRecipDesc lpRecips,FLAGS flFlags,ULONG ulReserved,LPULONG lpnNewRecips,lpMapiRecipDesc FAR * lppNewRecips)452 ULONG FAR PASCAL MAPIAddress(LHANDLE lhSession, ULONG ulUIParam,
453                              LPSTR lpszCaption, ULONG nEditFields,
454                              LPSTR lpszLabels, ULONG nRecips,
455                              lpMapiRecipDesc lpRecips, FLAGS flFlags,
456                              ULONG ulReserved, LPULONG lpnNewRecips,
457                              lpMapiRecipDesc FAR* lppNewRecips) {
458   return MAPI_E_NOT_SUPPORTED;
459 }
460 
MAPIDetails(LHANDLE lhSession,ULONG ulUIParam,lpMapiRecipDesc lpRecip,FLAGS flFlags,ULONG ulReserved)461 ULONG FAR PASCAL MAPIDetails(LHANDLE lhSession, ULONG ulUIParam,
462                              lpMapiRecipDesc lpRecip, FLAGS flFlags,
463                              ULONG ulReserved) {
464   return MAPI_E_NOT_SUPPORTED;
465 }
466 
MAPIResolveName(LHANDLE lhSession,ULONG ulUIParam,LPSTR lpszName,FLAGS flFlags,ULONG ulReserved,lpMapiRecipDesc FAR * lppRecip)467 ULONG FAR PASCAL MAPIResolveName(LHANDLE lhSession, ULONG ulUIParam,
468                                  LPSTR lpszName, FLAGS flFlags,
469                                  ULONG ulReserved,
470                                  lpMapiRecipDesc FAR* lppRecip) {
471   char* lpszRecipName = new char[(strlen((const char*)lpszName) + 1)];
472   if (lpszRecipName == NULL) return MAPI_E_INSUFFICIENT_MEMORY;
473   char* lpszRecipAddress = new char[(strlen((const char*)lpszName) + 6)];
474   if (!lpszRecipAddress) {
475     delete[] lpszRecipName;
476     return MAPI_E_INSUFFICIENT_MEMORY;
477   }
478   strcpy(lpszRecipName, (const char*)lpszName);
479   strcpy(lpszRecipAddress, (const char*)lpszName);
480   (*lppRecip) = (lpMapiRecipDesc FAR)malloc(sizeof(MapiRecipDesc));
481   if (!(*lppRecip)) {
482     delete[] lpszRecipName;
483     delete[] lpszRecipAddress;
484     return MAPI_E_INSUFFICIENT_MEMORY;
485   }
486   (*lppRecip)->ulRecipClass = 1;
487   (*lppRecip)->lpszName = lpszRecipName;
488   (*lppRecip)->lpszAddress = lpszRecipAddress;
489   (*lppRecip)->ulEIDSize = 0;
490   (*lppRecip)->lpEntryID = 0;
491   return SUCCESS_SUCCESS;
492 }
493 
494 void FreeMAPIRecipient(lpMapiRecipDesc pv);
495 void FreeMAPIMessage(lpMapiMessage pv);
496 
MAPIFreeBuffer(LPVOID pv)497 ULONG FAR PASCAL MAPIFreeBuffer(LPVOID pv) {
498   int i;
499 
500   if (!pv) return S_OK;
501 
502   for (i = 0; i < MAX_POINTERS; i++) {
503     if (pv == memArray[i].lpMem) {
504       if (memArray[i].memType == MAPI_MESSAGE_TYPE) {
505         FreeMAPIMessage((MapiMessage*)pv);
506         memArray[i].lpMem = NULL;
507       } else if (memArray[i].memType == MAPI_RECIPIENT_TYPE) {
508         FreeMAPIRecipient((MapiRecipDesc*)pv);
509         memArray[i].lpMem = NULL;
510       }
511     }
512   }
513 
514   pv = NULL;
515   return S_OK;
516 }
517 
GetMapiDllVersion()518 ULONG FAR PASCAL GetMapiDllVersion() { return 94; }
519 
FreeMAPIFile(lpMapiFileDesc pv)520 void FreeMAPIFile(lpMapiFileDesc pv) {
521   if (!pv) return;
522 
523   if (pv->lpszPathName != NULL) free(pv->lpszPathName);
524 
525   if (pv->lpszFileName != NULL) free(pv->lpszFileName);
526 }
527 
FreeMAPIMessage(lpMapiMessage pv)528 void FreeMAPIMessage(lpMapiMessage pv) {
529   ULONG i;
530 
531   if (!pv) return;
532 
533   if (pv->lpszSubject != NULL) free(pv->lpszSubject);
534 
535   if (pv->lpszNoteText) free(pv->lpszNoteText);
536 
537   if (pv->lpszMessageType) free(pv->lpszMessageType);
538 
539   if (pv->lpszDateReceived) free(pv->lpszDateReceived);
540 
541   if (pv->lpszConversationID) free(pv->lpszConversationID);
542 
543   if (pv->lpOriginator) FreeMAPIRecipient(pv->lpOriginator);
544 
545   for (i = 0; i < pv->nRecipCount; i++) {
546     if (&(pv->lpRecips[i]) != NULL) {
547       FreeMAPIRecipient(&(pv->lpRecips[i]));
548     }
549   }
550 
551   if (pv->lpRecips != NULL) {
552     free(pv->lpRecips);
553   }
554 
555   for (i = 0; i < pv->nFileCount; i++) {
556     if (&(pv->lpFiles[i]) != NULL) {
557       FreeMAPIFile(&(pv->lpFiles[i]));
558     }
559   }
560 
561   if (pv->lpFiles != NULL) {
562     free(pv->lpFiles);
563   }
564 
565   free(pv);
566   pv = NULL;
567 }
568 
FreeMAPIRecipient(lpMapiRecipDesc pv)569 void FreeMAPIRecipient(lpMapiRecipDesc pv) {
570   if (!pv) return;
571 
572   if (pv->lpszName != NULL) free(pv->lpszName);
573 
574   if (pv->lpszAddress != NULL) free(pv->lpszAddress);
575 
576   if (pv->lpEntryID != NULL) free(pv->lpEntryID);
577 }
578