|
|
#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); }
|