Back to index

lightning-sunbird  0.9+nobinonly
MapiDll.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is Mozilla
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corp.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *           Krishna Mohan Khandrika (kkhandrika@netscape.com)
00023  *           Rajiv Dayal (rdayal@netscape.com)
00024  *           David Bienvenu <bienvenu@nventure.com>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either the GNU General Public License Version 2 or later (the "GPL"), or
00028  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include <windows.h>
00041 #include <tchar.h>
00042 #include <mapidefs.h>
00043 #include <mapi.h>
00044 #include "msgMapi.h"
00045 #include "msgMapiMain.h"
00046 
00047 #define MAX_RECIPS  100
00048 #define MAX_FILES   100
00049 
00050 
00051 #define           MAX_NAME_LEN    256
00052 #define           MAX_PW_LEN      256
00053 #define           MAX_MSGINFO_LEN 512
00054 #define           MAX_POINTERS    32
00055 
00056 const CLSID CLSID_CMapiImp = {0x29f458be, 0x8866, 0x11d5,
00057                               {0xa3, 0xdd, 0x0, 0xb0, 0xd0, 0xf3, 0xba, 0xa7}};
00058 const IID IID_nsIMapi = {0x6EDCD38E,0x8861,0x11d5,
00059                         {0xA3,0xDD,0x00,0xB0,0xD0,0xF3,0xBA,0xA7}};
00060 
00061 DWORD tId = 0;
00062 
00063 #define   MAPI_MESSAGE_TYPE     0
00064 #define   MAPI_RECIPIENT_TYPE   1
00065  
00066 typedef struct {
00067   LPVOID    lpMem;
00068   UCHAR     memType;
00069 } memTrackerType;
00070 
00071 
00072 // this can't be right.
00073 memTrackerType    memArray[MAX_POINTERS];
00074 
00075 //
00076 // For remembering memory...how ironic.
00077 //
00078 void
00079 SetPointerArray(LPVOID ptr, BYTE type)
00080 {
00081 int i;
00082   
00083   for (i=0; i<MAX_POINTERS; i++)
00084   {
00085     if (memArray[i].lpMem == NULL)
00086     {
00087       memArray[i].lpMem = ptr;
00088       memArray[i].memType = type;
00089       break;
00090     }
00091   }
00092 }
00093 
00094 
00095 BOOL WINAPI DllMain(HINSTANCE aInstance, DWORD aReason, LPVOID aReserved)
00096 {
00097     switch (aReason)
00098     {
00099         case DLL_PROCESS_ATTACH : tId = TlsAlloc();
00100                                   if (tId == 0xFFFFFFFF)
00101                                       return FALSE;
00102                                   break;
00103 
00104         case DLL_PROCESS_DETACH : TlsFree(tId);
00105                                   break;
00106     }
00107     return TRUE;
00108 }
00109 
00110 BOOL InitMozillaReference(nsIMapi **aRetValue)
00111 {
00112     // Check whether this thread has a valid Interface
00113     // by looking into thread-specific-data variable
00114 
00115     *aRetValue = (nsIMapi *)TlsGetValue(tId);
00116 
00117     // Check whether the pointer actually resolves to
00118     // a valid method call; otherwise mozilla is not running
00119 
00120     if ((*aRetValue) && (*aRetValue)->IsValid() == S_OK)
00121          return TRUE;
00122 
00123     HRESULT hRes = ::CoInitialize(nsnull) ;
00124 
00125     hRes = ::CoCreateInstance(CLSID_CMapiImp, NULL, CLSCTX_LOCAL_SERVER,
00126                                          IID_nsIMapi, (LPVOID *)aRetValue);
00127 
00128     if (hRes == S_OK && (*aRetValue)->Initialize() == S_OK)
00129         if (TlsSetValue(tId, (LPVOID)(*aRetValue)))
00130             return TRUE;
00131 
00132     // Either CoCreate or TlsSetValue failed; so return FALSE
00133 
00134     if ((*aRetValue))
00135         (*aRetValue)->Release();
00136 
00137     ::CoUninitialize();
00138     return FALSE;
00139 }
00140 
00142 // The MAPILogon function begins a Simple MAPI session, loading the default message ////
00143 // store and address book providers                            ////
00145 
00146 ULONG FAR PASCAL MAPILogon(ULONG aUIParam, LPTSTR aProfileName,
00147                             LPTSTR aPassword, FLAGS aFlags,
00148                             ULONG aReserved, LPLHANDLE aSession)
00149 {
00150     HRESULT hr = 0;
00151     ULONG nSessionId = 0;
00152     nsIMapi *pNsMapi = NULL;
00153 
00154     if (!InitMozillaReference(&pNsMapi))
00155         return MAPI_E_FAILURE;
00156 
00157     if (!(aFlags & MAPI_UNICODE))
00158     {
00159         // Need to convert the parameters to Unicode.
00160 
00161         char *pUserName = (char *) aProfileName;
00162         char *pPassWord = (char *) aPassword;
00163 
00164         TCHAR ProfileName[MAX_NAME_LEN] = {0};
00165         TCHAR PassWord[MAX_PW_LEN] = {0};
00166 
00167         if (pUserName != NULL)
00168         {
00169             if (!MultiByteToWideChar(CP_ACP, 0, pUserName, -1, ProfileName,
00170                                                             MAX_NAME_LEN))
00171                 return MAPI_E_FAILURE;
00172         }
00173 
00174         if (pPassWord != NULL)
00175         {
00176             if (!MultiByteToWideChar(CP_ACP, 0, pPassWord, -1, PassWord,
00177                                                             MAX_NAME_LEN))
00178                 return MAPI_E_FAILURE;
00179         }
00180 
00181         hr = pNsMapi->Login(aUIParam, ProfileName, PassWord, aFlags,
00182                                                         &nSessionId);
00183     }
00184     else
00185         hr = pNsMapi->Login(aUIParam, aProfileName, aPassword,
00186                                                 aFlags, &nSessionId);
00187     if (hr == S_OK)
00188         (*aSession) = (LHANDLE) nSessionId;
00189     else
00190         return nSessionId;
00191 
00192     return SUCCESS_SUCCESS;
00193 }
00194 
00195 ULONG FAR PASCAL MAPILogoff (LHANDLE aSession, ULONG aUIParam,
00196                                             FLAGS aFlags, ULONG aReserved)
00197 {
00198     nsIMapi *pNsMapi = (nsIMapi *)TlsGetValue(tId);
00199     if (pNsMapi != NULL)
00200     {
00201         if (pNsMapi->Logoff((ULONG) aSession) == S_OK)
00202             pNsMapi->Release();
00203         pNsMapi = NULL;
00204     }
00205 
00206     TlsSetValue(tId, NULL);
00207 
00208     ::CoUninitialize();
00209 
00210     return SUCCESS_SUCCESS;
00211 }
00212 
00213 ULONG FAR PASCAL MAPISendMail (LHANDLE lhSession, ULONG ulUIParam, nsMapiMessage *lpMessage,
00214                 FLAGS flFlags, ULONG ulReserved )
00215 {
00216     HRESULT hr = 0;
00217     BOOL bTempSession = FALSE ;
00218     nsIMapi *pNsMapi = NULL;
00219 
00220     if (!InitMozillaReference(&pNsMapi))
00221         return MAPI_E_FAILURE;
00222 
00223     if (lpMessage->nRecipCount > MAX_RECIPS)
00224         return MAPI_E_TOO_MANY_RECIPIENTS ;
00225 
00226     if (lpMessage->nFileCount > MAX_FILES)
00227         return MAPI_E_TOO_MANY_FILES ;
00228 
00229     if ( (!(flFlags & MAPI_DIALOG)) && (lpMessage->lpRecips == NULL) )
00230         return MAPI_E_UNKNOWN_RECIPIENT ;
00231 
00232     if (!lhSession || pNsMapi->IsValidSession(lhSession) != S_OK)
00233     {
00234         FLAGS LoginFlag ;
00235         if ( (flFlags & MAPI_LOGON_UI) && (flFlags & MAPI_NEW_SESSION) )
00236             LoginFlag = MAPI_LOGON_UI | MAPI_NEW_SESSION ;
00237         else if (flFlags & MAPI_LOGON_UI) 
00238             LoginFlag = MAPI_LOGON_UI ;
00239 
00240         hr = MAPILogon (ulUIParam, (LPTSTR) NULL, (LPTSTR) NULL, LoginFlag, 0, &lhSession) ;
00241         if (hr != SUCCESS_SUCCESS)
00242             return MAPI_E_LOGIN_FAILURE ;
00243         bTempSession = TRUE ;
00244     }
00245 
00246     // we need to deal with null data passed in by MAPI clients, specially when MAPI_DIALOG is set.
00247     // The MS COM type lib code generated by MIDL for the MS COM interfaces checks for these parameters
00248     // to be non null, although null is a valid value for them here. 
00249     nsMapiRecipDesc * lpRecips ;
00250     nsMapiFileDesc * lpFiles ;
00251 
00252     nsMapiMessage Message ;
00253     memset (&Message, 0, sizeof (nsMapiMessage) ) ;
00254     nsMapiRecipDesc Recipient ;
00255     memset (&Recipient, 0, sizeof (nsMapiRecipDesc) );
00256     nsMapiFileDesc Files ;
00257     memset (&Files, 0, sizeof (nsMapiFileDesc) ) ;
00258 
00259     if(!lpMessage)
00260     {
00261        lpMessage = &Message ;
00262     }
00263     if(!lpMessage->lpRecips)
00264     {
00265         lpRecips = &Recipient ;
00266     }
00267     else
00268         lpRecips = lpMessage->lpRecips ;
00269     if(!lpMessage->lpFiles)
00270     {
00271         lpFiles = &Files ;
00272     }
00273     else
00274         lpFiles = lpMessage->lpFiles ;
00275 
00276     hr = pNsMapi->SendMail (lhSession, lpMessage, 
00277                             (short) lpMessage->nRecipCount, lpRecips,
00278                             (short) lpMessage->nFileCount, lpFiles,
00279                             flFlags, ulReserved);
00280 
00281     // we are seeing a problem when using Word, although we return success from the MAPI support
00282     // MS COM interface in mozilla, we are getting this error here. This is a temporary hack !!
00283     if (hr == 0x800703e6)
00284         hr = SUCCESS_SUCCESS;
00285     
00286     if (bTempSession)
00287         MAPILogoff (lhSession, ulUIParam, 0,0) ;
00288 
00289     return hr ; 
00290 }
00291 
00292 
00293 ULONG FAR PASCAL MAPISendDocuments(ULONG ulUIParam, LPTSTR lpszDelimChar, LPTSTR lpszFilePaths,
00294                                 LPTSTR lpszFileNames, ULONG ulReserved)
00295 {
00296     LHANDLE lhSession ;
00297     nsIMapi *pNsMapi = NULL;
00298 
00299     if (!InitMozillaReference(&pNsMapi))
00300         return MAPI_E_FAILURE;
00301 
00302     unsigned long result = MAPILogon (ulUIParam, (LPTSTR) NULL, (LPTSTR) NULL, MAPI_LOGON_UI, 0, &lhSession) ;
00303     if (result != SUCCESS_SUCCESS)
00304         return MAPI_E_LOGIN_FAILURE ;
00305 
00306     HRESULT hr;
00307 
00308     hr = pNsMapi->SendDocuments(lhSession, (LPTSTR) lpszDelimChar, (LPTSTR) lpszFilePaths, 
00309                                     (LPTSTR) lpszFileNames, ulReserved) ;
00310 
00311     MAPILogoff (lhSession, ulUIParam, 0,0) ;
00312 
00313     return hr ;
00314 }
00315 
00316 ULONG FAR PASCAL MAPIFindNext(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageType,
00317                               LPTSTR lpszSeedMessageID, FLAGS flFlags, ULONG ulReserved,
00318                               unsigned char lpszMessageID[64])
00319 {
00320   nsIMapi *pNsMapi = NULL;
00321 
00322   if (!InitMozillaReference(&pNsMapi))
00323     return MAPI_E_FAILURE;
00324 
00325   if (lhSession == 0)
00326     return(MAPI_E_INVALID_SESSION);
00327 
00328   if (!lpszMessageType)
00329     lpszMessageType = L"";
00330 
00331   if (!lpszSeedMessageID)
00332     lpszSeedMessageID = L"";
00333 
00334   return pNsMapi->FindNext(lhSession, ulUIParam, lpszMessageType,
00335                               lpszSeedMessageID, flFlags, ulReserved,
00336                               lpszMessageID) ;
00337 
00338 
00339 }
00340 
00341 
00342 ULONG FAR PASCAL MAPIReadMail(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageID,
00343                               FLAGS flFlags, ULONG ulReserved, nsMapiMessage **lppMessage)
00344 {
00345   nsIMapi *pNsMapi = NULL;
00346 
00347   if (!InitMozillaReference(&pNsMapi))
00348     return MAPI_E_FAILURE;
00349 
00350   if (lhSession == 0)
00351     return(MAPI_E_INVALID_SESSION);
00352 
00353   return pNsMapi->ReadMail(lhSession, ulUIParam,
00354                               lpszMessageID, flFlags, ulReserved,
00355                               lppMessage) ;
00356 
00357 }
00358 
00359 ULONG FAR PASCAL MAPISaveMail(LHANDLE lhSession, ULONG ulUIParam, lpnsMapiMessage lpMessage,
00360                               FLAGS flFlags, ULONG ulReserved, LPTSTR lpszMessageID)
00361 {
00362     nsIMapi *pNsMapi = NULL;
00363 
00364   if (lhSession == 0)
00365     return(MAPI_E_INVALID_SESSION);
00366 
00367   if (!InitMozillaReference(&pNsMapi))
00368       return MAPI_E_FAILURE;
00369 
00370   return MAPI_E_FAILURE;
00371 }
00372 
00373 ULONG FAR PASCAL MAPIDeleteMail(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszMessageID,
00374                                 FLAGS flFlags, ULONG ulReserved)
00375 {
00376   nsIMapi *pNsMapi = NULL;
00377 
00378   if (lhSession == 0)
00379     return(MAPI_E_INVALID_SESSION);
00380 
00381   if (!InitMozillaReference(&pNsMapi))
00382       return MAPI_E_FAILURE;
00383 
00384   return pNsMapi->DeleteMail(lhSession, ulUIParam,
00385                               lpszMessageID, flFlags, ulReserved) ;
00386 }
00387 
00388 ULONG FAR PASCAL MAPIAddress(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszCaption,
00389                              ULONG nEditFields, LPTSTR lpszLabels, ULONG nRecips,
00390                              lpMapiRecipDesc lpRecips, FLAGS flFlags,
00391                              ULONG ulReserved, LPULONG lpnNewRecips,
00392                              lpMapiRecipDesc FAR *lppNewRecips)
00393 {
00394     return MAPI_E_FAILURE;
00395 }
00396 
00397 ULONG FAR PASCAL MAPIDetails(LHANDLE lhSession, ULONG ulUIParam, lpMapiRecipDesc lpRecip,
00398                              FLAGS flFlags, ULONG ulReserved)
00399 {
00400     return MAPI_E_FAILURE;
00401 }
00402 
00403 ULONG FAR PASCAL MAPIResolveName(LHANDLE lhSession, ULONG ulUIParam, LPTSTR lpszName,
00404                                  FLAGS flFlags, ULONG ulReserved, lpMapiRecipDesc FAR *lppRecip)
00405 {
00406     return MAPI_E_FAILURE;
00407 }
00408 
00409 void FreeMAPIRecipient(lpMapiRecipDesc pv);
00410 void FreeMAPIMessage(lpMapiMessage pv);
00411 
00412 ULONG FAR PASCAL MAPIFreeBuffer(LPVOID pv)
00413 {
00414   int   i;
00415 
00416   if (!pv)
00417        return(S_OK);
00418 
00419   for (i=0; i<MAX_POINTERS; i++)
00420   {
00421     if (pv == memArray[i].lpMem)
00422     {
00423       if (memArray[i].memType == MAPI_MESSAGE_TYPE)
00424       {
00425         FreeMAPIMessage((MapiMessage *)pv);
00426         memArray[i].lpMem = NULL;
00427       }
00428       else if (memArray[i].memType == MAPI_RECIPIENT_TYPE)
00429       {
00430         FreeMAPIRecipient((MapiRecipDesc *)pv);
00431         memArray[i].lpMem = NULL;
00432       }
00433     }
00434   }
00435 
00436   pv = NULL;
00437   return(S_OK);
00438 }
00439 
00440 ULONG FAR PASCAL GetMapiDllVersion()
00441 {
00442     return 94;
00443 }
00444 
00445 void
00446 FreeMAPIFile(lpMapiFileDesc pv)
00447 {
00448   if (!pv)
00449     return;
00450 
00451   if (pv->lpszPathName != NULL)   
00452     free(pv->lpszPathName);
00453 
00454   if (pv->lpszFileName != NULL)   
00455     free(pv->lpszFileName);
00456 }
00457 
00458 
00459 void
00460 FreeMAPIMessage(lpMapiMessage pv)
00461 {
00462   ULONG i;
00463 
00464   if (!pv)
00465     return;
00466 
00467   if (pv->lpszSubject != NULL)
00468     free(pv->lpszSubject);
00469 
00470   if (pv->lpszNoteText)
00471       free(pv->lpszNoteText);
00472   
00473   if (pv->lpszMessageType)
00474     free(pv->lpszMessageType);
00475   
00476   if (pv->lpszDateReceived)
00477     free(pv->lpszDateReceived);
00478   
00479   if (pv->lpszConversationID)
00480     free(pv->lpszConversationID);
00481   
00482   if (pv->lpOriginator)
00483     FreeMAPIRecipient(pv->lpOriginator);
00484   
00485   for (i=0; i<pv->nRecipCount; i++)
00486   {
00487     if (&(pv->lpRecips[i]) != NULL)
00488     {
00489       FreeMAPIRecipient(&(pv->lpRecips[i]));
00490     }
00491   }
00492 
00493   if (pv->lpRecips != NULL)
00494   {
00495     free(pv->lpRecips);
00496   }
00497 
00498   for (i=0; i<pv->nFileCount; i++)
00499   {
00500     if (&(pv->lpFiles[i]) != NULL)
00501     {
00502       FreeMAPIFile(&(pv->lpFiles[i]));
00503     }
00504   }
00505 
00506   if (pv->lpFiles != NULL)
00507   {
00508     free(pv->lpFiles);
00509   }
00510   
00511   free(pv);
00512   pv = NULL;
00513 }
00514 
00515 void
00516 FreeMAPIRecipient(lpMapiRecipDesc pv)
00517 {
00518   if (!pv)
00519     return;
00520 
00521   if (pv->lpszName != NULL)   
00522     free(pv->lpszName);
00523 
00524   if (pv->lpszAddress != NULL)
00525     free(pv->lpszAddress);
00526 
00527   if (pv->lpEntryID != NULL)
00528     free(pv->lpEntryID);  
00529 }
00530 
00531 
00532 
00533