Esempio n. 1
0
void CMapiFolderList::DumpList( void)
{
  CMapiFolder *pFolder;
  nsString  str;
  int      depth;
  char    prefix[256];

  MAPI_TRACE0( "Folder List ---------------------------------\n");
  for (int i = 0; i < m_array.Count(); i++) {
    pFolder = (CMapiFolder *)GetAt( i);
    depth = pFolder->GetDepth();
    pFolder->GetDisplayName( str);
    depth *= 2;
    if (depth > 255)
      depth = 255;
    memset( prefix, ' ', depth);
    prefix[depth] = 0;
#ifdef MAPI_DEBUG
        char *ansiStr = ToNewCString(str);
    MAPI_TRACE2( "%s%s: ", prefix, ansiStr);
    NS_Free(ansiStr);
#endif
    pFolder->GetFilePath( str);
#ifdef MAPI_DEBUG
        ansiStr = ToNewCString(str);
    MAPI_TRACE2( "depth=%d, filePath=%s\n", pFolder->GetDepth(), ansiStr);
    NS_Free(ansiStr);
#endif
  }
  MAPI_TRACE0( "---------------------------------------------\n");
}
Esempio n. 2
0
BOOL CMapiApi::LogOn( void)
{
  if (!m_initialized) {
    MAPI_TRACE0( "Tried to LogOn before initializing MAPI\n");
    return( FALSE);
  }

  if (m_lpSession)
    return( TRUE);

  HRESULT hr;

  hr = MAPILogonEx(  0, // might need to be passed in HWND
            NULL, // profile name, 64 char max (LPTSTR)
            NULL, // profile password, 64 char max (LPTSTR)
            // MAPI_NEW_SESSION | MAPI_NO_MAIL | MAPI_LOGON_UI | MAPI_EXPLICIT_PROFILE,
            // MAPI_NEW_SESSION | MAPI_NO_MAIL | MAPI_LOGON_UI,
            // MAPI_NO_MAIL | MAPI_LOGON_UI,
            MAPI_NO_MAIL | MAPI_USE_DEFAULT | MAPI_EXTENDED | MAPI_NEW_SESSION,
            &m_lpSession);

  if (FAILED(hr)) {
    m_lpSession = NULL;
    MAPI_TRACE2( "LogOn failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  MAPI_TRACE0( "MAPI Logged on\n");
  return( TRUE);
}
Esempio n. 3
0
bool CMapiMessage::CopyBinAttachToFile(LPATTACH lpAttach,
                                       nsIFile **tmp_file)
{
  nsCOMPtr<nsIFile> _tmp_file;
  nsresult rv = GetSpecialDirectoryWithFileName(NS_OS_TEMP_DIR,
    "mapiattach.tmp",
    getter_AddRefs(_tmp_file));
  NS_ENSURE_SUCCESS(rv, false);

  rv = _tmp_file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 00600);
  NS_ENSURE_SUCCESS(rv, false);

  nsCString tmpPath;
  _tmp_file->GetNativePath(tmpPath);
  LPSTREAM lpStreamFile;
  HRESULT hr = CMapiApi::OpenStreamOnFile(gpMapiAllocateBuffer, gpMapiFreeBuffer, STGM_READWRITE | STGM_CREATE,
    const_cast<char*>(tmpPath.get()), NULL, &lpStreamFile);
  if (HR_FAILED(hr)) {
    MAPI_TRACE1("~~ERROR~~ OpenStreamOnFile failed - temp path: %s\r\n",
                tmpPath.get());
    return false;
  }

  bool bResult = true;
  LPSTREAM lpAttachStream;
  hr = lpAttach->OpenProperty(PR_ATTACH_DATA_BIN, &IID_IStream, 0, 0, (LPUNKNOWN *)&lpAttachStream);

  if (HR_FAILED(hr)) {
    MAPI_TRACE0("~~ERROR~~ OpenProperty failed for PR_ATTACH_DATA_BIN.\r\n");
    lpAttachStream = NULL;
    bResult = false;
  }
  else {
    STATSTG st;
    hr = lpAttachStream->Stat(&st, STATFLAG_NONAME);
    if (HR_FAILED(hr)) {
      MAPI_TRACE0("~~ERROR~~ Stat failed for attachment stream\r\n");
      bResult = false;
    }
    else {
      hr = lpAttachStream->CopyTo(lpStreamFile, st.cbSize, NULL, NULL);
      if (HR_FAILED(hr)) {
        MAPI_TRACE0("~~ERROR~~ Attach Stream CopyTo temp file failed.\r\n");
        bResult = false;
      }
    }
  }

  if (lpAttachStream)
    lpAttachStream->Release();
  lpStreamFile->Release();
  if (!bResult)
    _tmp_file->Remove(false);
  else
    CallQueryInterface(_tmp_file, tmp_file);

  return bResult;
}
Esempio n. 4
0
BOOL CMapiFolderContents::SetUpIter( void)
{
  // First, open up the MAPIFOLDER object
  ULONG    ulObjType;
  HRESULT    hr;
  hr = m_lpMdb->OpenEntry( m_fCbEid, (LPENTRYID) m_fLpEid, NULL, 0, &ulObjType, (LPUNKNOWN *) &m_lpFolder);

  if (FAILED(hr) || !m_lpFolder) {
    m_lpFolder = NULL;
    m_lastError = hr;
    MAPI_TRACE2( "CMapiFolderContents OpenEntry failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  if (ulObjType != MAPI_FOLDER) {
    m_lastError = -1;
    MAPI_TRACE0( "CMapiFolderContents - bad object type, not a folder.\n");
    return( FALSE);
  }


  hr = m_lpFolder->GetContentsTable( 0, &m_lpTable);
  if (FAILED(hr) || !m_lpTable) {
    m_lastError = hr;
    m_lpTable = NULL;
    MAPI_TRACE2( "CMapiFolderContents - GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  hr = m_lpTable->GetRowCount( 0, &m_count);
  if (FAILED(hr)) {
    m_lastError = hr;
    MAPI_TRACE0( "CMapiFolderContents - GetRowCount failed\n");
    return( FALSE);
  }

  hr = m_lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0);
  if (FAILED(hr)) {
    m_lastError = hr;
    MAPI_TRACE2( "CMapiFolderContents - SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  hr = m_lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL);
  if (FAILED(hr)) {
    m_lastError = hr;
    MAPI_TRACE2( "CMapiFolderContents - SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  return( TRUE);
}
Esempio n. 5
0
BOOL CMapiApi::GetStoreFolders( ULONG cbEid, LPENTRYID lpEid, CMapiFolderList& folders, int startDepth)
{
  // Fill in the array with the folders in the given store
  if (!m_initialized || !m_lpSession) {
    MAPI_TRACE0( "MAPI not initialized for GetStoreFolders\n");
    return( FALSE);
  }

  m_lpMdb = NULL;

  CMsgStore *    pStore = FindMessageStore( cbEid, lpEid);
  BOOL      bResult = FALSE;
  LPSPropValue  pVal;

  if (pStore && pStore->Open( m_lpSession, &m_lpMdb)) {
    // Successful open, do the iteration of the store
    pVal = GetMapiProperty( m_lpMdb, PR_IPM_SUBTREE_ENTRYID);
    if (pVal) {
      ULONG      cbEntry;
      LPENTRYID    pEntry;
      LPMAPIFOLDER  lpSubTree = NULL;

      if (GetEntryIdFromProp( pVal, cbEntry, pEntry)) {
        // Open up the folder!
        bResult = OpenEntry( cbEntry, pEntry, (LPUNKNOWN *)&lpSubTree);
        MAPIFreeBuffer( pEntry);
        if (bResult && lpSubTree) {
          // Iterate the subtree with the results going into the folder list
          CGetStoreFoldersIter iterHandler( this, folders, startDepth);
          bResult = IterateHierarchy( &iterHandler, lpSubTree);
          lpSubTree->Release();
        }
        else {
          MAPI_TRACE0( "GetStoreFolders: Error opening sub tree.\n");
        }
      }
      else {
        MAPI_TRACE0( "GetStoreFolders: Error getting entryID from sub tree property val.\n");
      }
    }
    else {
      MAPI_TRACE0( "GetStoreFolders: Error getting sub tree property.\n");
    }
  }
  else {
    MAPI_TRACE0( "GetStoreFolders: Error opening message store.\n");
  }

  return( bResult);
}
Esempio n. 6
0
BOOL CMapiApi::GetStringFromProp( LPSPropValue pVal, nsString& val, BOOL delVal)
{
  BOOL bResult = TRUE;
  if ( pVal && (PROP_TYPE( pVal->ulPropTag) == PT_STRING8)) {
    CStrToUnicode( (const char *)pVal->Value.lpszA, val);
  }
  else if ( pVal && (PROP_TYPE( pVal->ulPropTag) == PT_UNICODE)) {
    val = (PRUnichar *) pVal->Value.lpszW;
  }
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_NULL)) {
    val.Truncate();
  }
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_ERROR)) {
    val.Truncate();
    bResult = FALSE;
  }
  else {
    if (pVal) {
      MAPI_TRACE1( "GetStringFromProp: invalid value, expecting string - %d\n", (int) PROP_TYPE( pVal->ulPropTag));
    }
    else {
      MAPI_TRACE0( "GetStringFromProp: invalid value, expecting string, got null pointer\n");
    }
    val.Truncate();
    bResult = FALSE;
  }
  if (pVal && delVal)
    MAPIFreeBuffer( pVal);

  return( bResult);
}
Esempio n. 7
0
BOOL CMapiApi::HandleContentsItem( ULONG oType, ULONG cb, LPENTRYID pEntry)
{
  if (oType == MAPI_MESSAGE) {
    LPMESSAGE pMsg;
    if (OpenEntry( cb, pEntry, (LPUNKNOWN *) &pMsg)) {
      LPSPropValue pVal;
      pVal = GetMapiProperty( pMsg, PR_SUBJECT);
      ReportStringProp( "PR_SUBJECT:", pVal);
      pVal = GetMapiProperty( pMsg, PR_DISPLAY_BCC);
      ReportStringProp( "PR_DISPLAY_BCC:", pVal);
      pVal = GetMapiProperty( pMsg, PR_DISPLAY_CC);
      ReportStringProp( "PR_DISPLAY_CC:", pVal);
      pVal = GetMapiProperty( pMsg, PR_DISPLAY_TO);
      ReportStringProp( "PR_DISPLAY_TO:", pVal);
      pVal = GetMapiProperty( pMsg, PR_MESSAGE_CLASS);
      ReportStringProp( "PR_MESSAGE_CLASS:", pVal);
      ListProperties( pMsg);
      pMsg->Release();
    }
    else {
      MAPI_TRACE0( "    Folder type - error opening\n");
    }
  }
  else
    MAPI_TRACE1( "    ObjectType: %ld\n", oType);

  return( TRUE);
}
Esempio n. 8
0
CMsgStore *  CMapiApi::FindMessageStore( ULONG cbEid, LPENTRYID lpEid)
{
  if (!m_lpSession) {
    MAPI_TRACE0( "FindMessageStore called before session is open\n");
    m_lastError = -1;
    return( NULL);
  }

  ULONG    result;
  HRESULT    hr;
  CMsgStore *  pStore;
  for (int i = 0; i < m_pStores->Count(); i++) {
    pStore = (CMsgStore *) m_pStores->ElementAt( i);
    hr = m_lpSession->CompareEntryIDs( cbEid, lpEid, pStore->GetCBEntryID(), pStore->GetLPEntryID(),
                      0, &result);
    if (HR_FAILED( hr)) {
      MAPI_TRACE2( "CompareEntryIDs failed: 0x%lx, %d\n", (long)hr, (int)hr);
      m_lastError = hr;
      return( NULL);
    }
    if ( result) {
      return( pStore);
    }
  }

  pStore = new CMsgStore( cbEid, lpEid);
  AddMessageStore( pStore);
  return( pStore);
}
Esempio n. 9
0
void CMapiApi::ListProperties( LPMAPIPROP lpProp, BOOL getValues)
{
  LPSPropTagArray    pArray;
  HRESULT        hr = lpProp->GetPropList( 0, &pArray);
  if (FAILED(hr)) {
    MAPI_TRACE0( "    Unable to retrieve property list\n");
    return;
  }
  ULONG count = 0;
  LPMAPINAMEID FAR * lppPropNames;
  SPropTagArray    tagArray;
  LPSPropTagArray lpTagArray = &tagArray;
  tagArray.cValues = (ULONG)1;
  nsCString  desc;
  for (ULONG i = 0; i < pArray->cValues; i++) {
    GetPropTagName( pArray->aulPropTag[i], desc);
    if (getValues) {
      tagArray.aulPropTag[0] = pArray->aulPropTag[i];
      hr = lpProp->GetNamesFromIDs(&lpTagArray, nsnull, 0, &count, &lppPropNames);
      if (hr == S_OK)
        MAPIFreeBuffer(lppPropNames);

      LPSPropValue pVal = GetMapiProperty( lpProp, pArray->aulPropTag[i]);
      if (pVal) {
        desc += ", ";
        ListPropertyValue( pVal, desc);
        MAPIFreeBuffer( pVal);
      }
    }
    MAPI_TRACE2( "    Tag #%d: %s\n", (int)i, (const char *)desc);
  }

  MAPIFreeBuffer( pArray);
}
Esempio n. 10
0
BOOL CMapiApi::OpenEntry( ULONG cbEntry, LPENTRYID pEntryId, LPUNKNOWN *ppOpen)
{
  if (!m_lpMdb) {
    MAPI_TRACE0( "OpenEntry called before the message store is open\n");
    return( FALSE);
  }

  return( OpenMdbEntry( m_lpMdb, cbEntry, pEntryId, ppOpen));
}
Esempio n. 11
0
BOOL CMapiApi::OpenStore( ULONG cbEid, LPENTRYID lpEid, LPMDB *ppMdb)
{
  if (!m_lpSession) {
    MAPI_TRACE0( "OpenStore called before a session was opened\n");
    return( FALSE);
  }

  CMsgStore *    pStore = FindMessageStore( cbEid, lpEid);
  if (pStore && pStore->Open( m_lpSession, ppMdb))
    return( TRUE);
  return( FALSE);
}
Esempio n. 12
0
LONG CMapiApi::GetLongFromProp( LPSPropValue pVal, BOOL delVal)
{
  LONG val = 0;
  if ( pVal && (PROP_TYPE( pVal->ulPropTag) == PT_LONG)) {
    val = pVal->Value.l;
  }
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_NULL)) {
    val = 0;
  }
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_ERROR)) {
    val = 0;
    MAPI_TRACE0( "GetLongFromProp: Error retrieving property\n");
  }
  else {
    MAPI_TRACE0( "GetLongFromProp: invalid value, expecting long\n");
  }
  if (pVal && delVal)
    MAPIFreeBuffer( pVal);

  return( val);
}
Esempio n. 13
0
BOOL CMapiMessage::FetchHeaders( void)
{
  LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS);
  if (pVal && CMapiApi::IsLargeProperty( pVal)) {
    m_headers.Truncate();
    CMapiApi::GetLargeStringProperty( m_lpMsg, PR_TRANSPORT_MESSAGE_HEADERS, m_headers);
  }
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) {
    m_headers = pVal->Value.LPSZ;
  }
  else {
    // Need to build the headers from the other stuff
    m_headers.Truncate();
    BuildHeaders();
  }

  if (pVal)
    CMapiApi::MAPIFreeBuffer( pVal);

  m_fromLine.Truncate();
  if (NeedsFromLine()) {
    BuildFromLine();
  }

  if (!m_fromLine.IsEmpty()) {
    MAPI_DUMP_STRING(m_fromLine.get());
  }
  MAPI_DUMP_STRING(m_headers.get());
  MAPI_TRACE0("\r\n");

  ProcessHeaders();

  if (!m_headers.IsEmpty()) {
    if (!m_bHasSubject)
      AddSubject( m_headers);
    if (!m_bHasFrom)
      AddFrom( m_headers);
    if (!m_bHasDate)
      AddDate( m_headers);
    m_headers.Trim( kWhitespace, PR_FALSE, PR_TRUE);
    m_headers += "\x0D\x0A";
  }

  return( !m_headers.IsEmpty());
}
Esempio n. 14
0
BOOL CMapiApi::Initialize( void)
{
  if (m_initialized)
    return( TRUE);

  HRESULT    hr;

  hr = MAPIInitialize( NULL);

  if (FAILED(hr)) {
    MAPI_TRACE2( "MAPI Initialize failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  m_initialized = TRUE;
  MAPI_TRACE0( "MAPI Initialized\n");

  return( TRUE);
}
Esempio n. 15
0
BOOL CMapiApi::HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry)
{
  if (oType == MAPI_FOLDER) {
    LPMAPIFOLDER pFolder;
    if (OpenEntry( cb, pEntry, (LPUNKNOWN *) &pFolder)) {
      LPSPropValue pVal;
      pVal = GetMapiProperty( pFolder, PR_DISPLAY_NAME);
      ReportStringProp( "Folder name:", pVal);
      IterateContents( NULL, pFolder);
      IterateHierarchy( NULL, pFolder);
      pFolder->Release();
    }
    else {
      MAPI_TRACE0( "    Folder type - error opening\n");
    }
  }
  else
    MAPI_TRACE1( "    ObjectType: %ld\n", oType);

  return( TRUE);
}
Esempio n. 16
0
BOOL CMapiMessage::FetchBody( void)
{
  m_bodyIsHtml = FALSE;
  m_body.Truncate();
  // Is it html?
  LPSPropValue pVal = CMapiApi::GetMapiProperty( m_lpMsg, 0x1013001e);
  if (pVal && CMapiApi::IsLargeProperty( pVal))
    CMapiApi::GetLargeStringProperty( m_lpMsg, 0x1013001e, m_body);
  else if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ)))
    m_body = pVal->Value.LPSZ;

  // kind-hearted Outlook will give us html even for a plain text message. But it will include
  // a comment saying it did the conversion. We'll use this as a hack to really use
  // the plain text part.
  if (!m_body.IsEmpty() && m_body.Find("<!-- Converted from text/plain format -->") == kNotFound)
    m_bodyIsHtml = TRUE;
  else
  {
    pVal = CMapiApi::GetMapiProperty( m_lpMsg, PR_BODY);
    if (pVal)
    {
      if (pVal && CMapiApi::IsLargeProperty( pVal)) {
        CMapiApi::GetLargeStringProperty( m_lpMsg, PR_BODY, m_body);
      }
      else {
        if (pVal && (PROP_TYPE( pVal->ulPropTag) == PT_TSTRING) && (pVal->Value.LPSZ) && (*(pVal->Value.LPSZ))) {
          m_body = pVal->Value.LPSZ;
        }
      }
    }
  }

  if (pVal)
    CMapiApi::MAPIFreeBuffer( pVal);

  MAPI_DUMP_STRING(m_body.get());
  MAPI_TRACE0("\r\n");

  return( TRUE);
}
Esempio n. 17
0
BOOL CGetStoreFoldersIter::HandleHierarchyItem( ULONG oType, ULONG cb, LPENTRYID pEntry)
{
  if (oType == MAPI_FOLDER) {
    LPMAPIFOLDER pFolder;
    if (m_pApi->OpenEntry( cb, pEntry, (LPUNKNOWN *) &pFolder)) {
      LPSPropValue    pVal;
      nsString      name;

      pVal = m_pApi->GetMapiProperty( pFolder, PR_CONTAINER_CLASS);
      if (pVal)
        m_pApi->GetStringFromProp( pVal, name);
      else
        name.Truncate();

      if ((name.IsEmpty() && m_isMail) || (!ExcludeFolderClass(name.get()))) {
        pVal = m_pApi->GetMapiProperty( pFolder, PR_DISPLAY_NAME);
        m_pApi->GetStringFromProp( pVal, name);
        CMapiFolder  *pNewFolder = new CMapiFolder(name.get(), cb, pEntry, m_depth);
        m_pList->AddItem( pNewFolder);

        pVal = m_pApi->GetMapiProperty( pFolder, PR_FOLDER_TYPE);
        MAPI_TRACE2( "Type: %d, name: %s\n", m_pApi->GetLongFromProp( pVal), (const char *)name);
        // m_pApi->ListProperties( pFolder);

        CGetStoreFoldersIter  nextIter( m_pApi, *m_pList, m_depth + 1, m_isMail);
        m_pApi->IterateHierarchy( &nextIter, pFolder);
      }
      pFolder->Release();
    }
    else {
      MAPI_TRACE0( "GetStoreFolders - HandleHierarchyItem: Error opening folder entry.\n");
      return( FALSE);
    }
  }
  else
    MAPI_TRACE1( "GetStoreFolders - HandleHierarchyItem: Unhandled ObjectType: %ld\n", oType);
  return( TRUE);
}
Esempio n. 18
0
// If the value is a string, get it...
BOOL CMapiApi::GetEntryIdFromProp( LPSPropValue pVal, ULONG& cbEntryId, LPENTRYID& lpEntryId, BOOL delVal)
{
  if (!pVal)
    return( FALSE);

  BOOL bResult = TRUE;
    switch( PROP_TYPE( pVal->ulPropTag)) {
    case PT_BINARY:
      cbEntryId = pVal->Value.bin.cb;
      MAPIAllocateBuffer( cbEntryId, (LPVOID *) &lpEntryId);
      memcpy( lpEntryId, pVal->Value.bin.lpb, cbEntryId);
    break;

    default:
      MAPI_TRACE0( "EntryId not in BINARY prop value\n");
      bResult = FALSE;
        break;
    }

  if (pVal && delVal)
    MAPIFreeBuffer( pVal);

  return( bResult);
}
Esempio n. 19
0
BOOL CMapiApi::IterateStores( CMapiFolderList& stores)
{
  stores.ClearAll();

  if (!m_lpSession) {
    MAPI_TRACE0( "IterateStores called before session is open\n");
    m_lastError = -1;
    return( FALSE);
  }


  HRESULT    hr;

  /* -- Some Microsoft sample code just to see if things are working --- *//*

  ULONG    cbEIDStore;
  LPENTRYID  lpEIDStore;

    hr = HrMAPIFindDefaultMsgStore( m_lpSession, &cbEIDStore, &lpEIDStore);
    if (HR_FAILED(hr)) {
        MAPI_TRACE0( "Default message store not found\n");
    // MessageBox(NULL,"Message Store Not Found",NULL,MB_OK);
    }
  else {
    LPMDB  lpStore;
    MAPI_TRACE0( "Default Message store FOUND\n");
    hr = m_lpSession->OpenMsgStore( NULL, cbEIDStore,
                                  lpEIDStore, NULL,
                                  MDB_NO_MAIL | MDB_NO_DIALOG, &lpStore);
    if (HR_FAILED(hr)) {
      MAPI_TRACE1( "Unable to open default message store: 0x%lx\n", hr);
    }
    else {
      MAPI_TRACE0( "Default message store OPENED\n");
      lpStore->Release();
    }
   }
     */



  LPMAPITABLE  lpTable;

  hr = m_lpSession->GetMsgStoresTable( 0, &lpTable);
  if (FAILED(hr)) {
    MAPI_TRACE0( "GetMsgStoresTable failed\n");
    m_lastError = hr;
    return( FALSE);
  }


  ULONG rowCount;
  hr = lpTable->GetRowCount( 0, &rowCount);
  MAPI_TRACE1( "MsgStores Table rowCount: %ld\n", rowCount);

  hr = lpTable->SetColumns( (LPSPropTagArray)&ptaTbl, 0);
  if (FAILED(hr)) {
    lpTable->Release();
    MAPI_TRACE2( "SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr);
    m_lastError = hr;
    return( FALSE);
  }

  hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL);
  if (FAILED(hr)) {
    lpTable->Release();
    MAPI_TRACE2( "SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr);
    m_lastError = hr;
    return( FALSE);
  }

  int      cNumRows = 0;
  LPSRowSet  lpRow;
  BOOL    keepGoing = TRUE;
  BOOL    bResult = TRUE;
  do {

    lpRow = NULL;
    hr = lpTable->QueryRows( 1, 0, &lpRow);

        if(HR_FAILED(hr)) {
      MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr);
            bResult = FALSE;
      m_lastError = hr;
      break;
    }

        if(lpRow) {
            cNumRows = lpRow->cRows;

        if (cNumRows) {
        LPCTSTR    lpStr = (LPCTSTR) lpRow->aRow[0].lpProps[itblPR_DISPLAY_NAME].Value.LPSZ;
                LPENTRYID  lpEID = (LPENTRYID) lpRow->aRow[0].lpProps[itblPR_ENTRYID].Value.bin.lpb;
                ULONG    cbEID = lpRow->aRow[0].lpProps[itblPR_ENTRYID].Value.bin.cb;

        // In the future, GetStoreInfo needs to somehow return
        // whether or not the store is from an IMAP server.
        // Currently, GetStoreInfo opens the store and attempts
        // to get the hierarchy tree.  If the tree is empty or
        // does not exist, then szContents will be zero.  We'll
        // assume that any store that doesn't have anything in
        // it's hierarchy tree is not a store we want to import -
        // there would be nothing to import from anyway!
        // Currently, this does exclude IMAP server accounts
        // which is the desired behaviour.

                int         strLen = strlen(lpStr);
                PRUnichar * pwszStr = (PRUnichar *) nsMemory::Alloc((strLen + 1) * sizeof(WCHAR));
                if (!pwszStr) {
                    // out of memory
                    FreeProws( lpRow);
                    lpTable->Release();
                    return FALSE;
                }
                ::MultiByteToWideChar(CP_ACP, 0, lpStr, strlen(lpStr) + 1, pwszStr, (strLen + 1) * sizeof(WCHAR));
        CMapiFolder *pFolder = new CMapiFolder( pwszStr, cbEID, lpEID, 0, MAPI_STORE);
                nsMemory::Free(pwszStr);

        long szContents = 1;
         GetStoreInfo( pFolder, &szContents);

        MAPI_TRACE1( "    DisplayName: %s\n", lpStr);
        if (szContents) {
          stores.AddItem( pFolder);
        }
        else {
          delete pFolder;
          MAPI_TRACE0( "    ^^^^^ Not added to store list\n");
        }

        keepGoing = TRUE;
        }
      FreeProws( lpRow);
        }

  } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing);

  lpTable->Release();

  return( bResult);
}
Esempio n. 20
0
bool CMapiMessage::AddAttachment(DWORD aNum)
{
  LPATTACH lpAttach = NULL;
  HRESULT hr = m_lpMsg->OpenAttach(aNum, NULL, 0, &lpAttach);
  if (HR_FAILED(hr)) {
    MAPI_TRACE2("\t\t****Attachment error, unable to open attachment: %d, 0x%lx\r\n", idx, hr);
    return false;
  }

  bool bResult = false;
  attach_data *data = new attach_data;
  ULONG aMethod;
  if (data) {
    bResult = true;

    // 1. Get the file that contains the attachment data
    LPSPropValue pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_METHOD);
    if (pVal) {
      aMethod = CMapiApi::GetLongFromProp(pVal);
      switch (aMethod) {
      case ATTACH_BY_VALUE:
        MAPI_TRACE1("\t\t** Attachment #%d by value.\r\n", aNum);
        bResult = CopyBinAttachToFile(lpAttach, getter_AddRefs(data->tmp_file));
        data->delete_file = true;
        break;
      case ATTACH_BY_REFERENCE:
      case ATTACH_BY_REF_RESOLVE:
      case ATTACH_BY_REF_ONLY:
        pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_PATHNAME_W);
        if (pVal) {
          nsCString path;
          CMapiApi::GetStringFromProp(pVal, path);
          nsresult rv;
          data->tmp_file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
          if (NS_FAILED(rv) || !data->tmp_file) {
            MAPI_TRACE0("*** Error creating file spec for attachment\n");
            bResult = false;
          }
          else data->tmp_file->InitWithNativePath(path);
        }
        MAPI_TRACE2("\t\t** Attachment #%d by ref: %s\r\n",
          aNum, m_attachPath.get());
        break;
      case ATTACH_EMBEDDED_MSG:
        MAPI_TRACE1("\t\t** Attachment #%d by Embedded Message??\r\n", aNum);
        // Convert the embedded IMessage from PR_ATTACH_DATA_OBJ to rfc822 attachment
        // (see http://msdn.microsoft.com/en-us/library/cc842329.aspx)
        // This is a recursive call.
        bResult = CopyMsgAttachToFile(lpAttach, getter_AddRefs(data->tmp_file));
        data->delete_file = true;
        break;
      case ATTACH_OLE:
        MAPI_TRACE1("\t\t** Attachment #%d by OLE - yuck!!!\r\n", aNum);
        break;
      default:
        MAPI_TRACE2("\t\t** Attachment #%d unknown attachment method - 0x%lx\r\n", aNum, aMethod);
        bResult = false;
      }
    }
    else
      bResult = false;

    if (bResult)
      bResult = data->tmp_file;

    if (bResult) {
      bool isFile = false;
      bool exists = false;
      data->tmp_file->Exists(&exists);
      data->tmp_file->IsFile(&isFile);

      if (!exists || !isFile) {
        bResult = false;
        MAPI_TRACE0("Attachment file does not exist\n");
      }
    }

    if (bResult)
      bResult = GetURL(data->tmp_file, getter_AddRefs(data->orig_url));

    if (bResult) {
      // Now we have the file; proceed to the other properties

      data->encoding = NS_strdup(ENCODING_BINARY);

      nsString fname, fext;
      pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_LONG_FILENAME_W);
      if (!pVal)
        pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_FILENAME_W);
      CMapiApi::GetStringFromProp(pVal, fname);
      pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_EXTENSION_W);
      CMapiApi::GetStringFromProp(pVal, fext);
      MAPI_TRACE2("\t\t\t--- File name: %s, extension: %s\r\n",
        fname.get(), fext.get());

      if (fext.IsEmpty()) {
        int idx = fname.RFindChar(L'.');
        if (idx != -1)
          fext = Substring(fname, idx);
      }
      else if (fname.RFindChar(L'.') == -1) {
        fname += L".";
        fname += fext;
      }
      if (fname.IsEmpty()) {
        // If no description use "Attachment i" format.
        fname = L"Attachment ";
        fname.AppendInt(static_cast<uint32_t>(aNum));
      }
      data->real_name = ToNewUTF8String(fname);

      nsCString tmp;
       // We have converted it to the rfc822 document
      if (aMethod == ATTACH_EMBEDDED_MSG) {
        data->type = NS_strdup(MESSAGE_RFC822);
      } else {
        pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_MIME_TAG_A);
        CMapiApi::GetStringFromProp(pVal, tmp);
        MAPI_TRACE1("\t\t\t--- Mime type: %s\r\n", tmp.get());
        if (tmp.IsEmpty()) {
          uint8_t *pType = NULL;
          if (!fext.IsEmpty()) {
            pType = CMimeTypes::GetMimeType(fext);
          }
          if (pType)
            data->type = NS_strdup((PC_S8)pType);
          else
            data->type = NS_strdup(APPLICATION_OCTET_STREAM);
        }
        else
          data->type = ToNewCString(tmp);
      }

      pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_CONTENT_ID_A);
      CMapiApi::GetStringFromProp(pVal, tmp);
      if (!tmp.IsEmpty())
        data->cid = ToNewCString(tmp);
    }
    if (bResult) {
      // Now we need to decide if this attachment is embedded or not.
      // At first, I tried to simply check for the presence of the Content-Id.
      // But it turned out that this method is unreliable, since there exist cases
      // when an attachment has a Content-Id while isn't embedded (even in a message
      // with a plain-text body!). So next I tried to look for <img> tags that contain
      // the found Content-Id. But this is unreliable, too, because there exist cases
      // where other places of HTML reference the embedded messages (e.g. it may be
      // a background of a table cell, or some CSS; further, it is possible that the
      // reference to an embedded object is not in the main body, but in another
      // embedded object - like body references a CSS attachment that in turn references
      // a picture as a background of its element). From the other hand, it's unreliable
      // to relax the search criteria to any occurence of the Content-Id string in the body -
      // partly because the string may be simply in a text or other non-referencing part,
      // partly because of the abovementioned possibility that the reference is outside
      // the body at all.
      // There exist the PR_ATTACH_FLAGS property of the attachment. The MS documentation
      // tells about two possible flags in it: ATT_INVISIBLE_IN_HTML and ATT_INVISIBLE_IN_RTF.
      // There is at least one more undocumented flag: ATT_MHTML_REF. Some sources in Internet
      // suggest simply check for the latter flag to distinguish between the embedded
      // and ordinary attachments. But my observations indicate that even if the flags
      // don't include ATT_MHTML_REF, the attachment is still may be embedded.
      // However, my observations always show that the message is embedded if the flags
      // is not 0.
      // So now I will simply test for the non-zero flags to decide whether the attachment
      // is embedded or not. Possible advantage is reliability (I hope).
      // Another advantage is that it's much faster than search the body for Content-Id.

      DWORD flags = 0;

      pVal = CMapiApi::GetMapiProperty(lpAttach, PR_ATTACH_FLAGS);
      if (pVal)
        flags = CMapiApi::GetLongFromProp(pVal);
      if (m_bodyIsHtml && data->cid && (flags != 0)) // this is the embedded attachment
        m_embattachments.push_back(data);
      else // this is ordinary attachment
        m_stdattachments.push_back(data);
    }
    else {
      delete data;
    }
  }

  lpAttach->Release();
  return bResult;
}
Esempio n. 21
0
BOOL CMapiApi::IterateContents( CMapiContentIter *pIter, LPMAPIFOLDER pFolder, ULONG flags)
{
  // flags can be 0 or MAPI_ASSOCIATED
  // MAPI_ASSOCIATED is usually used for forms and views

  HRESULT    hr;
  LPMAPITABLE  lpTable;
  hr = pFolder->GetContentsTable( flags, &lpTable);
  if (FAILED(hr)) {
    MAPI_TRACE2( "GetContentsTable failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  ULONG rowCount;
  hr = lpTable->GetRowCount( 0, &rowCount);
  if (!rowCount) {
    MAPI_TRACE0( "  Empty Table\n");
  }

  hr = lpTable->SetColumns( (LPSPropTagArray)&ptaEid, 0);
  if (FAILED(hr)) {
    lpTable->Release();
    MAPI_TRACE2( "SetColumns failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  hr = lpTable->SeekRow( BOOKMARK_BEGINNING, 0, NULL);
  if (FAILED(hr)) {
    lpTable->Release();
    MAPI_TRACE2( "SeekRow failed: 0x%lx, %d\n", (long)hr, (int)hr);
    return( FALSE);
  }

  int      cNumRows = 0;
  LPSRowSet  lpRow;
  BOOL    keepGoing = TRUE;
  BOOL    bResult = TRUE;
  do {
    lpRow = NULL;
    hr = lpTable->QueryRows( 1, 0, &lpRow);
    if(HR_FAILED(hr)) {
      MAPI_TRACE2( "QueryRows failed: 0x%lx, %d\n", (long)hr, (int)hr);
      bResult = FALSE;
      break;
    }

    if(lpRow) {
      cNumRows = lpRow->cRows;
      if (cNumRows) {
        LPENTRYID  lpEID = (LPENTRYID) lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.lpb;
        ULONG    cbEID = lpRow->aRow[0].lpProps[ieidPR_ENTRYID].Value.bin.cb;
        ULONG    oType = lpRow->aRow[0].lpProps[ieidPR_OBJECT_TYPE].Value.ul;
        keepGoing = HandleContentsItem( oType, cbEID, lpEID);
        MAPI_TRACE1( "    ObjectType: %ld\n", oType);
      }
      FreeProws( lpRow);
    }

  } while ( SUCCEEDED(hr) && cNumRows && lpRow && keepGoing);

  lpTable->Release();
  return( bResult);
}
Esempio n. 22
0
BOOL CMapiMessage::CopyBinAttachToFile( LPATTACH lpAttach)
{
  LPSTREAM lpStreamFile;

  m_ownsAttachFile = FALSE;
  m_attachPath.Truncate();

  nsCOMPtr<nsIFile> tmpFile;
  nsresult rv = GetSpecialDirectoryWithFileName(NS_OS_TEMP_DIR,
    "mapiattach.tmp",
    getter_AddRefs(tmpFile));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 00600);
  NS_ENSURE_SUCCESS(rv, rv);

  nsCString tmpPath;
  tmpFile->GetNativePath(tmpPath);
  HRESULT hr = CMapiApi::OpenStreamOnFile( gpMapiAllocateBuffer, gpMapiFreeBuffer, STGM_READWRITE | STGM_CREATE,
    (char *) tmpPath.get(), NULL, &lpStreamFile);
  if (HR_FAILED(hr)) {
    MAPI_TRACE1("~~ERROR~~ OpenStreamOnFile failed - temp path: %s\r\n",
                tmpPath.get());
    return( FALSE);
  }
  MAPI_TRACE1("\t\t** Attachment extracted to temp file: %s\r\n",
              m_attachPath.get());

  BOOL bResult = TRUE;
  LPSTREAM lpAttachStream;
  hr = lpAttach->OpenProperty( PR_ATTACH_DATA_BIN, &IID_IStream, 0, 0, (LPUNKNOWN *)&lpAttachStream);

  if (HR_FAILED( hr)) {
    MAPI_TRACE0( "~~ERROR~~ OpenProperty failed for PR_ATTACH_DATA_BIN.\r\n");
    lpAttachStream = NULL;
    bResult = FALSE;
  }
  else {
    STATSTG st;
    hr = lpAttachStream->Stat( &st, STATFLAG_NONAME);
    if (HR_FAILED( hr)) {
      MAPI_TRACE0( "~~ERROR~~ Stat failed for attachment stream\r\n");
      bResult = FALSE;
    }
    else {
      hr = lpAttachStream->CopyTo( lpStreamFile, st.cbSize, NULL, NULL);
      if (HR_FAILED( hr)) {
        MAPI_TRACE0( "~~ERROR~~ Attach Stream CopyTo temp file failed.\r\n");
        bResult = FALSE;
      }
    }
  }

  m_attachPath = tmpPath;
  if (lpAttachStream)
    lpAttachStream->Release();
  lpStreamFile->Release();
  if (!bResult)
    tmpFile->Remove(PR_FALSE);
  else
    m_ownsAttachFile = TRUE;

  return( bResult);
}
Esempio n. 23
0
bool CMapiMessage::FetchBody(void)
{
  m_bodyIsHtml = false;
  m_body.Truncate();

  // Get the Outlook codepage info; if unsuccessful then it defaults to 0 (CP_ACP) -> system default
  // Maybe we can use this info later?
  unsigned int codepage=0;
  LPSPropValue pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_INTERNET_CPID);
  if (pVal) {
    if (PROP_TYPE(pVal->ulPropTag) == PT_LONG)
      codepage = pVal->Value.l;
    CMapiApi::MAPIFreeBuffer(pVal);
  }

  unsigned long nativeBodyType = 0;
  if (CMapiApi::GetRTFPropertyDecodedAsUTF16(m_lpMsg, m_body, nativeBodyType,
                                             codepage)) {
    m_bodyIsHtml = nativeBodyType == MAPI_NATIVE_BODY_TYPE_HTML;
  }
  else { // Cannot get RTF version
    // Is it html?
    pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_HTML_W);
    if (pVal) {
      if (CMapiApi::IsLargeProperty(pVal))
        CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_HTML_W, m_body);
      else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) &&
               (pVal->Value.lpszW) && (*(pVal->Value.lpszW)))
        m_body.Assign(pVal->Value.lpszW);
      CMapiApi::MAPIFreeBuffer(pVal);
    }

    // Kind-hearted Outlook will give us html even for a plain text message.
    // But it will include a comment saying it did the conversion.
    // We'll use this as a hack to really use the plain text part.
    //
    // Sadly there are cases where this string is returned despite the fact
    // that the message is indeed HTML.
    //
    // To detect the "true" plain text messages, we look for our string
    // immediately following the <BODY> tag.
    if (!m_body.IsEmpty() &&
        m_body.Find("<BODY>\r\n<!-- Converted from text/plain format -->") ==
        kNotFound) {
      m_bodyIsHtml = true;
    }
    else {
      pVal = CMapiApi::GetMapiProperty(m_lpMsg, PR_BODY_W);
      if (pVal) {
        if (CMapiApi::IsLargeProperty(pVal))
          CMapiApi::GetLargeStringProperty(m_lpMsg, PR_BODY_W, m_body);
        else if ((PROP_TYPE(pVal->ulPropTag) == PT_UNICODE) &&
                 (pVal->Value.lpszW) && (*(pVal->Value.lpszW)))
          m_body.Assign(pVal->Value.lpszW);
        CMapiApi::MAPIFreeBuffer(pVal);
      }
    }
  }

  // OK, now let's restore the original encoding!
  // 1. We may have a header defining the charset (we already called the FetchHeaders(), and there ProcessHeaders();
  //    in this case, the m_mimeCharset is set. See nsOutlookMail::ImportMailbox())
  // 2. We may have the codepage walue provided by Outlook ("codepage" at the very beginning of this function)
  // 3. We may have an HTML charset header.

  bool bFoundCharset = false;

  if (!m_mimeCharset.IsEmpty()) // The top-level header data
    bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get());
  // No valid charset in the message header - try the HTML header.
  // arguably may be useless
  if (!bFoundCharset && m_bodyIsHtml) {
    ExtractMetaCharset(m_body.get(), m_body.Length(), m_mimeCharset);
    if (!m_mimeCharset.IsEmpty())
      bFoundCharset = CheckBodyInCharsetRange(m_mimeCharset.get());
  }
  // Get from Outlook (seems like it keeps the MIME part header encoding info)
  if (!bFoundCharset && codepage) {
    const char* charset = CpToCharset(codepage);
    if (charset) {
      bFoundCharset = CheckBodyInCharsetRange(charset);
      if (bFoundCharset)
        m_mimeCharset.Assign(charset);
    }
  }
  if (!bFoundCharset) { // Use system default
    const char* charset = nsMsgI18NFileSystemCharset();
    if (charset) {
      bFoundCharset = CheckBodyInCharsetRange(charset);
      if (bFoundCharset)
        m_mimeCharset.Assign(charset);
    }
  }
  if (!bFoundCharset) // Everything else failed, let's use the lossless utf-8...
    m_mimeCharset.Assign("utf-8");

  MAPI_DUMP_STRING(m_body.get());
  MAPI_TRACE0("\r\n");

  return true;
}