You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
876 lines
22 KiB
876 lines
22 KiB
#include "pch.hxx"
|
|
#include <mapi.h>
|
|
#include <mapix.h>
|
|
#include <imnapi.h>
|
|
#include <newimp.h>
|
|
#include <impapi.h>
|
|
#include <import.h>
|
|
#include "mapiconv.h"
|
|
#include <dllmain.h>
|
|
#include <shlwapi.h>
|
|
#include <strconst.h>
|
|
|
|
#define INITGUID
|
|
#define USES_IID_IMessage
|
|
#define USES_IID_IMAPIFolder
|
|
|
|
#include <ole2.h>
|
|
#include <initguid.h>
|
|
#include <MAPIGUID.H>
|
|
|
|
ASSERTDATA
|
|
|
|
static const TCHAR c_szMapi32Dll[] = TEXT("mapi32.dll");
|
|
|
|
const static TCHAR szMAPILogonEx[] = TEXT("MAPILogonEx");
|
|
const static TCHAR szMAPIInitialize[] = TEXT("MAPIInitialize");
|
|
const static TCHAR szMAPIUninitialize[] = TEXT("MAPIUninitialize");
|
|
const static TCHAR szMAPIFreeBuffer[] = TEXT("MAPIFreeBuffer");
|
|
const static TCHAR szMAPIAllocateBuffer[] = TEXT("MAPIAllocateBuffer");
|
|
const static TCHAR szMAPIAllocateMore[] = TEXT("MAPIAllocateMore");
|
|
const static TCHAR szMAPIAdminProfiles[] = TEXT("MAPIAdminProfiles");
|
|
const static TCHAR szFreeProws[] = TEXT("FreeProws@4");
|
|
const static TCHAR szHrQueryAllRows[] = TEXT("HrQueryAllRows@24");
|
|
const static TCHAR szWrapCompressedRTFStream[] = TEXT("WrapCompressedRTFStream");
|
|
|
|
static char g_szDefClient[MAX_PATH];
|
|
|
|
HMODULE g_hlibMAPI = NULL;
|
|
|
|
LPMAPILOGONEX lpMAPILogonEx = NULL;
|
|
LPMAPIINITIALIZE lpMAPIInitialize = NULL;
|
|
LPMAPIUNINITIALIZE lpMAPIUninitialize = NULL;
|
|
LPMAPIFREEBUFFER lpMAPIFreeBuffer = NULL;
|
|
LPMAPIALLOCATEBUFFER lpMAPIAllocateBuffer = NULL;
|
|
LPMAPIALLOCATEMORE lpMAPIAllocateMore = NULL;
|
|
LPMAPIADMINPROFILES lpMAPIAdminProfiles = NULL;
|
|
LPFREEPROWS lpFreeProws = NULL;
|
|
LPHRQUERYALLROWS lpHrQueryAllRows = NULL;
|
|
LPWRAPCOMPRESSEDRTFSTREAM lpWrapCompressedRTFStream = NULL;
|
|
|
|
HRESULT GetSubFolderList(LPMAPICONTAINER pcont, IMPFOLDERNODE **ppnode, IMPFOLDERNODE *pparent);
|
|
HRESULT ExchGetFolderList(HWND hwnd, IMAPISession *pmapi, IMPFOLDERNODE **pplist);
|
|
void ExchFreeFolderList(IMPFOLDERNODE *pnode);
|
|
VOID ExchFreeImsg(LPIMSG lpImsg);
|
|
|
|
static BOOL g_fMapiInit = FALSE;
|
|
|
|
CExchImport::CExchImport()
|
|
{
|
|
DllAddRef();
|
|
|
|
m_cRef = 1;
|
|
m_plist = NULL;
|
|
m_pmapi = NULL;
|
|
}
|
|
|
|
CExchImport::~CExchImport()
|
|
{
|
|
if (m_plist != NULL)
|
|
ExchFreeFolderList(m_plist);
|
|
|
|
if (m_pmapi != NULL)
|
|
{
|
|
m_pmapi->Logoff(NULL, 0, 0);
|
|
SideAssert(0 == m_pmapi->Release());
|
|
}
|
|
|
|
DllRelease();
|
|
}
|
|
|
|
ULONG CExchImport::AddRef()
|
|
{
|
|
m_cRef++;
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
ULONG CExchImport::Release()
|
|
{
|
|
ULONG cRef;
|
|
|
|
cRef = --m_cRef;
|
|
if (cRef == 0)
|
|
delete this;
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
HRESULT CExchImport::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IMailImport == riid)
|
|
*ppv = (IMailImport *)this;
|
|
else if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else
|
|
hr = E_NOINTERFACE;
|
|
|
|
if (*ppv != NULL)
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CExchImport::InitializeImport(HWND hwnd)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (SUCCEEDED(hr = ExchInit()) && S_OK == (hr = MapiLogon(hwnd, &m_pmapi)))
|
|
{
|
|
Assert(m_pmapi != NULL);
|
|
hr = ExchGetFolderList(hwnd, m_pmapi, &m_plist);
|
|
}
|
|
|
|
if (hr == hrMapiInitFail)
|
|
{
|
|
ImpMessageBox(hwnd, MAKEINTRESOURCE(idsImportTitle),
|
|
MAKEINTRESOURCE(idsMapiImportFailed), MAKEINTRESOURCE(idsMapiInitError),
|
|
MB_OK | MB_ICONSTOP);
|
|
}
|
|
else if (hr == hrNoProfilesFound)
|
|
{
|
|
ImpMessageBox(hwnd, MAKEINTRESOURCE(idsImportTitle),
|
|
MAKEINTRESOURCE(idsMapiImportFailed), MAKEINTRESOURCE(idsNoMapiProfiles),
|
|
MB_OK | MB_ICONSTOP);
|
|
}
|
|
else if (FAILED(hr) && hr != MAPI_E_USER_CANCEL)
|
|
{
|
|
ImpMessageBox(hwnd, MAKEINTRESOURCE(idsImportTitle),
|
|
MAKEINTRESOURCE(idsMapiImportFailed), MAKEINTRESOURCE(idsGenericError),
|
|
MB_OK | MB_ICONSTOP);
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CExchImport::GetDirectory(char *szDir, UINT cch)
|
|
{
|
|
return(S_FALSE);
|
|
}
|
|
|
|
HRESULT CExchImport::SetDirectory(char *szDir)
|
|
{
|
|
Assert(FALSE);
|
|
|
|
return(E_FAIL);
|
|
}
|
|
|
|
HRESULT CExchImport::EnumerateFolders(DWORD_PTR dwCookie, IEnumFOLDERS **ppEnum)
|
|
{
|
|
CExchEnumFOLDERS *pEnum;
|
|
IMPFOLDERNODE *pnode;
|
|
|
|
Assert(ppEnum != NULL);
|
|
*ppEnum = NULL;
|
|
|
|
if (dwCookie == COOKIE_ROOT)
|
|
pnode = m_plist;
|
|
else
|
|
pnode = ((IMPFOLDERNODE *)dwCookie)->pchild;
|
|
|
|
if (pnode == NULL)
|
|
return(S_FALSE);
|
|
|
|
pEnum = new CExchEnumFOLDERS(pnode);
|
|
if (pEnum == NULL)
|
|
return(E_OUTOFMEMORY);
|
|
|
|
*ppEnum = pEnum;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
static SizedSPropTagArray(1, s_taMessage) =
|
|
{
|
|
1,
|
|
{
|
|
PR_ENTRYID,
|
|
}
|
|
};
|
|
|
|
STDMETHODIMP CExchImport::ImportFolder(DWORD_PTR dwCookie, IFolderImport *pImport)
|
|
{
|
|
IMPFOLDERNODE *pnode;
|
|
HRESULT hr;
|
|
IMSG imsg;
|
|
LPMAPITABLE ptbl;
|
|
LPMAPICONTAINER pcont;
|
|
ULONG cRow, i, ulObjType;
|
|
LPSRow lprw;
|
|
LPSPropValue lpProp;
|
|
LPSRowSet prset;
|
|
LPMESSAGE pmsg;
|
|
|
|
Assert(pImport != NULL);
|
|
|
|
pnode = (IMPFOLDERNODE *)dwCookie;
|
|
Assert(pnode != NULL);
|
|
|
|
hr = E_FAIL;
|
|
|
|
pcont = (LPMAPICONTAINER)pnode->lparam;
|
|
|
|
Assert(pcont != NULL);
|
|
|
|
hr = pcont->GetContentsTable(0, &ptbl);
|
|
if (FAILED(hr))
|
|
{
|
|
Assert(FALSE);
|
|
return(hr);
|
|
}
|
|
|
|
if (!FAILED(hr = ptbl->SetColumns((LPSPropTagArray)&s_taMessage, 0)) &&
|
|
!FAILED(hr = ptbl->GetRowCount(0, &cRow)) &&
|
|
cRow > 0)
|
|
{
|
|
pImport->SetMessageCount(cRow);
|
|
|
|
while (TRUE)
|
|
{
|
|
if(hr == hrUserCancel)
|
|
break;
|
|
if (cRow == 0)
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
hr = ptbl->QueryRows(cRow, 0, &prset);
|
|
if (FAILED(hr))
|
|
break;
|
|
if (prset->cRows == 0)
|
|
{
|
|
FreeSRowSet(prset);
|
|
break;
|
|
}
|
|
|
|
for (i = 0, lprw = prset->aRow; i < prset->cRows; i++, lprw++)
|
|
{
|
|
if(hr == hrUserCancel)
|
|
break;
|
|
|
|
lpProp = lprw->lpProps;
|
|
Assert(lpProp->ulPropTag == PR_ENTRYID);
|
|
|
|
hr = pcont->OpenEntry(lpProp->Value.bin.cb,
|
|
(LPENTRYID)lpProp->Value.bin.lpb, NULL, MAPI_BEST_ACCESS,
|
|
&ulObjType, (LPUNKNOWN *)&pmsg);
|
|
Assert(!FAILED(hr));
|
|
if (!FAILED(hr))
|
|
{
|
|
hr = HrMapiToImsg(pmsg, &imsg);
|
|
Assert(!FAILED(hr));
|
|
if (!FAILED(hr))
|
|
{
|
|
hr = pImport->ImportMessage(&imsg);
|
|
|
|
ExchFreeImsg(&imsg);
|
|
}
|
|
|
|
pmsg->Release();
|
|
}
|
|
}
|
|
|
|
Assert(prset->cRows <= cRow);
|
|
cRow -= prset->cRows;
|
|
|
|
FreeSRowSet(prset);
|
|
}
|
|
}
|
|
|
|
ptbl->Release();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
CExchEnumFOLDERS::CExchEnumFOLDERS(IMPFOLDERNODE *plist)
|
|
{
|
|
Assert(plist != NULL);
|
|
|
|
m_cRef = 1;
|
|
m_plist = plist;
|
|
m_pnext = plist;
|
|
}
|
|
|
|
CExchEnumFOLDERS::~CExchEnumFOLDERS()
|
|
{
|
|
|
|
}
|
|
|
|
ULONG CExchEnumFOLDERS::AddRef()
|
|
{
|
|
m_cRef++;
|
|
|
|
return(m_cRef);
|
|
}
|
|
|
|
ULONG CExchEnumFOLDERS::Release()
|
|
{
|
|
ULONG cRef;
|
|
|
|
cRef = --m_cRef;
|
|
if (cRef == 0)
|
|
delete this;
|
|
|
|
return(cRef);
|
|
}
|
|
|
|
HRESULT CExchEnumFOLDERS::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (ppv == NULL)
|
|
return(E_INVALIDARG);
|
|
|
|
*ppv = NULL;
|
|
|
|
if (IID_IEnumFOLDERS == riid)
|
|
*ppv = (IEnumFOLDERS *)this;
|
|
else if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else
|
|
hr = E_NOINTERFACE;
|
|
|
|
if (*ppv != NULL)
|
|
((LPUNKNOWN)*ppv)->AddRef();
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT CExchEnumFOLDERS::Next(IMPORTFOLDER *pfldr)
|
|
{
|
|
Assert(pfldr != NULL);
|
|
|
|
if (m_pnext == NULL)
|
|
return(S_FALSE);
|
|
|
|
ZeroMemory(pfldr, sizeof(IMPORTFOLDER));
|
|
pfldr->dwCookie = (DWORD_PTR)m_pnext;
|
|
StrCpyN(pfldr->szName, m_pnext->szName, ARRAYSIZE(pfldr->szName));
|
|
// pfldr->type = 0;
|
|
pfldr->fSubFolders = (m_pnext->pchild != NULL);
|
|
|
|
m_pnext = m_pnext->pnext;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT CExchEnumFOLDERS::Reset()
|
|
{
|
|
m_pnext = m_plist;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
HRESULT ExchInit(void)
|
|
{
|
|
HRESULT hr;
|
|
DWORD cb, type;
|
|
char sz[MAX_PATH];
|
|
|
|
if (g_fMapiInit)
|
|
return(S_OK);
|
|
|
|
Assert(g_hlibMAPI == NULL);
|
|
|
|
g_hlibMAPI = LoadLibrary(c_szMapi32Dll);
|
|
if (g_hlibMAPI == NULL)
|
|
return(hrMapiInitFail);
|
|
|
|
lpMAPILogonEx = (LPMAPILOGONEX)GetProcAddress(g_hlibMAPI, szMAPILogonEx);
|
|
lpMAPIInitialize = (LPMAPIINITIALIZE)GetProcAddress(g_hlibMAPI, szMAPIInitialize);
|
|
lpMAPIUninitialize = (LPMAPIUNINITIALIZE)GetProcAddress(g_hlibMAPI, szMAPIUninitialize);
|
|
lpMAPIFreeBuffer = (LPMAPIFREEBUFFER)GetProcAddress(g_hlibMAPI, szMAPIFreeBuffer);
|
|
lpMAPIAllocateBuffer = (LPMAPIALLOCATEBUFFER)GetProcAddress(g_hlibMAPI, szMAPIAllocateBuffer);
|
|
lpMAPIAllocateMore = (LPMAPIALLOCATEMORE)GetProcAddress(g_hlibMAPI, szMAPIAllocateMore);
|
|
lpMAPIAdminProfiles = (LPMAPIADMINPROFILES)GetProcAddress(g_hlibMAPI, szMAPIAdminProfiles);
|
|
lpFreeProws = (LPFREEPROWS)GetProcAddress(g_hlibMAPI, szFreeProws);
|
|
lpHrQueryAllRows = (LPHRQUERYALLROWS)GetProcAddress(g_hlibMAPI, szHrQueryAllRows);
|
|
lpWrapCompressedRTFStream = (LPWRAPCOMPRESSEDRTFSTREAM)GetProcAddress(g_hlibMAPI, szWrapCompressedRTFStream);
|
|
|
|
if (lpMAPILogonEx == NULL ||
|
|
lpMAPIInitialize == NULL ||
|
|
lpMAPIUninitialize == NULL ||
|
|
lpMAPIFreeBuffer == NULL ||
|
|
lpFreeProws == NULL ||
|
|
lpHrQueryAllRows == NULL ||
|
|
lpWrapCompressedRTFStream == NULL ||
|
|
lpMAPIAllocateBuffer == NULL ||
|
|
lpMAPIAllocateMore == NULL)
|
|
{
|
|
hr = hrMapiInitFail;
|
|
}
|
|
else
|
|
{
|
|
*g_szDefClient = 0;
|
|
cb = sizeof(sz);
|
|
if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, c_szRegOutlook, NULL, &type, (LPBYTE)sz, &cb))
|
|
{
|
|
cb = sizeof(g_szDefClient);
|
|
if (ERROR_SUCCESS == SHGetValue(HKEY_LOCAL_MACHINE, c_szRegMail, NULL, &type, (LPBYTE)g_szDefClient, &cb))
|
|
{
|
|
if (0 != lstrcmpi(g_szDefClient, c_szMicrosoftOutlook))
|
|
{
|
|
if (ERROR_SUCCESS != SHSetValue(HKEY_LOCAL_MACHINE, c_szRegMail, NULL, REG_SZ, (LPBYTE)c_szMicrosoftOutlook, lstrlen(c_szMicrosoftOutlook) + 1))
|
|
*g_szDefClient = 0;
|
|
}
|
|
else
|
|
{
|
|
*g_szDefClient = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = lpMAPIInitialize(NULL);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
g_fMapiInit = TRUE;
|
|
}
|
|
else
|
|
{
|
|
FreeLibrary(g_hlibMAPI);
|
|
g_hlibMAPI = NULL;
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
void ExchDeinit()
|
|
{
|
|
if (g_fMapiInit)
|
|
{
|
|
Assert(g_hlibMAPI != NULL);
|
|
|
|
lpMAPIUninitialize();
|
|
|
|
FreeLibrary(g_hlibMAPI);
|
|
g_hlibMAPI = NULL;
|
|
|
|
if (*g_szDefClient != 0)
|
|
{
|
|
SHSetValue(HKEY_LOCAL_MACHINE, c_szRegMail, NULL, REG_SZ, (LPBYTE)g_szDefClient, lstrlen(g_szDefClient) + 1);
|
|
*g_szDefClient = 0;
|
|
}
|
|
|
|
g_fMapiInit = FALSE;
|
|
}
|
|
}
|
|
|
|
HRESULT MapiLogon(HWND hwnd, IMAPISession **ppmapi)
|
|
{
|
|
HRESULT hr;
|
|
LPPROFADMIN lpAdmin;
|
|
LPMAPITABLE lpTable = NULL;
|
|
ULONG ulCount = NULL;
|
|
|
|
Assert(g_fMapiInit);
|
|
|
|
if (ppmapi != NULL)
|
|
*ppmapi = NULL;
|
|
|
|
if (!FAILED(hr = lpMAPIAdminProfiles(0, &lpAdmin)))
|
|
{
|
|
Assert(lpAdmin != NULL);
|
|
|
|
if (FAILED(hr = lpAdmin->GetProfileTable(0, &lpTable)) ||
|
|
FAILED(hr = lpTable->GetRowCount(0, &ulCount)) ||
|
|
!ulCount)
|
|
{
|
|
// could not find a valid profile
|
|
|
|
hr = hrNoProfilesFound;
|
|
}
|
|
else
|
|
{
|
|
if (ppmapi != NULL)
|
|
hr = lpMAPILogonEx((ULONG_PTR)hwnd, NULL, NULL, MAPI_EXTENDED | MAPI_LOGON_UI | MAPI_ALLOW_OTHERS, ppmapi);
|
|
else
|
|
hr = S_OK;
|
|
}
|
|
|
|
if (lpTable != NULL)
|
|
lpTable->Release();
|
|
|
|
lpAdmin->Release();
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
HRESULT ExchGetFolderList(HWND hwnd, IMAPISession *pmapi, IMPFOLDERNODE **pplist)
|
|
{
|
|
HRESULT hr;
|
|
LPMAPICONTAINER pcont;
|
|
IMPFOLDERNODE *plist;
|
|
|
|
Assert(g_fMapiInit);
|
|
Assert(pmapi != NULL);
|
|
|
|
hr = E_FAIL;
|
|
|
|
pcont = OpenDefaultStoreContainer(hwnd, pmapi);
|
|
if (pcont != NULL)
|
|
{
|
|
plist = NULL;
|
|
|
|
hr = GetSubFolderList(pcont, &plist, NULL);
|
|
Assert(!FAILED(hr));
|
|
Assert(plist != NULL);
|
|
|
|
*pplist = plist;
|
|
|
|
pcont->Release();
|
|
}
|
|
|
|
return(hr);
|
|
}
|
|
|
|
void ExchFreeFolderList(IMPFOLDERNODE *pnode)
|
|
{
|
|
Assert(pnode != NULL);
|
|
|
|
if (pnode->pchild != NULL)
|
|
ExchFreeFolderList(pnode->pchild);
|
|
|
|
if (pnode->pnext != NULL)
|
|
ExchFreeFolderList(pnode->pnext);
|
|
|
|
if (pnode->szName != NULL)
|
|
MemFree(pnode->szName);
|
|
|
|
if (pnode->lparam != NULL)
|
|
((LPMAPICONTAINER)pnode->lparam)->Release();
|
|
|
|
MemFree(pnode);
|
|
}
|
|
|
|
LPMAPICONTAINER OpenDefaultStoreContainer(HWND hwnd, IMAPISession *pmapi)
|
|
{
|
|
HRESULT hr;
|
|
LPMDB pmdb;
|
|
LPMAPITABLE ptbl;
|
|
LPSRowSet lpsrw;
|
|
LPSRow prw;
|
|
ULONG cStores,
|
|
cRows;
|
|
LPSPropValue ppvDefStore;
|
|
LPENTRYID lpEID;
|
|
ULONG cbEID, ulObjType, ulValues;
|
|
LPMAPICONTAINER pcont;
|
|
LPSPropValue lpPropsIPM = NULL;
|
|
ULONG ulPropTags[2] = {1, PR_IPM_SUBTREE_ENTRYID};
|
|
SizedSPropTagArray(4, pta) =
|
|
{ 4, {PR_DEFAULT_STORE, PR_ENTRYID, PR_OBJECT_TYPE, PR_RESOURCE_FLAGS}};
|
|
|
|
Assert(hwnd != NULL);
|
|
Assert(pmapi != NULL);
|
|
|
|
pmdb = NULL;
|
|
ptbl = NULL;
|
|
lpsrw = NULL;
|
|
pcont = NULL;
|
|
|
|
hr = pmapi->GetMsgStoresTable(0, &ptbl);
|
|
if (HR_FAILED(hr))
|
|
goto error;
|
|
|
|
hr = lpHrQueryAllRows(ptbl,(LPSPropTagArray)&pta, NULL, NULL, 0, &lpsrw);
|
|
if (HR_FAILED(hr))
|
|
goto error;
|
|
|
|
cRows = lpsrw->cRows;
|
|
prw = &lpsrw->aRow[0];
|
|
|
|
cStores = 0;
|
|
ppvDefStore = NULL;
|
|
|
|
while (cRows--)
|
|
{
|
|
if (prw->lpProps[2].ulPropTag == PR_OBJECT_TYPE && prw->lpProps[2].Value.l == MAPI_STORE)
|
|
{
|
|
if (prw->lpProps[3].ulPropTag != PR_RESOURCE_FLAGS ||
|
|
!(prw->lpProps[3].Value.l & STATUS_NO_DEFAULT_STORE))
|
|
cStores++;
|
|
}
|
|
|
|
if( prw->lpProps[0].ulPropTag == PR_DEFAULT_STORE &&
|
|
prw->lpProps[0].Value.b)
|
|
ppvDefStore=prw->lpProps;
|
|
|
|
prw++;
|
|
}
|
|
|
|
if (!ppvDefStore || ppvDefStore[1].ulPropTag != PR_ENTRYID)
|
|
goto error;
|
|
|
|
hr = pmapi->OpenMsgStore((ULONG_PTR)hwnd, ppvDefStore[1].Value.bin.cb,
|
|
(LPENTRYID)ppvDefStore[1].Value.bin.lpb,
|
|
NULL, MAPI_BEST_ACCESS, &pmdb);
|
|
if (!HR_FAILED(hr))
|
|
{
|
|
// Get the IPM_SUBTREE from the ROOT
|
|
if (!FAILED(hr = pmdb->GetProps((LPSPropTagArray)&ulPropTags, 0, &ulValues, &lpPropsIPM)))
|
|
{
|
|
cbEID = lpPropsIPM->Value.bin.cb;
|
|
lpEID = (LPENTRYID)lpPropsIPM->Value.bin.lpb;
|
|
|
|
hr = pmdb->OpenEntry(cbEID, lpEID, NULL, MAPI_BEST_ACCESS,
|
|
&ulObjType, (LPUNKNOWN *)&pcont);
|
|
|
|
lpMAPIFreeBuffer(lpPropsIPM);
|
|
}
|
|
}
|
|
|
|
error:
|
|
if (lpsrw != NULL)
|
|
FreeSRowSet(lpsrw);
|
|
if (ptbl != NULL)
|
|
ptbl->Release();
|
|
if (pmdb != NULL)
|
|
pmdb->Release();
|
|
|
|
return(pcont);
|
|
}
|
|
|
|
/*
|
|
* FreeSRowSet
|
|
*
|
|
* Purpose:
|
|
* Frees an SRowSet structure and the rows therein
|
|
*
|
|
* Parameters:
|
|
* LPSRowSet The row set to free
|
|
*/
|
|
void FreeSRowSet(LPSRowSet prws)
|
|
{
|
|
ULONG irw;
|
|
|
|
if (!prws)
|
|
return;
|
|
|
|
// Free each row
|
|
for (irw = 0; irw < prws->cRows; irw++)
|
|
lpMAPIFreeBuffer(prws->aRow[irw].lpProps);
|
|
|
|
// Free the top level structure
|
|
lpMAPIFreeBuffer(prws);
|
|
}
|
|
|
|
static SizedSPropTagArray(5, s_taFolder) =
|
|
{
|
|
5,
|
|
{
|
|
PR_DISPLAY_NAME,
|
|
PR_ENTRYID,
|
|
PR_SUBFOLDERS,
|
|
PR_OBJECT_TYPE,
|
|
PR_CONTENT_COUNT
|
|
}
|
|
};
|
|
|
|
enum
|
|
{
|
|
iDISPLAY_NAME = 0,
|
|
iENTRYID,
|
|
iSUBFOLDERS,
|
|
iOBJECT_TYPE,
|
|
iCONTENT_COUNT
|
|
};
|
|
|
|
HRESULT GetSubFolderList(LPMAPICONTAINER pcont, IMPFOLDERNODE **ppnode, IMPFOLDERNODE *pparent)
|
|
{
|
|
HRESULT hr;
|
|
IMPFOLDERNODE *pnode, *pnew, *plast;
|
|
ULONG i, cRow, ulObj;
|
|
int cb;
|
|
LPSRow lprw;
|
|
LPSPropValue lpProp;
|
|
LPMAPITABLE ptbl;
|
|
LPSRowSet prset;
|
|
|
|
*ppnode = NULL;
|
|
|
|
hr = pcont->GetHierarchyTable(0, &ptbl);
|
|
if (FAILED(hr))
|
|
return(hr);
|
|
|
|
pnode = NULL;
|
|
|
|
if (!FAILED(hr = ptbl->SetColumns((LPSPropTagArray)&s_taFolder, 0)) &&
|
|
!FAILED(hr = ptbl->GetRowCount(0, &cRow)) &&
|
|
cRow > 0)
|
|
{
|
|
while (TRUE)
|
|
{
|
|
if (cRow == 0)
|
|
{
|
|
hr = S_OK;
|
|
break;
|
|
}
|
|
hr = ptbl->QueryRows(cRow, 0, &prset);
|
|
if (FAILED(hr))
|
|
break;
|
|
if (prset->cRows == 0)
|
|
{
|
|
FreeSRowSet(prset);
|
|
break;
|
|
}
|
|
|
|
for (i = 0, lprw = prset->aRow; i < prset->cRows; i++, lprw++)
|
|
{
|
|
if (!MemAlloc((void **)&pnew, sizeof(IMPFOLDERNODE)))
|
|
break;
|
|
ZeroMemory(pnew, sizeof(IMPFOLDERNODE));
|
|
|
|
lpProp = &lprw->lpProps[iENTRYID];
|
|
Assert(lpProp->ulPropTag == PR_ENTRYID);
|
|
hr = pcont->OpenEntry(lpProp->Value.bin.cb, (LPENTRYID)lpProp->Value.bin.lpb, NULL,
|
|
MAPI_BEST_ACCESS, &ulObj, (LPUNKNOWN *)&pnew->lparam);
|
|
if (FAILED(hr))
|
|
{
|
|
MemFree(pnew);
|
|
continue;
|
|
}
|
|
|
|
lpProp = &lprw->lpProps[iCONTENT_COUNT];
|
|
Assert(lpProp->ulPropTag == PR_CONTENT_COUNT);
|
|
pnew->cMsg = lpProp->Value.l;
|
|
|
|
lpProp = &lprw->lpProps[iDISPLAY_NAME];
|
|
Assert(lpProp->ulPropTag == PR_DISPLAY_NAME);
|
|
cb = (lstrlen(lpProp->Value.LPSZ) + 1) * sizeof(TCHAR);
|
|
if (!MemAlloc((void **)&pnew->szName, cb))
|
|
break;
|
|
StrCpyN(pnew->szName, lpProp->Value.LPSZ, cb / sizeof(TCHAR));
|
|
|
|
pnew->depth = (pparent != NULL) ? pparent->depth + 1 : 0;
|
|
|
|
pnew->pparent = pparent;
|
|
|
|
if (pnode == NULL)
|
|
pnode = pnew;
|
|
else
|
|
plast->pnext = pnew;
|
|
|
|
plast = pnew;
|
|
|
|
lpProp = &lprw->lpProps[iSUBFOLDERS];
|
|
Assert(lpProp->ulPropTag == PR_SUBFOLDERS);
|
|
if (lpProp->Value.b)
|
|
{
|
|
hr = GetSubFolderList((LPMAPICONTAINER)pnew->lparam, &pnew->pchild, pnew);
|
|
Assert(!FAILED(hr));
|
|
}
|
|
}
|
|
|
|
Assert(prset->cRows <= cRow);
|
|
cRow -= prset->cRows;
|
|
|
|
FreeSRowSet(prset);
|
|
}
|
|
}
|
|
|
|
ptbl->Release();
|
|
|
|
*ppnode = pnode;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
LPSPropValue PvalFind(LPSRow prw, ULONG ulPropTag)
|
|
{
|
|
UINT ival = 0;
|
|
LPSPropValue pval = NULL;
|
|
|
|
if(!prw)
|
|
return NULL;
|
|
|
|
ival = (UINT) prw->cValues;
|
|
pval = prw->lpProps;
|
|
while (ival--)
|
|
{
|
|
if (pval->ulPropTag == ulPropTag)
|
|
return pval;
|
|
++pval;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
VOID ExchFreeImsg (LPIMSG lpImsg)
|
|
{
|
|
// Locals
|
|
ULONG i;
|
|
|
|
// Nothing
|
|
if (lpImsg == NULL)
|
|
return;
|
|
|
|
// Free Stuff
|
|
if (lpImsg->lpszSubject)
|
|
MemFree(lpImsg->lpszSubject);
|
|
lpImsg->lpszSubject = NULL;
|
|
|
|
if (lpImsg->lpstmBody)
|
|
lpImsg->lpstmBody->Release ();
|
|
lpImsg->lpstmBody = NULL;
|
|
|
|
if (lpImsg->lpstmHtml)
|
|
lpImsg->lpstmHtml->Release ();
|
|
lpImsg->lpstmHtml = NULL;
|
|
|
|
// Walk Address list
|
|
for (i=0; i<lpImsg->cAddress; i++)
|
|
{
|
|
if (lpImsg->lpIaddr[i].lpszAddress)
|
|
MemFree(lpImsg->lpIaddr[i].lpszAddress);
|
|
lpImsg->lpIaddr[i].lpszAddress = NULL;
|
|
|
|
if (lpImsg->lpIaddr[i].lpszDisplay)
|
|
MemFree(lpImsg->lpIaddr[i].lpszDisplay);
|
|
lpImsg->lpIaddr[i].lpszDisplay = NULL;
|
|
}
|
|
|
|
// Free Address list
|
|
if (lpImsg->lpIaddr)
|
|
MemFree(lpImsg->lpIaddr);
|
|
lpImsg->lpIaddr = NULL;
|
|
|
|
// Walk Attachment list
|
|
for (i=0; i<lpImsg->cAttach; i++)
|
|
{
|
|
if (lpImsg->lpIatt[i].lpszFileName)
|
|
MemFree(lpImsg->lpIatt[i].lpszFileName);
|
|
lpImsg->lpIatt[i].lpszFileName = NULL;
|
|
|
|
if (lpImsg->lpIatt[i].lpszPathName)
|
|
MemFree(lpImsg->lpIatt[i].lpszPathName);
|
|
lpImsg->lpIatt[i].lpszPathName = NULL;
|
|
|
|
if (lpImsg->lpIatt[i].lpszExt)
|
|
MemFree(lpImsg->lpIatt[i].lpszExt);
|
|
lpImsg->lpIatt[i].lpszExt = NULL;
|
|
|
|
if (lpImsg->lpIatt[i].lpImsg)
|
|
{
|
|
ExchFreeImsg (lpImsg->lpIatt[i].lpImsg);
|
|
MemFree(lpImsg->lpIatt[i].lpImsg);
|
|
lpImsg->lpIatt[i].lpImsg = NULL;
|
|
}
|
|
|
|
if (lpImsg->lpIatt[i].lpstmAtt)
|
|
lpImsg->lpIatt[i].lpstmAtt->Release ();
|
|
lpImsg->lpIatt[i].lpstmAtt = NULL;
|
|
}
|
|
|
|
// Free the att list
|
|
if (lpImsg->lpIatt)
|
|
MemFree(lpImsg->lpIatt);
|
|
}
|