📄 voipcallerinfodbenum.cpp
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
// VoIPCallerInfoDBEnum.cpp : Implementation of CVoIPCallerInfoDBEnum
#include "VoIPStore.h"
#include "VoIPCallerInfoRecord.h"
#include "VoIPCallerInfoDB.h"
#include "VoIPCallerInfoDBEnum.h"
#include "auto_xxx.hxx"
/////////////////////////////////////////////////////////////////////////////
// CVoIPCallerInfoDBEnum
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::Init
Initializes the database enumerator.
Parameters:
pDB: The CVoipDB that corresponds to the actual database over
which we are enumerating.
pCallerInfoDB: The database interface that is associated with the
CVoipDB.
------------------------------------------------------------------------------*/
HRESULT CVoIPCallerInfoDBEnum::Init(
CVoipDB *pDB,
CVoIPCallerInfoDB *pCallerInfoDB,
FilterFn *pfnFilter
)
{
HRESULT hr = S_OK;
// Check parameters
if (pDB == NULL || pCallerInfoDB == NULL || pfnFilter == NULL)
{
return E_POINTER;
}
// Initialize member variables and add a reference to the interface pointer
if (SUCCEEDED(hr))
{
m_pDB = pDB;
m_pCallerInfoDB = pCallerInfoDB;
m_pCallerInfoDB->AddRef();
m_pfnFilter = pfnFilter;
// Database was locked. Now we need to seek back to the beginning
if (!m_pDB->ResetSeek())
{
m_pCallerInfoDB->Release();
m_pCallerInfoDB = NULL;
return E_FAIL;
}
}
m_fInit = TRUE;
return S_OK;
}
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::Next
Reads in the next celt records in the database, storing them in the array
array.
Parameters:
celt: The number of elements to read.
rgCallerInfoRecord: The array to fill with elements.
pceltFetched: The number of elements actually read.
Returns S_OK if the number of elements requested were actually read,
S_FALSE if there were no errors but the number read < the number
requested, and FAILED hr otherwise.
------------------------------------------------------------------------------*/
STDMETHODIMP CVoIPCallerInfoDBEnum::Next(
unsigned long celt,
IVoIPCallerInfoRecord **rgCallerInfoRecord,
unsigned long FAR* pceltFetched
)
{
int i = 0;
int cRecordsRead = 0;
CComObject<CVoIPCallerInfoRecord> *pRecord = NULL;
IVoIPCallerInfoRecord *piCallerInfoRecord = NULL;
CEPROPVAL *pcpvFill = NULL;
HRESULT hr = S_OK;
int cProps = 0;
CEOID ceoid = 0;
// Can't call this without first initializing the enumerator
if (!m_fInit)
{
return VOIP_E_NOTINITIALIZED;
}
// Check parameters
if (celt <= 0)
{
return E_INVALIDARG;
}
if (rgCallerInfoRecord == NULL)
{
return E_POINTER;
}
// Reset the number fetched (if requested)
if (pceltFetched != NULL)
{
*pceltFetched = 0;
}
// Initialize the Record array
for(i = 0; i < (int)celt; i++)
{
rgCallerInfoRecord[i] = NULL;
}
int celtsLeft = celt;
// For each element the user is trying to get:
while(celtsLeft > 0 && SUCCEEDED(hr))
{
// Move to the next element in the database
if (!m_pDB->SeekToNext(1))
{
// No more items; this is not necessarily failure.
break;
}
if (SUCCEEDED(hr))
{
// Create a record in the database using the module-internal
// create (so we can change the record contents).
// pRecord now has a single reference on it.
hr = m_pCallerInfoDB->InternalCreateRecord(&pRecord);
}
if (SUCCEEDED(hr))
{
// Read the record into a CEPROPVAL structure
if (!m_pDB->ReadCurrentRecord((CEPROPVAL**)&pcpvFill, &cProps, &ceoid))
{
hr = E_FAIL;
}
}
if (SUCCEEDED(hr))
{
// Associate the record's OID with this database.
pRecord->SetOID(ceoid);
// Query the COM object for the corresponding interface. This
// will add another reference to piCallerInfoRecord/pRecord,
// for a total of two.
hr = pRecord->QueryInterface(IID_IVoIPCallerInfoRecord, (void**)&piCallerInfoRecord);
}
if (SUCCEEDED(hr))
{
// We won't store the interface pointer more than once, so
// release one of our references.
pRecord->Release();
pRecord = NULL;
// The record we are returning is empty so far. Ask the
// database object to fill the record with properties.
hr = m_pCallerInfoDB->FillRecord(piCallerInfoRecord, pcpvFill, cProps);
}
if (pcpvFill != NULL)
{
// Alloc'ed in ReadCurrentRecord
LocalFree(pcpvFill);
}
//Give the record to the user if the record is ok
if (SUCCEEDED(hr))
{
//Check to see if this is an acceptable record
hr = m_pfnFilter(piCallerInfoRecord);
}
//If the function said "yes" - we return it to the user
if (hr == S_OK)
{
//Add-refed from the QueryInterface, so we don't need to add ref again
rgCallerInfoRecord[celt-celtsLeft] = piCallerInfoRecord;
cRecordsRead++;
celtsLeft--;
}
if (FAILED(hr))
{
break;
}
}
if(SUCCEEDED(hr))
{
// Did we read all the records we were asked to read?
if((unsigned long)cRecordsRead == celt)
{
hr = S_OK;
}
else
{
hr = S_FALSE;
}
// Return the number of fetched elements (if requested)
if (pceltFetched != NULL)
{
(*pceltFetched) = cRecordsRead;
}
}
// Clean up
//
if (FAILED(hr))
{
// Something went wrong
// If the record still has a reference on it, release it
if (piCallerInfoRecord != NULL)
{
piCallerInfoRecord->Release();
piCallerInfoRecord = NULL;
}
// Clean up the array since it's probably half-baked
for(i = 0; i < cRecordsRead; i++)
{
if (rgCallerInfoRecord[i] != NULL)
{
rgCallerInfoRecord[i]->Release();
rgCallerInfoRecord[i] = NULL;
}
}
}
// Return S_OK if we got all the elements requested, S_FALSE otherwise
return hr;
}
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::Skip
Skips over the next celt elements in the enumeration.
Parameters:
celt: The number of elements to skip.
------------------------------------------------------------------------------*/
STDMETHODIMP CVoIPCallerInfoDBEnum::Skip(
unsigned long celt
)
{
HRESULT hr = S_OK;
// Can't call this without first initializing the enumerator
if (!m_fInit)
{
return VOIP_E_NOTINITIALIZED;
}
// Check parameters
if (celt < 0)
{
return E_INVALIDARG;
}
if (SUCCEEDED(hr))
{
// Internally seek ahead by celt elements
if (!m_pDB->SeekToNext(celt))
{
hr = E_FAIL;
}
}
return hr;
}
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::Reset
Resets the enumerator. This will re-validate an interface pointer that
has become invalid because someone else has changed the database's version.
------------------------------------------------------------------------------*/
STDMETHODIMP CVoIPCallerInfoDBEnum::Reset()
{
HRESULT hr = S_OK;
// Can't call this without first initializing the enumerator
if (!m_fInit)
{
return VOIP_E_NOTINITIALIZED;
}
if (SUCCEEDED(hr))
{
// Reset the seek internally
if (!m_pDB->ResetSeek())
{
hr = E_FAIL;
}
}
return hr;
}
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::AcceptAll
Filter that accepts all non-null records
------------------------------------------------------------------------------*/
/* static */ HRESULT CVoIPCallerInfoDBEnum::AcceptAll(IVoIPCallerInfoRecord * piRecord)
{
return (piRecord != NULL) ? S_OK : E_POINTER;
}
/*------------------------------------------------------------------------------
CVoIPCallerInfoDBEnum::SpeedDialExists
Filter that accepts records whose speed dial entry is not invalid
Parameters:
piRecord: The record to check
Returns: S_OK - yes, keep the record
S_FALSE - no, skip the record
E_ - failure
------------------------------------------------------------------------------*/
/* static */ HRESULT CVoIPCallerInfoDBEnum::SpeedDialExists(IVoIPCallerInfoRecord * piRecord)
{
INT idxSpeedDial = 0;
HRESULT hr = S_OK;
//Check params
if (piRecord == NULL)
{
return E_POINTER;
}
//Get the speed dial entry
if (SUCCEEDED(hr))
{
hr = piRecord->get_SpeedDialEntry(&idxSpeedDial);
}
//Check to make sure the speed dial entry exists!
if (SUCCEEDED(hr))
{
if (idxSpeedDial == VOIP_INVALID_SPEED_DIAL_ENTRY)
{
return S_FALSE;
}
}
return hr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -