Leaked source code of windows server 2003
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.
 
 
 
 
 
 

346 lines
8.9 KiB

//--------------------------------------------------------------------------
// EnumMsgs.cpp
//--------------------------------------------------------------------------
#include "pch.hxx"
#include "enummsgs.h"
//--------------------------------------------------------------------------
// CEnumerateMessages::CEnumerateMessages
//--------------------------------------------------------------------------
CEnumerateMessages::CEnumerateMessages(void)
{
TraceCall("CEnumerateMessages::CEnumerateMessages");
m_cRef = 1;
m_hRowset = NULL;
m_pDB = NULL;
m_idParent = MESSAGEID_INVALID;
}
//--------------------------------------------------------------------------
// CEnumerateMessages::~CEnumerateMessages
//--------------------------------------------------------------------------
CEnumerateMessages::~CEnumerateMessages(void)
{
TraceCall("CEnumerateMessages::~CEnumerateMessages");
if (m_hRowset && m_pDB)
m_pDB->CloseRowset(&m_hRowset);
SafeRelease(m_pDB);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::QueryInterface
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::QueryInterface(REFIID riid, LPVOID *ppv)
{
// Locals
HRESULT hr=S_OK;
// Stack
TraceCall("CEnumerateMessages::QueryInterface");
// Find IID
if (IID_IUnknown == riid)
*ppv = (IUnknown *)this;
else
{
*ppv = NULL;
hr = TraceResult(E_NOINTERFACE);
goto exit;
}
// AddRef It
((IUnknown *)*ppv)->AddRef();
exit:
// Done
return(hr);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::AddRef
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumerateMessages::AddRef(void)
{
TraceCall("CEnumerateMessages::AddRef");
return InterlockedIncrement(&m_cRef);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Release
//--------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CEnumerateMessages::Release(void)
{
TraceCall("CEnumerateMessages::Release");
LONG cRef = InterlockedDecrement(&m_cRef);
if (0 == cRef)
delete this;
return (ULONG)cRef;
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Initialize
//--------------------------------------------------------------------------
HRESULT CEnumerateMessages::Initialize(IDatabase *pDB, MESSAGEID idParent)
{
// Locals
HRESULT hr=S_OK;
MESSAGEINFO Child={0};
ROWORDINAL iFirstRow;
// Trace
TraceCall("CEnumerateMessages::Initialize");
// Invalid Args
Assert(pDB);
// Reset ?
if (m_hRowset && m_pDB)
m_pDB->CloseRowset(&m_hRowset);
SafeRelease(m_pDB);
// Save parent
m_idParent = idParent;
// Save pStore
m_pDB = pDB;
m_pDB->AddRef();
// Set idParent
Child.idParent = idParent;
// Locate where the first record with idParent
IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
// Not Found
if (DB_S_NOTFOUND == hr)
{
hr = S_OK;
goto exit;
}
// Create a Rowset
IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &m_hRowset));
// Seek the rowset to the first row
IF_FAILEXIT(hr = m_pDB->SeekRowset(m_hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
exit:
// Cleanup
m_pDB->FreeRecord(&Child);
// Done
return(hr);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Next
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::Next(ULONG cWanted, LPMESSAGEINFO prgInfo,
ULONG *pcFetched)
{
// Locals
HRESULT hr=S_OK;
DWORD cFetched=0;
// Trace
TraceCall("CEnumerateMessages::Next");
// Initialize
if (pcFetched)
*pcFetched = 0;
// Nothing
if (NULL == m_hRowset)
return(S_FALSE);
// Validate
Assert(m_pDB);
// Query the Rowset for cFetch Rows...
IF_FAILEXIT(hr = m_pDB->QueryRowset(m_hRowset, cWanted, (LPVOID *)prgInfo, &cFetched));
// Adjust Actual Fetched based on m_idParent
while(cFetched && prgInfo[cFetched - 1].idParent != m_idParent)
{
// Free prgInfo
m_pDB->FreeRecord(&prgInfo[cFetched - 1]);
// Decrement cFetched
cFetched--;
}
// Return pcFetched
if (pcFetched)
*pcFetched = cFetched;
exit:
// Done
return(cFetched == cWanted) ? S_OK : S_FALSE;
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Skip
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::Skip(ULONG cItems)
{
// Locals
HRESULT hr=S_OK;
DWORD i;
MESSAGEINFO Message={0};
// Trace
TraceCall("CEnumerateMessages::Skip");
// Loop...
for (i=0; i<cItems; i++)
{
// Query the Rowset for cFetch Rows...
IF_FAILEXIT(hr = m_pDB->QueryRowset(m_hRowset, 1, (LPVOID *)&Message, NULL));
// Different Parent
if (Message.idParent != m_idParent)
break;
// Free
m_pDB->FreeRecord(&Message);
}
exit:
// Free
m_pDB->FreeRecord(&Message);
// Done
return(hr);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Reset
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::Reset(void)
{
// Locals
HRESULT hr=S_OK;
MESSAGEINFO Child={0};
ROWORDINAL iFirstRow;
// Trace
TraceCall("CEnumerateMessages::Reset");
// Close Rowset
m_pDB->CloseRowset(&m_hRowset);
// Set idParent
Child.idParent = m_idParent;
// Locate where the first record with idParent
IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
// Not Found
if (DB_S_NOTFOUND == hr)
{
hr = S_OK;
goto exit;
}
// Create a Rowset
IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &m_hRowset));
// Seek the rowset to the first row
IF_FAILEXIT(hr = m_pDB->SeekRowset(m_hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
exit:
// Cleanup
m_pDB->FreeRecord(&Child);
// Done
return(hr);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Clone
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::Clone(CEnumerateMessages **ppEnum)
{
// Locals
HRESULT hr=S_OK;
CEnumerateMessages *pEnum=NULL;
// Trace
TraceCall("CEnumerateMessages::Clone");
// Allocate a New Enumerator
IF_NULLEXIT(pEnum = new CEnumerateMessages);
// Initialzie
IF_FAILEXIT(hr = pEnum->Initialize(m_pDB, m_idParent));
// Return It
*ppEnum = (CEnumerateMessages *)pEnum;
// Don't Release It
pEnum = NULL;
exit:
// Cleanup
SafeRelease(pEnum);
// Done
return(hr);
}
//--------------------------------------------------------------------------
// CEnumerateMessages::Release
//--------------------------------------------------------------------------
STDMETHODIMP CEnumerateMessages::Count(ULONG *pcItems)
{
// Locals
HRESULT hr=S_OK;
MESSAGEINFO Child={0};
MESSAGEINFO Message={0};
ROWORDINAL iFirstRow;
HROWSET hRowset;
// Trace
TraceCall("CEnumerateMessages::Next");
// Init
*pcItems = 0;
// Set idParent
Child.idParent = m_idParent;
// Locate where the first record with idParent
IF_FAILEXIT(hr = m_pDB->FindRecord(IINDEX_THREADS, 1, &Child, &iFirstRow));
// Not Found
if (DB_S_NOTFOUND == hr)
{
hr = S_OK;
goto exit;
}
// Create a Rowset
IF_FAILEXIT(hr = m_pDB->CreateRowset(IINDEX_THREADS, NOFLAGS, &hRowset));
// Seek the rowset to the first row
IF_FAILEXIT(hr = m_pDB->SeekRowset(hRowset, SEEK_ROWSET_BEGIN, iFirstRow - 1, NULL));
// Walk the Rowset
while (S_OK == m_pDB->QueryRowset(hRowset, 1, (LPVOID *)&Message, NULL) && Message.idParent == m_idParent)
{
// Increment Count
(*pcItems)++;
// Free
m_pDB->FreeRecord(&Message);
}
exit:
// Cleanup
m_pDB->CloseRowset(&hRowset);
m_pDB->FreeRecord(&Message);
m_pDB->FreeRecord(&Child);
// Done
return(hr);
}