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.
304 lines
8.0 KiB
304 lines
8.0 KiB
// --------------------------------------------------------------------------------
|
|
// AddrEnum.cpp
|
|
// Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
|
|
// --------------------------------------------------------------------------------
|
|
#include "pch.hxx"
|
|
#include "dllmain.h"
|
|
#include "addrenum.h"
|
|
#include "olealloc.h"
|
|
#include "addressx.h"
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::CMimeEnumAddressTypes
|
|
// --------------------------------------------------------------------------------
|
|
CMimeEnumAddressTypes::CMimeEnumAddressTypes(void)
|
|
{
|
|
DllAddRef();
|
|
m_cRef = 1;
|
|
m_pTable = NULL;
|
|
m_iAddress = 0;
|
|
ZeroMemory(&m_rList, sizeof(ADDRESSLIST));
|
|
InitializeCriticalSection(&m_cs);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::~CMimeEnumAddressTypes
|
|
// --------------------------------------------------------------------------------
|
|
CMimeEnumAddressTypes::~CMimeEnumAddressTypes(void)
|
|
{
|
|
g_pMoleAlloc->FreeAddressList(&m_rList);
|
|
SafeRelease(m_pTable);
|
|
DeleteCriticalSection(&m_cs);
|
|
DllRelease();
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::QueryInterface
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::QueryInterface(REFIID riid, LPVOID *ppv)
|
|
{
|
|
// check params
|
|
if (ppv == NULL)
|
|
return TrapError(E_INVALIDARG);
|
|
|
|
// Find IID
|
|
if (IID_IUnknown == riid)
|
|
*ppv = (IUnknown *)this;
|
|
else if (IID_IMimeEnumAddressTypes == riid)
|
|
*ppv = (IMimeEnumAddressTypes *)this;
|
|
else
|
|
{
|
|
*ppv = NULL;
|
|
return TrapError(E_NOINTERFACE);
|
|
}
|
|
|
|
// AddRef It
|
|
((IUnknown *)*ppv)->AddRef();
|
|
|
|
// Done
|
|
return S_OK;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::QueryInterface
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG) CMimeEnumAddressTypes::AddRef(void)
|
|
{
|
|
return InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Release
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP_(ULONG) CMimeEnumAddressTypes::Release(void)
|
|
{
|
|
ULONG cRef = InterlockedDecrement(&m_cRef);
|
|
if (0 == cRef)
|
|
delete this;
|
|
return cRef;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Next
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::Next(ULONG cWanted, LPADDRESSPROPS prgAdr, ULONG *pcFetched)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
ULONG cFetch=0,
|
|
iAddress=0;
|
|
|
|
// Thread Safety
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Init
|
|
if (pcFetched)
|
|
*pcFetched = 0;
|
|
|
|
// No Internal Formats
|
|
if (NULL == m_rList.prgAdr)
|
|
goto exit;
|
|
|
|
// Compute number to fetch
|
|
cFetch = min(cWanted, m_rList.cAdrs - m_iAddress);
|
|
if (0 == cFetch)
|
|
goto exit;
|
|
|
|
// Invalid Arg
|
|
if (NULL == prgAdr)
|
|
{
|
|
hr = TrapError(E_INVALIDARG);
|
|
goto exit;
|
|
}
|
|
|
|
// Copy cWanted
|
|
for (iAddress=0; iAddress<cFetch; iAddress++)
|
|
{
|
|
// Zero
|
|
ZeroMemory(&prgAdr[iAddress], sizeof(ADDRESSPROPS));
|
|
|
|
// Copy Props
|
|
CHECKHR(hr = HrCopyAddressProps(&m_rList.prgAdr[m_iAddress], &prgAdr[iAddress]));
|
|
|
|
// Next
|
|
m_iAddress++;
|
|
}
|
|
|
|
// Return fetced ?
|
|
if (pcFetched)
|
|
*pcFetched = cFetch;
|
|
|
|
exit:
|
|
// Thread Safety
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// Done
|
|
return (cFetch == cWanted) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Skip
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::Skip(ULONG cSkip)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
|
|
// Thread Safety
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Can we do it...
|
|
if (((m_iAddress + cSkip) >= m_rList.cAdrs) || NULL == m_rList.prgAdr)
|
|
{
|
|
hr = S_FALSE;
|
|
goto exit;
|
|
}
|
|
|
|
// Skip
|
|
m_iAddress += cSkip;
|
|
|
|
exit:
|
|
// Thread Safety
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// Done
|
|
return hr;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Reset
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::Reset(void)
|
|
{
|
|
EnterCriticalSection(&m_cs);
|
|
m_iAddress = 0;
|
|
LeaveCriticalSection(&m_cs);
|
|
return S_OK;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Count
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::Count(ULONG *pcCount)
|
|
{
|
|
// Invalid Arg
|
|
if (NULL == pcCount)
|
|
return TrapError(E_INVALIDARG);
|
|
|
|
// Thread Safety
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Set Count
|
|
*pcCount = m_rList.cAdrs;
|
|
|
|
// Thread Safety
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// Done
|
|
return S_OK;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::Clone
|
|
// --------------------------------------------------------------------------------
|
|
STDMETHODIMP CMimeEnumAddressTypes::Clone(IMimeEnumAddressTypes **ppEnum)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
CMimeEnumAddressTypes *pEnum=NULL;
|
|
|
|
// Invalid Arg
|
|
if (NULL == ppEnum)
|
|
return TrapError(E_INVALIDARG);
|
|
|
|
// Thread Safety
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Init
|
|
*ppEnum = NULL;
|
|
|
|
// Create the clone.
|
|
CHECKALLOC(pEnum = new CMimeEnumAddressTypes);
|
|
|
|
// Init
|
|
CHECKHR(hr = pEnum->HrInit(m_pTable, m_iAddress, &m_rList, TRUE));
|
|
|
|
// Set Return
|
|
*ppEnum = pEnum;
|
|
(*ppEnum)->AddRef();
|
|
|
|
exit:
|
|
// Cleanup
|
|
SafeRelease(pEnum);
|
|
|
|
// Thread Safety
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// Done
|
|
return hr;
|
|
}
|
|
|
|
// --------------------------------------------------------------------------------
|
|
// CMimeEnumAddressTypes::HrInit
|
|
// --------------------------------------------------------------------------------
|
|
HRESULT CMimeEnumAddressTypes::HrInit(IMimeAddressTable *pTable, ULONG iAddress, LPADDRESSLIST pList, BOOL fDuplicate)
|
|
{
|
|
// Locals
|
|
HRESULT hr=S_OK;
|
|
ULONG i;
|
|
|
|
// Invalid Arg
|
|
Assert(pTable && pList);
|
|
|
|
// Thread Safety
|
|
EnterCriticalSection(&m_cs);
|
|
|
|
// Check param
|
|
Assert(m_iAddress == 0 && m_rList.cAdrs == 0 && m_rList.prgAdr == NULL);
|
|
|
|
// Empty Enumerator ?
|
|
if (0 == pList->cAdrs)
|
|
{
|
|
Assert(pList->prgAdr == NULL);
|
|
goto exit;
|
|
}
|
|
|
|
// No Duplicate ?
|
|
if (FALSE == fDuplicate)
|
|
CopyMemory(&m_rList, pList, sizeof(ADDRESSLIST));
|
|
|
|
// Otherwise
|
|
else
|
|
{
|
|
// Allocat an internal array
|
|
CHECKHR(hr = HrAlloc((LPVOID *)&m_rList.prgAdr, sizeof(ADDRESSPROPS) * pList->cAdrs));
|
|
|
|
// Copy prgPart
|
|
for (i=0; i<pList->cAdrs; i++)
|
|
{
|
|
// Zero Dest
|
|
ZeroMemory(&m_rList.prgAdr[i], sizeof(ADDRESSPROPS));
|
|
|
|
// Copy Address Props
|
|
CHECKHR(hr = HrCopyAddressProps(&pList->prgAdr[i], &m_rList.prgAdr[i]));
|
|
}
|
|
|
|
// Save Size and State
|
|
m_rList.cAdrs = pList->cAdrs;
|
|
}
|
|
|
|
// Save Current Index
|
|
Assert(iAddress < m_rList.cAdrs);
|
|
m_iAddress = iAddress;
|
|
|
|
// Assume the Table
|
|
m_pTable = pTable;
|
|
m_pTable->AddRef();
|
|
|
|
exit:
|
|
// Thread Safety
|
|
LeaveCriticalSection(&m_cs);
|
|
|
|
// Done
|
|
return hr;
|
|
}
|