Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
mapihook.cpp File Reference
#include <windows.h>
#include <trace.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "wfemsg.h"
#include "msgmapi.h"
#include "nsstrseq.h"
#include "mapihook.h"
#include "nscpmapi.h"
#include "mapismem.h"
#include "mapimail.h"
#include "hiddenfr.h"
#include "msgcom.h"

Go to the source code of this file.

Defines

#define DELIMIT   "-{|}-"

Functions

LONG ProcessMAPILogon (MAPILogonType *logonInfo)
LONG ProcessMAPILogoff (MAPILogoffType *logoffInfo)
LONG ProcessMAPISendMail (MAPISendMailType *sendMailPtr)
LONG ProcessMAPISaveMail (MAPISendMailType *sendMailPtr)
LONG ProcessMAPISendDocuments (MAPISendDocumentsType *sendDocPtr)
LONG ProcessMAPIFindNext (MAPIFindNextType *findInfo)
LONG ProcessMAPIDeleteMail (MAPIDeleteMailType *delInfo)
LONG ProcessMAPIResolveName (MAPIResolveNameType *nameInfo)
LONG ProcessMAPIDetails (MAPIDetailsType *detailInfo)
LONG ProcessMAPIReadMail (MAPIReadMailType *readInfo)
LONG ProcessMAPIAddress (MAPIAddressType *addrInfo)
void StoreMAPIFrameWnd (CFrameWnd *pFrameWnd)
LONG ProcessNetscapeMAPIHook (WPARAM wParam, LPARAM lParam)
CMAPIConnectionGetDefaultSession (void)
LONG GetOpenSessionSlot (void)
BOOL TryDefaultReassignment (void)
static LPSTR CheckNull (LPSTR inStr)
LONG WriteTheMemoryBufferToDisk (LPSTR fName, UINT bufSize, LPSTR buf)
static LPSTR GetTheTempDirectoryOnTheSystem (void)
static DWORD ValidateFile (LPCSTR szFile)
static LONG GetTempAttachmentName (LPSTR fName)
BOOL AddressCallback (int totalCount, int currentIndex, int addrType, LPSTR addrString)
BOOL GetNextAddress (LPSTR *name, LPSTR *address, int *addrType)

Variables

static CMAPIConnectionmapiConnections [MAX_CON] = {NULL, NULL, NULL, NULL}
static CFrameWnd * pMAPIFrameWnd = NULL
int arrayCount = 0
int addressCount = 0
LPSTRaddrArray
LPSTR toString = "1"
LPSTR ccString = "2"
LPSTR bccString = "3"
int getAddressCount = 0
MAPIAddressTypegetAddressPtr = NULL
NSstringSeq addrSeq = NULL

Define Documentation

#define DELIMIT   "-{|}-"

Definition at line 62 of file mapihook.cpp.


Function Documentation

BOOL AddressCallback ( int  totalCount,
int  currentIndex,
int  addrType,
LPSTR  addrString 
)

Definition at line 1410 of file mapihook.cpp.

