Back to index

lightning-sunbird  0.9+nobinonly
mapimem.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 //
00038 //  mem.cpp
00039 //  Written by: Rich Pizzarro (rhp@netscape.com)
00040 //  November 1997
00041 //  This implements various memory management functions for use with
00042 //  MAPI features of Communicator
00043 //
00044 #include <windows.h>     
00045 #include <memory.h> 
00046 #include <malloc.h>
00047 #include "mapimem.h"
00048 #include <nscpmapi.h>   // lives in communicator winfe
00049 #include "nsstrseq.h"
00050 #include "trace.h"
00051 #include "mapiutl.h"
00052 #include "xpapi.h"
00053 
00054 LPSTR
00055 CheckNullString(LPSTR inStr)
00056 {
00057   static UCHAR  str[1];
00058 
00059   str[0] = '\0';
00060   if (inStr == NULL)
00061     return((LPSTR)str);
00062   else
00063     return(inStr);
00064 }
00065 
00066 void
00067 FreeMAPIFile(lpMapiFileDesc pv)
00068 {
00069   if (!pv)
00070     return;
00071 
00072   if (pv->lpszPathName != NULL)   
00073     free(pv->lpszPathName);
00074 
00075   if (pv->lpszFileName != NULL)   
00076     free(pv->lpszFileName);
00077 }
00078 
00079 void
00080 FreeMAPIMessage(lpMapiMessage pv)
00081 {
00082   ULONG i;
00083 
00084   if (!pv)
00085     return;
00086 
00087   if (pv->lpszSubject != NULL)
00088     free(pv->lpszSubject);
00089 
00090   if (pv->lpszNoteText)
00091       free(pv->lpszNoteText);
00092   
00093   if (pv->lpszMessageType)
00094     free(pv->lpszMessageType);
00095   
00096   if (pv->lpszDateReceived)
00097     free(pv->lpszDateReceived);
00098   
00099   if (pv->lpszConversationID)
00100     free(pv->lpszConversationID);
00101   
00102   if (pv->lpOriginator)
00103     FreeMAPIRecipient(pv->lpOriginator);
00104   
00105   for (i=0; i<pv->nRecipCount; i++)
00106   {
00107     if (&(pv->lpRecips[i]) != NULL)
00108     {
00109       FreeMAPIRecipient(&(pv->lpRecips[i]));
00110     }
00111   }
00112 
00113   if (pv->lpRecips != NULL)
00114   {
00115     free(pv->lpRecips);
00116   }
00117 
00118   for (i=0; i<pv->nFileCount; i++)
00119   {
00120     if (&(pv->lpFiles[i]) != NULL)
00121     {
00122       FreeMAPIFile(&(pv->lpFiles[i]));
00123     }
00124   }
00125 
00126   if (pv->lpFiles != NULL)
00127   {
00128     free(pv->lpFiles);
00129   }
00130   
00131   free(pv);
00132   pv = NULL;
00133 }
00134 
00135 void
00136 FreeMAPIRecipient(lpMapiRecipDesc pv)
00137 {
00138   if (!pv)
00139     return;
00140 
00141   if (pv->lpszName != NULL)   
00142     free(pv->lpszName);
00143 
00144   if (pv->lpszAddress != NULL)
00145     free(pv->lpszAddress);
00146 
00147   if (pv->lpEntryID != NULL)
00148     free(pv->lpEntryID);  
00149 }
00150 
00151 //
00152 // This routine will take an lpMapiMessage structure and "flatten" it into
00153 // one contiguous chunk of memory that can be easily passed around. After this
00154 // is done, "extract" routines will be written to get complicated string routines
00155 // out of the chunk of memory at the end.
00156 // 
00157 LPVOID
00158 FlattenMAPIMessageStructure(lpMapiMessage msg, DWORD *totalSize)
00159 {
00160   MAPISendMailType    *mailPtr;
00161   LPSTR               *strArray;
00162   DWORD               strCount = 0;
00163   DWORD               currentString = 0;
00164   DWORD               arrayBufSize = 0;
00165   DWORD               i;
00166 
00167   *totalSize = 0;
00168   if (!msg)
00169     return(NULL);
00170 
00171   //
00172   // Allocate the initial structure to hold all of the mail info.
00173   //
00174   *totalSize = sizeof(MAPISendMailType);
00175   mailPtr = (MAPISendMailType *) malloc(sizeof(MAPISendMailType));
00176   if (!mailPtr)
00177     return(NULL);
00178   memset(mailPtr, 0, sizeof(MAPISendMailType));
00179 
00180   //
00181   // First, assign all of the easy numeric values...
00182   //
00183   mailPtr->MSG_flFlags = msg->flFlags;          // unread,return receipt
00184   mailPtr->MSG_nRecipCount = msg->nRecipCount;  // Number of recipients
00185   mailPtr->MSG_nFileCount = msg->nFileCount;    // # of file attachments
00186   if (msg->lpOriginator != NULL)
00187   {
00188     mailPtr->MSG_ORIG_ulRecipClass = msg->lpOriginator->ulRecipClass; //  Recipient class - MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG
00189   }
00190 
00191   //
00192   // Now, figure out how many string pointers we need...
00193   //
00194   strCount = 4;     // These are the 4 KNOWN strings up front for a message
00195   strCount += 2;    // This is for the originator name and address
00196 
00197   strCount += msg->nRecipCount * 3; // Name, address & class (cc, bcc) for each recipient
00198   strCount += msg->nFileCount  * 2; // filename and display name for each attachment
00199 
00200   // 
00201   // Now allocate a new string sequence...add one entry for NULL at the end
00202   //  
00203   arrayBufSize = sizeof(LPSTR) * (strCount + 1);
00204 
00205 #ifdef WIN16    // Check for max mem allocation...
00206   if ((sizeof(MAPISendMailType) + arrayBufSize) > 64000)
00207   {
00208     free(mailPtr);
00209     return NULL;
00210   }
00211 #endif
00212 
00213   //
00214   // Allocate a buffer for the string pointers and if this fails, 
00215   // cleanup and return.
00216   // 
00217   strArray = (LPSTR *)malloc( (size_t) arrayBufSize);
00218   if (!strArray)
00219   {
00220     free(mailPtr);
00221     return NULL;
00222   }
00223 
00224   memset(strArray, 0, (size_t) arrayBufSize);  // Set the array to NULL
00225   strArray[currentString++] = CheckNullString(msg->lpszSubject);        // Message Subject
00226   strArray[currentString++] = CheckNullString(msg->lpszNoteText);       // Message Text  
00227   strArray[currentString++] = CheckNullString(msg->lpszDateReceived);   // in YYYY/MM/DD HH:MM format
00228   strArray[currentString++] = CheckNullString(msg->lpszConversationID); // conversation thread ID
00229 
00230   if (msg->lpOriginator)
00231   {
00232     strArray[currentString++] = CheckNullString(msg->lpOriginator[0].lpszName);
00233     strArray[currentString++] = CheckNullString(msg->lpOriginator[0].lpszAddress);
00234   }
00235   else
00236   {
00237     strArray[currentString++] = CheckNullString(NULL);
00238     strArray[currentString++] = CheckNullString(NULL);
00239   }
00240 
00241   //
00242   // Assign pointers for the Name and address of each recipient
00243   //
00244   LPSTR toString  = "1";
00245   LPSTR ccString  = "2";
00246   LPSTR bccString = "3";
00247 
00248   for (i=0; i<msg->nRecipCount; i++)
00249   {
00250     // rhp - need message class
00251     if (msg->lpRecips[i].ulRecipClass == MAPI_BCC)
00252       strArray[currentString++] = CheckNullString(bccString);
00253     else if (msg->lpRecips[i].ulRecipClass == MAPI_CC)
00254       strArray[currentString++] = CheckNullString(ccString);
00255     else
00256       strArray[currentString++] = CheckNullString(toString);
00257 
00258     strArray[currentString++] = CheckNullString(msg->lpRecips[i].lpszName);
00259     strArray[currentString++] = CheckNullString(msg->lpRecips[i].lpszAddress);  
00260   }
00261 
00262   BYTE    szNewFileName[_MAX_PATH];
00263 
00264   for (i=0; i<msg->nFileCount; i++)
00265   {
00266     char *namePtr;
00267     // have to copy/create temp files here of office won't work...
00268 
00269     if ( 
00270           (msg->lpFiles[i].lpszFileName != NULL) &&
00271           (*msg->lpFiles[i].lpszFileName != '\0') 
00272        )
00273     {
00274       namePtr = (char *)msg->lpFiles[i].lpszFileName;
00275     }
00276     else
00277     {
00278       namePtr = (char *)msg->lpFiles[i].lpszPathName;
00279     }
00280 
00281     if (GetTempMailNameWithExtension((char *)szNewFileName, namePtr) == 0)
00282     {
00283       free(strArray);
00284       free(mailPtr);
00285       return NULL;
00286     }
00287     
00288     if (!XP_CopyFile((char *)msg->lpFiles[i].lpszPathName, (char *)szNewFileName, TRUE))
00289     {
00290       free(strArray);
00291       free(mailPtr);
00292       return NULL;
00293     }
00294 
00295     strArray[currentString++] = CheckNullString((char *)szNewFileName);
00296     strArray[currentString++] = CheckNullString(msg->lpFiles[i].lpszFileName);
00297 
00298     AddTempFile((LPSTR) szNewFileName);
00299 //    strArray[currentString++] = CheckNullString(msg->lpFiles[i].lpszPathName);
00300 //    strArray[currentString++] = CheckNullString(msg->lpFiles[i].lpszFileName);
00301   }
00302 
00303   if (currentString != strCount)
00304   {
00305     TRACE("MAPI PROBLEM!!!!!! FlattenMAPIMessageStructure() currentString != strCount\n");
00306   }
00307 
00308   strArray[strCount] = NULL;    // terminate at the end
00309   NSstringSeq strSeq = NSStrSeqNew(strArray);
00310   if (!strSeq)
00311   {
00312     free(strArray);
00313     free(mailPtr);
00314     return NULL;
00315   }
00316   
00317   //
00318   // Now we need to copy the structure into a big, contiguous chunk of memory
00319   //
00320   LONG totalArraySize = NSStrSeqSize(strSeq);
00321   LONG totalMemSize = sizeof(MAPISendMailType) + totalArraySize;
00322 
00323 #ifdef WIN16
00324   if (totalMemSize > 64000)
00325   {
00326     free(strArray);
00327     NSStrSeqDelete(strSeq);
00328     free(mailPtr);
00329     return NULL;
00330   }
00331 #endif
00332 
00333   MAPISendMailType *newMailPtr = (MAPISendMailType *)malloc((size_t)totalMemSize);
00334   if (!newMailPtr)
00335   {
00336     free(strArray);
00337     NSStrSeqDelete(strSeq);
00338     free(mailPtr);
00339     return NULL;
00340   }
00341 
00342   memset(newMailPtr, 0, (size_t) totalMemSize);
00343   //
00344   // Finally do the copy...
00345   //
00346   memcpy(newMailPtr, mailPtr, sizeof(MAPISendMailType));
00347   memcpy(newMailPtr->dataBuf, strSeq, (size_t) totalArraySize);
00348   *totalSize = totalMemSize;
00349 
00350   //
00351   // Cleanup and scram...
00352   //
00353   if (strArray)
00354     free(strArray);
00355 
00356   if (strSeq)
00357     NSStrSeqDelete(strSeq);
00358 
00359   if (mailPtr)
00360     free(mailPtr);
00361 
00362   return(newMailPtr);
00363 }