{
  LPSTR     messageClass; 

  TRACE("TOTAL COUNT   = %d\n", totalCount);
  TRACE("CURRENT COUNT = %d\n", currentIndex);
  TRACE("CURRENT ADDR  = %s\n", addrString);

  // If this is the first entry, then we need to allocate the array...
  if (currentIndex == 0)
  {
    addressCount = totalCount;
    addrArray = (LPSTR *) malloc( (size_t) 
                            sizeof(LPSTR) * ((addressCount * 3) + 1) 
                          );
    if (!addrArray)
    {
      addressCount = 0;
      return FALSE;
    }
  }

  // if the array was not allocated...
  if (!addrArray)
  {
    addressCount = 0;
    return FALSE;
  }

  // Deal with the address type...
  if (addrType == MSG_CC_HEADER_MASK)
    messageClass = ccString;
  else if (addrType == MSG_BCC_HEADER_MASK)
    messageClass = bccString;
  else 
    messageClass = toString;

  // Now get the following 3 items:
  //      String x: LPSTR lpszName;             // Recipient N name                           
  //      String x: LPSTR lpszAddress;          // Recipient N address (optional)             
  //      String x: LPSTR lpszRecipClass        // recipient class - sprintf of ULONG

  char *ptr = strchr(addrString, '<');
  if (ptr)
  {
    addrString[strlen(addrString) - 1] = '\0';
    *(ptr-1) = '\0';
  }
  addrArray[arrayCount++] = CheckNull(addrString);

  if (ptr)
  {
    ptr++;
  }
  else
  {
    ptr = (char *) addrString;
  }

  addrArray[arrayCount++] = CheckNull(ptr);

  // 0 MAPI_ORIG     Indicates the original sender of the message. 
  // 1 MAPI_TO       Indicates a primary message recipient. 
  // 2 MAPI_CC       Indicates a recipient of a message copy. 
  // 3 MAPI_BCC      Indicates a recipient of a blindcopy. 
  addrArray[arrayCount++] = CheckNull(messageClass);

  return(TRUE);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static LPSTR CheckNull ( LPSTR  inStr) [static]

Definition at line 1073 of file mapihook.cpp.

{
  static UCHAR  str[1];

  str[0] = '\0';
  if (inStr == NULL)
    return((LPSTR)str);
  else
    return(inStr);
}

Here is the caller graph for this function:

Definition at line 424 of file mapihook.cpp.

{
  int i;
  
  for (i=0; i < MAX_CON; i++)
  {
    if (mapiConnections[i] != NULL)
    {
      if (mapiConnections[i]->IsDefault())
      {
        return mapiConnections[i];
      }
    }
  }

  return(NULL);
}

Here is the caller graph for this function:

BOOL GetNextAddress ( LPSTR name,
LPSTR address,
int addrType 
)

Definition at line 1487 of file mapihook.cpp.

{
  if ( getAddressCount >= (getAddressPtr->nRecips * 3) )
  {
    return FALSE;
  }

  ULONG   aType = atoi(NSStrSeqGet(addrSeq, getAddressCount++));

  // return which type of address this is?
  if (aType == MAPI_CC)
    *addrType = MSG_CC_HEADER_MASK;
  else if (aType == MAPI_BCC)
    *addrType = MSG_BCC_HEADER_MASK;
  else
    *addrType = MSG_TO_HEADER_MASK;
      
  *name    = (LPSTR) NSStrSeqGet(addrSeq, getAddressCount++);
  *address = (LPSTR) NSStrSeqGet(addrSeq, getAddressCount++);

  return TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 446 of file mapihook.cpp.

{
  int i;
  
  for (i=0; i < MAX_CON; i++)
  {
    if (mapiConnections[i] == NULL)
    {
      return(i);
    }
  }

  return(-1);
}

Here is the caller graph for this function:

static LONG GetTempAttachmentName ( LPSTR  fName) [static]

Definition at line 1158 of file mapihook.cpp.

{
  UINT        res;
  static UINT uUnique = 1;

  if (!fName)
    return(-1);

  LPSTR szTempPath = GetTheTempDirectoryOnTheSystem();

TRYAGAIN:
#ifdef WIN32
  res = GetTempFileName(szTempPath, "MAPI", uUnique++, fName);
#else
  res = ISGetTempFileName(szTempPath, "MAPI", uUnique++, fName);
#endif

  if (ValidateFile(fName) != 1) 
  {
    if (uUnique < 32000)
    {
      goto TRYAGAIN;
    }
    else
    {
      return(-1);
    }
  }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static LPSTR GetTheTempDirectoryOnTheSystem ( void  ) [static]

Definition at line 1111 of file mapihook.cpp.

{
 static UCHAR retPath[_MAX_PATH];
  
  if (getenv("TEMP"))
  {
    lstrcpy((LPSTR) retPath, getenv("TEMP"));  // environmental variable
  } 
  else if (getenv("TMP"))
  {
    lstrcpy((LPSTR) retPath, getenv("TMP"));  // How about this environmental variable?
  }
  else
  {
    GetWindowsDirectory((LPSTR) retPath, sizeof(retPath));
  }

  return((LPSTR) &(retPath[0]));
}

Here is the caller graph for this function:

Definition at line 1511 of file mapihook.cpp.

{
  CMAPIConnection *mySession;

  TRACE("MAPI: ProcessMAPIAddress() Incomming Addrs = %d\nCaption = [%s]\n",
                    addrInfo->nRecips,
                    addrInfo->lpszCaption);
  //
  // Verify the session handle...
  //
  if (((addrInfo->lhSession-1) >= MAX_CON) || ((addrInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(addrInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  // 
  // Put up the address dialog and do the right thing :-)
  // 
  addrSeq = (NSstringSeq) &(addrInfo->dataBuf[0]);
  getAddressCount = 0;  // Make sure to reset the counter for address info...
  getAddressPtr = addrInfo; // Address pointer for callback...
  arrayCount = 0;       // counter for the rest of the entries...
  theApp.m_pHiddenFrame->AddressDialog((LPSTR) (addrInfo->lpszCaption), 
                                            AddressCallback, GetNextAddress);

  // If the address count is zero, then we can return early...
  addrInfo->nNewRecips = addressCount;
  if (addressCount == 0)
  {
    return(SUCCESS_SUCCESS);
  }

  addrArray[arrayCount] = NULL;  

  // Create the string sequence
  NSstringSeq strSeq = NSStrSeqNew(addrArray);
  
  // Now just cleanup the array....
  free(addrArray);
  
  if (!strSeq)
  {
    return(MAPI_E_INSUFFICIENT_MEMORY);
  }
  
  // Now get the name of the file to write the blob to!
  if (GetTempAttachmentName((LPSTR)addrInfo->lpszBlob) < 0)
  {
    NSStrSeqDelete(strSeq);
    return(MAPI_E_INSUFFICIENT_MEMORY);
  }

  // Now write the blob to disk and move on...
  if (WriteTheMemoryBufferToDisk((LPSTR) addrInfo->lpszBlob, 
                      (UINT) NSStrSeqSize(strSeq), strSeq) != 0)
  {
    NSStrSeqDelete(strSeq);
    return(MAPI_E_INSUFFICIENT_MEMORY);
  }

  NSStrSeqDelete(strSeq);
  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 846 of file mapihook.cpp.

{
  CMAPIConnection *mySession;

  //
  // Verify the session handle...
  //
  if (((delInfo->lhSession-1) >= MAX_CON) || ((delInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(delInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  BOOL    msgValid = TRUE;

  TRACE("MAPI: RICHIE TODO: ProcessMAPIDeleteMail() TRY TO FIND THE MESSAGE FROM THE IDENTIFIER:\n");
  TRACE("MAPI: RICHIE TODO: ProcessMAPIDeleteMail() [%s]\n", delInfo->lpszMessageID);

  if (msgValid)
  {
    TRACE("MAPI: RICHIE TODO: ProcessMAPIDeleteMail() DELETE THE MESSAGE!!!\n");

    return(SUCCESS_SUCCESS);
  }
  else
  {
    return(MAPI_E_INVALID_MESSAGE);
  }
}

Here is the caller graph for this function:

Definition at line 965 of file mapihook.cpp.

{
  CMAPIConnection *mySession;

  //
  // Verify the session handle...
  //
  if (((detailInfo->lhSession-1) >= MAX_CON) || ((detailInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(detailInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  TRACE("MAPI: ProcessMAPIDetails() NEED TO LOCATE THE ENTRY FOR:\n");
  TRACE("MAPI: ProcessMAPIDetails() [%s]\n", detailInfo->lpszABookID);

  char    workString[MAX_NAME_LEN];
  char    *idString;
  char    *containerString;

  lstrcpy((LPSTR) workString, (LPSTR) detailInfo->lpszABookID);

  //
  // Now parse out the first and last names of the person...
  //
  int       totLen = lstrlen((LPSTR) workString);
  int       loc = 0;
  idString = &(workString[0]);

  while ( ( lstrlen((LPSTR) DELIMIT) + loc) < totLen)
  {
    if (strncmp((LPSTR)(workString + loc), DELIMIT, lstrlen(DELIMIT)) == 0)
    {
      workString[loc] = '\0';
      containerString = &(workString[loc + lstrlen(DELIMIT)]);
      break;
    }

    ++loc;
  }
    
  if ( (lstrlen((LPSTR) DELIMIT) + loc) >= totLen )
  {
    return(MAPI_E_INVALID_RECIPS);
  }

  // Now, convert the stuff to real values for the API...
  ABID              id = atoi((const char *) idString);
  AB_ContainerInfo  *container = AB_MAPI_ConvertToContainer(containerString);
  MSG_Pane          *personPane = NULL;
  extern MWContext         *GetUsableContext(void);

  // Need to first create a person entry pane and then call
  // FE_ShowPropertySheetAB2 on that pane - return 0 is problem
  int rc = AB_MAPI_CreatePropertySheetPane( 
            GetUsableContext(),
            WFE_MSGGetMaster(), 
            container, 
            id, 
            &personPane);  // BE will allocate a personPane and return a ptr to it here 
  if (!rc)
  {
    return(MAPI_E_INVALID_RECIPS);
  }

  // Now display the address book entry for this user. If the parameter
  // detailInfo->ulUIParam  is NULL, just doit and return, but if it is
  // not NULL, then we should do it as application modal.
  
  // RICHIE - THIS IS NOT IN THE BUILD YET! MUST WAIT
  //(void) FE_ShowPropertySheetForAB2(personPane, AB_Person);

  // cleanup the container and person pane...
  AB_MAPI_CloseContainer(&container);
  AB_ClosePane(personPane); 

  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 764 of file mapihook.cpp.

{
  CMAPIConnection *mySession;

  //
  // Verify the session handle...
  //
  if (((findInfo->lhSession-1) >= MAX_CON) || ((findInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(findInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  //
  // If this is true, then this is the first call to this FindNext function
  // and we should start the enumeration operation.
  //
       MSG_FolderInfo  *inboxFolder = NULL;
       int32           folderRC = MSG_GetFoldersWithFlag(WFE_MSGGetMaster(),
                                                                             MSG_FOLDER_FLAG_INBOX, &inboxFolder, 1);
  if (folderRC <= 0)
  {
    return(MAPI_E_NO_MESSAGES);
  }

  // This is the first message
  if (mySession->GetMessageIndex() < 0)
  {
    MSG_MapiListContext *cookie;

    MessageKey keyFound = MSG_GetFirstKeyInFolder(inboxFolder, &cookie);
    if (keyFound == MSG_MESSAGEKEYNONE)
    {
      mySession->SetMapiListContext(NULL);
      mySession->SetMessageIndex(-1); // Reset to -1...
      return(MAPI_E_NO_MESSAGES);
    }

    TRACE("MAPI: ProcessMAPIFindNext() Found message id = %d\n", keyFound);

    wsprintf((LPSTR) findInfo->lpszMessageID, "%d", keyFound);
    mySession->SetMapiListContext(cookie);
    mySession->SetMessageIndex(keyFound); // Just set to 1 and then increment from there...
  }
  else
  {
    MSG_MapiListContext *cookie = (MSG_MapiListContext *)mySession->GetMapiListContext();
    
    // Sanity check the cookie value...
    if (cookie == NULL)
    {
      mySession->SetMapiListContext(NULL);
      mySession->SetMessageIndex(-1); // Reset to -1...
      return(MAPI_E_NO_MESSAGES);
    }

    MessageKey nextKey = MSG_GetNextKeyInFolder(cookie);
    if (nextKey == MSG_MESSAGEKEYNONE)
    {
      mySession->SetMapiListContext(NULL);
      mySession->SetMessageIndex(-1); // Reset to -1...
      return(MAPI_E_NO_MESSAGES);
    }

    TRACE("MAPI: ProcessMAPIFindNext() Found message id = %d\n", nextKey);

    wsprintf((LPSTR) findInfo->lpszMessageID, "%d", nextKey);
    mySession->SetMessageIndex(nextKey); // Set the key to the found one and move on...
  }

  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 619 of file mapihook.cpp.

{
  TRACE("MAPI: ProcessMAPILogoff() Session ID = [%d]\n", logoffInfo->lhSession);
  //
  // Verify the session handle...
  //
  if (( (logoffInfo->lhSession-1) >= MAX_CON) || ( (logoffInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  CMAPIConnection *logoffSession = mapiConnections[(logoffInfo->lhSession - 1)];
  if (logoffSession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }
  
  //
  // Decrement the session count, then if this is the last one 
  // connected to this session, then kill it...
  //
  logoffSession->DecrementSessionCount();
  if (logoffSession->GetSessionCount() <= 0)
  {
    //
    // If this was the default session "holder", then we need to 
    // assign that task to a new one if it exists, if not, then
    // it is all back to null.
    //
    BOOL needToReassign = logoffSession->IsDefault();

    delete logoffSession;
    mapiConnections[logoffInfo->lhSession - 1] = NULL;

    if (needToReassign)
    {
      TRACE("MAPI: ProcessMAPILogoff() Need to reassign default\n");
      if (!TryDefaultReassignment())
      {
        if (pMAPIFrameWnd != NULL)
        {
          pMAPIFrameWnd->PostMessage(WM_CLOSE);
          pMAPIFrameWnd = NULL;
        }
      }
    }
  }

  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 493 of file mapihook.cpp.

{
  CMAPIConnection *defSession = GetDefaultSession();
  NSstringSeq strSeq = (LPSTR) logonInfo + sizeof(MAPILogonType);
  LPSTR lpszProfileName = NSStrSeqGet(strSeq, 0);
  LPSTR lpszPassword    = NSStrSeqGet(strSeq, 1);

  TRACE("MAPI: ProcessMAPILogon() ProfileName = [%s] Password = [%s]\n", 
                            lpszProfileName, lpszPassword);
  //
  // This is a query if lpszProfileName is NULL, lpszPassword is NULL and 
  // the MAPI_LOGON_UI is not set 
  //
  if ((lpszProfileName[0] == '\0') && (lpszPassword[0] == '\0') && 
    (!(logonInfo->flFlags & MAPI_LOGON_UI)) )
  {
    if (defSession == NULL)
    {
      return(MAPI_E_FAILURE);
    }
    else
    {
      defSession->IncrementSessionCount();
      logonInfo->lhSession = defSession->GetID();
      return(SUCCESS_SUCCESS);
    }
  }

  //
  // Only allow for sessions by a single profile name...
  //
  if ( ( defSession != NULL ) &&
       (
        (lstrcmp(lpszProfileName, defSession->GetProfileName() ) != 0) ||
        (lstrcmp(lpszPassword, defSession->GetPassword() ) != 0)
       )
     )
  {
    return(MAPI_E_TOO_MANY_SESSIONS);
  }

  //
  // Now create the new MAPI session if we have to...
  //
  BOOL createNew = FALSE;
  if ( 
      ( defSession == NULL ) ||
      // Indicates an attempt should be made to create a new session rather than acquire 
      // the environment's shared session. If the MAPI_NEW_SESSION flag is not set, MAPILogon 
      // uses an existing shared session.
      (logonInfo->flFlags & MAPI_NEW_SESSION) ||
      (defSession == NULL)      // No default session exists!
     ) 
  {
    createNew = TRUE;
  }

  //
  // Make sure only 4 max are allowed...
  //
  LONG  slot; 
  if ((createNew) && ((slot = GetOpenSessionSlot()) == -1))
  {
    return(MAPI_E_TOO_MANY_SESSIONS);
  }

  //
  // If we don't have to create a new session, just return the ID and
  // move on with life
  //
  if (!createNew)
  {
    if (defSession == NULL)
    {
      return(MAPI_E_FAILURE);
    }

    defSession->IncrementSessionCount();
    logonInfo->lhSession = defSession->GetID();
    return(SUCCESS_SUCCESS);
  }

  //
  // Finally, create a new session!
  //
  mapiConnections[slot] = new CMAPIConnection(slot, lpszProfileName, lpszPassword);
  if (defSession == NULL)
  {
    mapiConnections[slot]->SetDefault(TRUE);
  }

  logonInfo->lhSession = mapiConnections[slot]->GetID();

  //
  // Process Flags...
  //
  // Indicates an attempt should be made to download all of the user's messages before 
  // returning. If the MAPI_FORCE_DOWNLOAD flag is not set, messages can be downloaded 
  // in the background after the function call returns.
  if (logonInfo->flFlags & MAPI_FORCE_DOWNLOAD) 
  {
    MAPIGetNewMessagesInBackground();
  }

  // Indicates that a logon dialog box should be displayed to prompt the user for 
  // logon information. If the user needs to provide a password and profile name 
  // to enable a successful logon, MAPI_LOGON_UI must be set.
  if (logonInfo->flFlags & MAPI_LOGON_UI) 
  {
    TRACE("MAPI: ProcessMAPILogon() MAPI_LOGON_UI Unsupported.\n");
  }

#ifdef WIN32
  // Indicates that MAPILogon should only prompt for a password and not allow the user 
  // to change the profile name. Either MAPI_PASSWORD_UI or MAPI_LOGON_UI should not be 
  // set, since the intent is to select between two different dialog boxes for logon.
  if (logonInfo->flFlags & MAPI_PASSWORD_UI)
  {
    TRACE("MAPI: ProcessMAPILogon() MAPI_PASSWORD_UI Unsupported.\n");
  }         
#endif  
  
  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1191 of file mapihook.cpp.

{
  CMAPIConnection *mySession;
  lpMapiMessage   message;      // this is the message we will receive

  //
  // Verify the session handle...
  //
  if (((readInfo->lhSession-1) >= MAX_CON) || ((readInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(readInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  // First, gotta get the inbox folder!
  MSG_FolderInfo  *inboxFolder = NULL;
       int32           folderRC = MSG_GetFoldersWithFlag(WFE_MSGGetMaster(),
                                                                             MSG_FOLDER_FLAG_INBOX, &inboxFolder, 1);
  if (folderRC <= 0)
  {
    return(MAPI_E_INVALID_MESSAGE);
  }

  // Convert the message id to a number!
  MessageKey lookupKey = atoi((const char *)readInfo->lpszMessageID);
  TRACE("MAPI: ProcessMAPIReadMail() Find this message = [%s] - [%d]\n", 
                          readInfo->lpszMessageID, lookupKey);

  // Now see if we can find this message!
  BOOL msgFound = MSG_GetMapiMessageById(inboxFolder, lookupKey, &message);

  // If we didn't find the message, then we need to bail!
  if (!msgFound)
  {
    TRACE("MAPI: ProcessMAPIReadMail() MESSAGE NOT FOUND\n");
    return(MAPI_E_INVALID_MESSAGE);
  }

  //
  // Now that we have found the message, we need to populate the chunk of
  // memory that we will write to disk and then move on. For now, we need
  // to setup all of the variables for the information we will need for the
  // message.
  //
  ULONG     i;
  DWORD     arrayCount = 0;         // Counter for array entries!
  DWORD     arrayTotal = 0;         // Total for array entries!
  FLAGS     msgFlags;               // unread, return or receipt                  
  ULONG     msgRecipCount = message->nRecipCount; // Number of recipients                   
  ULONG     msgFileAttachCount = message->nFileCount; // # of file attachments                  

  LPSTR     msgSubject = message->lpszSubject;          // Message Subject
  LPSTR     msgNoteText = NULL;                         // Message Text will be
  LPSTR     msgDateReceived = message->lpszDateReceived;// in YYYY/MM/DD HH:MM format
  LPSTR     msgThreadID = message->lpszConversationID;  // conversation thread ID

  //
  // The following are for the originator of the message. Only ONE of these.
  //
  LPSTR     origName = NULL;    // Originator name                           
  LPSTR     origAddress = NULL; // Originator address (optional)             
  ULONG     origRecipClass = MAPI_TO;               // Recipient class - MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG

  // Now we have to make sure there is an originator and set the vars...
  if (message->lpOriginator)
  {
    origName    = message->lpOriginator->lpszName;
    origAddress = message->lpOriginator->lpszAddress;
  }

  if ( ! (readInfo->flFlags & MAPI_ENVELOPE_ONLY))
  {
      TRACE("MAPI: ProcessMAPIReadMail() GET NOTE TEXT - ONLY IF WE HAVE TO!\n"); 
      msgNoteText = message->lpszNoteText;
  }

  // First, figure out how many entries we need to have in a string array...
  arrayTotal = 6 + 1; // 6 for the first 6 strings and 1 for the final NULL    

  // Add the recipient information
  arrayTotal += (msgRecipCount * 3);

  // Now check to see if we are going to pass back attachments:
  //
  // MAPI_ENVELOPE_ONLY 
  // Indicates MAPIReadMail should read the message header only. File attachments are 
  // not copied to temporary files, and neither temporary file names nor message text 
  // is written. Setting this flag enhances performance. 
  //
  // MAPI_SUPPRESS_ATTACH 
  // Indicates MAPIReadMail should not copy file attachments but should write message 
  // text into the MapiMessage structure. MAPIReadMail ignores this flag if the 
  // calling application has set the MAPI_ENVELOPE_ONLY flag. Setting the 
  // MAPI_SUPPRESS_ATTACH flag enhances performance. 
  //
  if ((readInfo->flFlags & MAPI_SUPPRESS_ATTACH) ||
      (readInfo->flFlags & MAPI_ENVELOPE_ONLY) )
  {
    msgFileAttachCount = 0;
  }

  arrayTotal += (msgFileAttachCount * 2);
  
  // now allocate the memory for the string array 
  LPSTR *strArray = (LPSTR *) malloc((size_t) (sizeof(LPSTR) * arrayTotal));
  if (!strArray)
  {
    return(MAPI_E_INSUFFICIENT_MEMORY);
  }

  // Now assign the easy return values to the shared memory structure
  readInfo->MSG_flFlags     = msgFlags;           // unread, return or receipt                  
  readInfo->MSG_nRecipCount = msgRecipCount;      // Number of recipients                   
  readInfo->MSG_nFileCount  = msgFileAttachCount; // # of file attachments                  
  readInfo->MSG_ORIG_ulRecipClass = origRecipClass; //  Recipient class - MAPI_TO, MAPI_CC, MAPI_BCC, MAPI_ORIG

  // Now go through and fill out the array to create the string sequence
  strArray[0] = CheckNull(msgSubject);
  strArray[1] = CheckNull(msgNoteText);
  strArray[2] = CheckNull(msgDateReceived);
  strArray[3] = CheckNull(msgThreadID);
  strArray[4] = CheckNull(origName);
  strArray[5] = CheckNull(origAddress);

  arrayCount = 6;   // counter for the rest of the needed attachments

  // Now add all of the recipients
  for (i=0; i<msgRecipCount; i++)
  {
    UCHAR     tempString[128];
    ULONG     messageClass = message->lpRecips[i].ulRecipClass; // Get the recipient class...

    // Now get the following 3 items:
    //      String x: LPSTR lpszName;             // Recipient N name                           
    //      String x: LPSTR lpszAddress;          // Recipient N address (optional)             
    //      String x: LPSTR lpszRecipClass        // recipient class - sprintf of ULONG
    strArray[arrayCount++] = CheckNull(message->lpRecips[i].lpszName);
    strArray[arrayCount++] = CheckNull(message->lpRecips[i].lpszAddress);

    // 0      MAPI_ORIG     Indicates the original sender of the message. 
    // 1      MAPI_TO       Indicates a primary message recipient. 
    // 2      MAPI_CC       Indicates a recipient of a message copy. 
    // 3      MAPI_BCC      Indicates a recipient of a blind copy. 
    wsprintf((LPSTR) tempString, "%d", messageClass);
    strArray[arrayCount++] = CheckNull((LPSTR) tempString);
  }

  // Now, add all of the attachments to this blob
  for (i=0; i<msgFileAttachCount; i++)
  {
    //      String x: LPSTR lpszPathName // Fully qualified path of the attached file. 
    //                                   // This path should include the disk drive letter and directory name.
    //      String x: LPSTR lpszFileName // The display name for the attached file
    //
    strArray[arrayCount++] = CheckNull(message->lpFiles[i].lpszPathName);
    strArray[arrayCount++] = CheckNull(message->lpFiles[i].lpszFileName);
  }

  strArray[arrayCount] = NULL;

  // Create the string sequence
  NSstringSeq strSeq = NSStrSeqNew(strArray);

  // Now just cleanup the array....
  free(strArray);
 
  if (!strSeq)
  {
    return(MAPI_E_INSUFFICIENT_MEMORY);
  }
  
  // Now get the name of the file to write the blob to!
  if (GetTempAttachmentName((LPSTR)readInfo->lpszBlob) < 0)
  {
    NSStrSeqDelete(strSeq);
    return(MAPI_E_ATTACHMENT_WRITE_FAILURE);
  }

  // Now write the blob to disk and move on...
  if (WriteTheMemoryBufferToDisk((LPSTR) readInfo->lpszBlob, 
                      (UINT) NSStrSeqSize(strSeq), strSeq) != 0)
  {
    NSStrSeqDelete(strSeq);
    return(MAPI_E_ATTACHMENT_WRITE_FAILURE);
  }

  //
  // MAPI_PEEK 
  // Indicates MAPIReadMail does not mark the message as read. Marking a message as 
  // read affects its appearance in the user interface and generates a read receipt. 
  // If the messaging system does not support this flag, MAPIReadMail always marks 
  // the message as read. If MAPIReadMail encounters an error, it leaves the 
  // message unread.  
  if (!(readInfo->flFlags & MAPI_PEEK))
  {
    MSG_MarkMapiMessageRead (inboxFolder, lookupKey, TRUE);
  }

  // Now we have to free the message and the chunk of memory...
  MSG_FreeMapiMessage(message);
  NSStrSeqDelete(strSeq);

  return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 885 of file mapihook.cpp.

{
  CMAPIConnection *mySession;

  //
  // Verify the session handle...
  //
  if (((nameInfo->lhSession-1) >= MAX_CON) || ((nameInfo->lhSession-1) < 0))
  {
    return(MAPI_E_INVALID_SESSION);
  }

  mySession = mapiConnections[(nameInfo->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_INVALID_SESSION);
  }

  TRACE("MAPI: ProcessMAPIResolveName() TRY TO IDENTIFY THE ADDRESS INFO FOR THE NAME:\n");
  TRACE("MAPI: ProcessMAPIResolveName() [%s]\n", nameInfo->lpszName);

  DWORD numFound;
  LPSTR retFullName = NULL;
  LPSTR retAddr = NULL;
  
  AB_ContainerInfo  *ctr;
  ABID              id;

  numFound = AB_MAPI_ResolveName ( 
                (char *)nameInfo->lpszName, // i.e. a nickname or part of the person's name to look up. Assumes First Last 
                &ctr,                       // caller allocates the ctr ptr. BE fills Caller must close container when done with it
                &id);                       // caller allocates the ABID, BE fills 

  if (numFound > 1)
  {
    return(MAPI_E_AMBIGUOUS_RECIPIENT);
  }
  else if (numFound <= 0)
  {
    return(MAPI_E_UNKNOWN_RECIPIENT);
  }
  else    // Here we found a single entry!
  {
    // Get the full name and email address...
    retFullName = AB_MAPI_GetFullName(ctr, id);
    retAddr = AB_MAPI_GetEmailAddress(ctr, id);

    // null out return values just in case...
    nameInfo->lpszABookName[0] = '\0';
    nameInfo->lpszABookAddress[0] = '\0';

    // if valid, copy the strings over...
    if (retFullName)
      lstrcpy((LPSTR) nameInfo->lpszABookName, retFullName);
    if (retAddr)
      lstrcpy((LPSTR) nameInfo->lpszABookAddress, retAddr);

    // Now get the string to use for an ID later on...
    LPSTR  abookIDString =  AB_MAPI_ConvertToDescription(ctr); 

    // build that string ID to pass back through the MAPI API
    wsprintf((LPSTR) nameInfo->lpszABookID, "%d%s", id, DELIMIT);
    lstrcat((LPSTR) nameInfo->lpszABookID, abookIDString);
    
    // Be nice and cleanup after ourselves...
    if (retAddr)
      XP_FREE(retAddr);
    if (retFullName)
      XP_FREE(retFullName);
    if (abookIDString)
      XP_FREE(abookIDString);

    return(SUCCESS_SUCCESS);
  }
}

Here is the caller graph for this function:

Definition at line 719 of file mapihook.cpp.

{
  CMAPIConnection *mySession;
  NSstringSeq     mailInfoSeq;

  TRACE("MAPI: ProcessMAPISaveMail() Session ID = [%d]\n", sendMailPtr->lhSession);
  //
  // Verify the session handle...
  //
  if (((sendMailPtr->lhSession-1) >= MAX_CON) || ((sendMailPtr->lhSession-1) < 0))
  {
    return(MAPI_E_FAILURE);
  }

  mySession = mapiConnections[(sendMailPtr->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_FAILURE);
  }

  mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
  TRACE("MAPI: ProcessMAPISaveMail() Session ID = [%d]\n", sendMailPtr->lhSession);

  //
  // Now process the save mail operation...
  //
  LONG rc = DoMAPISaveMailOperation(sendMailPtr, 
                                    NSStrSeqGet(mailInfoSeq, 1));
  return(rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 754 of file mapihook.cpp.

{
  LONG rc = DoPartialMAPIMailOperation(sendDocPtr);    
  return(rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 674 of file mapihook.cpp.

{
  CMAPIConnection *mySession;
  NSstringSeq     mailInfoSeq;

  TRACE("MAPI: ProcessMAPISendMail() Session ID = [%d]\n", sendMailPtr->lhSession);
  //
  // Verify the session handle...
  //
  if (((sendMailPtr->lhSession-1) >= MAX_CON) || ((sendMailPtr->lhSession-1) < 0))
  {
    return(MAPI_E_FAILURE);
  }

  mySession = mapiConnections[(sendMailPtr->lhSession - 1)];
  if (mySession == NULL)
  {
    return(MAPI_E_FAILURE);
  }

  //
  // Before we start, make sure things make sense...
  //
  if ( (!(sendMailPtr->flFlags & MAPI_DIALOG)) && (sendMailPtr->MSG_nRecipCount == 0) )
  {
    return(MAPI_E_UNKNOWN_RECIPIENT);
  }

  mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
  TRACE("MAPI: ProcessMAPISendMail() Session ID = [%d]\n", sendMailPtr->lhSession);

  //
  // Now set the show window flag...
  //
  BOOL showWindow = (( sendMailPtr->flFlags & MAPI_DIALOG ) != 0);
  LONG rc = DoFullMAPIMailOperation(sendMailPtr, 
                                    NSStrSeqGet(mailInfoSeq, 1),
                                    showWindow);
  return(rc);
}

Here is the call graph for this function:

Here is the caller graph for this function:

LONG ProcessNetscapeMAPIHook ( WPARAM  wParam,
LPARAM  lParam 
)

Definition at line 115 of file mapihook.cpp.

{
  PCOPYDATASTRUCT      pcds = (PCOPYDATASTRUCT) lParam;
  MAPIIPCType       *ipcInfo; 
#ifdef WIN32   
  HANDLE            hSharedMemory;
#endif

       if (lParam == NULL)
       {
              return(MAPI_E_FAILURE);
       }

  //
  // Get shared memory info structure pointer...
  //
  ipcInfo = (MAPIIPCType *)pcds->lpData;
  if (ipcInfo == NULL)
       {
              return(MAPI_E_FAILURE);
       }

  //
  // Now connect to shared memory...or just set the
  // pointer for Win16
  //
#ifdef WIN32
  CSharedMem *sMem = NSOpenExistingSharedMemory((LPCTSTR) ipcInfo->smemName, &hSharedMemory);
  if (!sMem)
       {
              return(MAPI_E_FAILURE);
       }
#else
  if (!ipcInfo->lpsmem)
  {
    return(MAPI_E_FAILURE);
  }
#endif

  TRACE("MAPI: MAPIHook Message ID = %d\n", pcds->dwData);
       switch (pcds->dwData) 
       {
  // MAPILogon
  case NSCP_MAPILogon:
    {
     MAPILogonType     *logonInfo;
#ifdef WIN32
    logonInfo = (MAPILogonType *) &(sMem->m_buf[0]);
#else    
    logonInfo = (MAPILogonType *) ipcInfo->lpsmem;
#endif

    if (!logonInfo)
    {
      return(MAPI_E_FAILURE);
    }
  
    logonInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPILogon(logonInfo));
    break;
    }

  // MAPILogoff
  case NSCP_MAPILogoff:
    {
    MAPILogoffType     *logoffInfo;
 
#ifdef WIN32
    logoffInfo = (MAPILogoffType *) &(sMem->m_buf[0]);
#else    
    logoffInfo = (MAPILogoffType *) ipcInfo->lpsmem;
#endif

    if (!logoffInfo)
    {
      return(MAPI_E_FAILURE);
    }

    logoffInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPILogoff(logoffInfo));
    break;
    }

  // NSCP_MAPISendMail
  case NSCP_MAPISendMail:
     {
     MAPISendMailType     *sendMailPtr;
#ifdef WIN32
    sendMailPtr = (MAPISendMailType *) &(sMem->m_buf[0]);
#else    
    sendMailPtr = (MAPISendMailType *) ipcInfo->lpsmem;
#endif

    if (!sendMailPtr)
    {
      return(MAPI_E_FAILURE);
    }

    sendMailPtr->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPISendMail(sendMailPtr));
    break;
    }

  // MAPISendDocuments
  case NSCP_MAPISendDocuments:
     {
     MAPISendDocumentsType     *sendDocPtr;
#ifdef WIN32
    sendDocPtr = (MAPISendDocumentsType *) &(sMem->m_buf[0]);
#else    
    sendDocPtr = (MAPISendDocumentsType *) ipcInfo->lpsmem;
#endif

    if (!sendDocPtr)
    {
      return(MAPI_E_FAILURE);
    }

    sendDocPtr->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPISendDocuments(sendDocPtr));
    break;
    }

  // MAPIFindNext
  case NSCP_MAPIFindNext:
    {
    MAPIFindNextType    *findInfo;
 
#ifdef WIN32
    findInfo = (MAPIFindNextType *) &(sMem->m_buf[0]);
#else    
    findInfo = (MAPIFindNextType *) ipcInfo->lpsmem;
#endif

    if (!findInfo)
    {
      return(MAPI_E_FAILURE);
    }

    findInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIFindNext(findInfo));
    break;
    }

  // MAPIDeleteMail
  case NSCP_MAPIDeleteMail:
    {
    MAPIDeleteMailType    *delInfo;
 
#ifdef WIN32
    delInfo = (MAPIDeleteMailType *) &(sMem->m_buf[0]);
#else    
    delInfo = (MAPIDeleteMailType *) ipcInfo->lpsmem;
#endif

    if (!delInfo)
    {
      return(MAPI_E_FAILURE);
    }

    delInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIDeleteMail(delInfo));
    break;
    }

  // MAPIResolveName
  case NSCP_MAPIResolveName:
    {
    MAPIResolveNameType    *nameInfo;
 
#ifdef WIN32
    nameInfo = (MAPIResolveNameType *) &(sMem->m_buf[0]);
#else    
    nameInfo = (MAPIResolveNameType *) ipcInfo->lpsmem;
#endif

    if (!nameInfo)
    {
      return(MAPI_E_FAILURE);
    }

    nameInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIResolveName(nameInfo));
    break;
    }

  // MAPIDetails
  case NSCP_MAPIDetails:
    {
    MAPIDetailsType    *detailInfo;
 
#ifdef WIN32
    detailInfo = (MAPIDetailsType *) &(sMem->m_buf[0]);
#else    
    detailInfo = (MAPIDetailsType *) ipcInfo->lpsmem;
#endif

    if (!detailInfo)
    {
      return(MAPI_E_FAILURE);
    }

    detailInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIDetails(detailInfo));
    break;
    }

  // MAPIReadMail
  case NSCP_MAPIReadMail:
    {
    MAPIReadMailType    *readInfo;
 
#ifdef WIN32
    readInfo = (MAPIReadMailType *) &(sMem->m_buf[0]);
#else    
    readInfo = (MAPIReadMailType *) ipcInfo->lpsmem;
#endif

    if (!readInfo)
    {
      return(MAPI_E_FAILURE);
    }

    readInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIReadMail(readInfo));
    break;
    }

  // NSCP_MAPISaveMail
  case NSCP_MAPISaveMail:
     {
     MAPISendMailType     *sendMailPtr;
#ifdef WIN32
    sendMailPtr = (MAPISendMailType *) &(sMem->m_buf[0]);
#else    
    sendMailPtr = (MAPISendMailType *) ipcInfo->lpsmem;
#endif

    if (!sendMailPtr)
    {
      return(MAPI_E_FAILURE);
    }

    sendMailPtr->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPISaveMail(sendMailPtr));
    break;
    }

  // MAPIAddress
  case NSCP_MAPIAddress:
    {
    MAPIAddressType    *addrInfo;
 
#ifdef WIN32
    addrInfo = (MAPIAddressType *) &(sMem->m_buf[0]);
#else    
    addrInfo = (MAPIAddressType *) ipcInfo->lpsmem;
#endif

    if (!addrInfo)
    {
      return(MAPI_E_FAILURE);
    }

    addrInfo->ipcWorked = 1;         // Set the worked flag
    return(ProcessMAPIAddress(addrInfo));
    }
  
  case NSCP_MAPIFree:   // This should never hit Communicator, but if it does
#ifdef WIN16
    return(SUCCESS_SUCCESS);       // Just return
#else
    return(S_OK);       // Just return 
#endif

       default:
    return(MAPI_E_NOT_SUPPORTED);     // Should never hit here!
              break;
       }

       return(SUCCESS_SUCCESS);
}

Here is the call graph for this function:

void StoreMAPIFrameWnd ( CFrameWnd *  pFrameWnd)

Definition at line 91 of file mapihook.cpp.

{
  pMAPIFrameWnd = pFrameWnd;
}

Definition at line 465 of file mapihook.cpp.

{
  int   i;
  int   loc = -1;

  // Find any sessions left?
  for (i=0; i < MAX_CON; i++)
  {
    if (mapiConnections[i] != NULL)
    {
      loc = i;
      break;
    }
  }

  // Set default state on the object to true
  if (loc >= 0)
  {
    mapiConnections[loc]->SetDefault(TRUE);
    return(TRUE);
  }
  else    
  {
    return(FALSE);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static DWORD ValidateFile ( LPCSTR  szFile) [static]

Definition at line 1142 of file mapihook.cpp.

{
       struct _stat buf;
    int result;

    result = _stat( szFile, &buf );
    if (result != 0)
      return(1);

    if (!(buf.st_mode & S_IREAD))
      return(2);

    return(0);
}

Here is the caller graph for this function:

LONG WriteTheMemoryBufferToDisk ( LPSTR  fName,
UINT  bufSize,
LPSTR  buf 
)

Definition at line 1085 of file mapihook.cpp.

{
  if (!buf)
  {
    return(-1);
  }

  HFILE hFile = _lcreat(fName, 0);
  if (hFile == HFILE_ERROR)
  {
    return(-1);
  }

  UINT writeCount = _lwrite(hFile, buf, bufSize);
  _lclose(hFile);

  if (writeCount != bufSize)
  {
    _unlink(fName);
    return(-1);
  }

  return(0);
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 1404 of file mapihook.cpp.

Definition at line 1403 of file mapihook.cpp.

Definition at line 1483 of file mapihook.cpp.

Definition at line 1402 of file mapihook.cpp.

Definition at line 1407 of file mapihook.cpp.

LPSTR ccString = "2"

Definition at line 1406 of file mapihook.cpp.

Definition at line 1481 of file mapihook.cpp.

Definition at line 1482 of file mapihook.cpp.

Definition at line 67 of file mapihook.cpp.

CFrameWnd* pMAPIFrameWnd = NULL [static]

Definition at line 88 of file mapihook.cpp.

LPSTR toString = "1"

Definition at line 1405 of file mapihook.cpp.