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.
890 lines
19 KiB
890 lines
19 KiB
//////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 1999-2002 Microsoft Corporation
|
|
//
|
|
// Module Name:
|
|
// EnumCPICCCB.cpp
|
|
//
|
|
// Description:
|
|
// IClusCfgCallback Connection Point Enumerator implementation.
|
|
//
|
|
// Maintained By:
|
|
// David Potter (DavidP) 14-JUN-2001
|
|
// Geoffrey Pease (GPease) 10-NOV-2000
|
|
//
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "Pch.h"
|
|
#include "EnumCPICCCB.h"
|
|
|
|
DEFINE_THISCLASS("CEnumCPICCCB")
|
|
|
|
#define PUNK_BUFFER_GROW_SIZE 10
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumCPICCCB class
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::S_HrCreateInstance
|
|
//
|
|
// Description:
|
|
// Create a CEnumCPICCCB instance.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// E_POINTER
|
|
// The passed in ppunk is NULL.
|
|
//
|
|
// other HRESULTs
|
|
// Object creation failed.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumCPICCCB::S_HrCreateInstance(
|
|
IUnknown ** ppunkOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_OK;
|
|
CEnumCPICCCB * pcc = NULL;
|
|
|
|
Assert( ppunkOut != NULL );
|
|
if ( ppunkOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
pcc = new CEnumCPICCCB();
|
|
if ( pcc == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( pcc->HrInit() ); // fIsCloneIn = FALSE
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( pcc->TypeSafeQI( IUnknown, ppunkOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
if ( pcc != NULL )
|
|
{
|
|
pcc->Release();
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::S_HrCreateInstance
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::CEnumCPICCCB
|
|
//
|
|
// Description:
|
|
// Default constructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CEnumCPICCCB::CEnumCPICCCB( void )
|
|
: m_cRef( 1 )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
InterlockedIncrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CEnumCPICCCB::CEnumCPICCCB
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::~CEnumCPICCCB
|
|
//
|
|
// Description:
|
|
// Default destructor.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
CEnumCPICCCB::~CEnumCPICCCB( void )
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
IUnknown * punk = NULL;
|
|
|
|
if ( m_pList != NULL )
|
|
{
|
|
while ( m_cAlloced != 0 )
|
|
{
|
|
m_cAlloced --;
|
|
|
|
punk = m_pList[ m_cAlloced ];
|
|
|
|
AssertMsg( m_fIsClone || punk == NULL, "Someone didn't Unadvise before releasing the last Reference." );
|
|
if ( punk != NULL )
|
|
{
|
|
punk->Release();
|
|
}
|
|
|
|
} // while: m_cAlloced
|
|
|
|
TraceFree( m_pList );
|
|
} // while:
|
|
|
|
InterlockedDecrement( &g_cObjects );
|
|
|
|
TraceFuncExit();
|
|
|
|
} //*** CEnumCPICCCB::~CEnumCPICCCB
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumCPICCCB -- IUnknown interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::AddRef
|
|
//
|
|
// Description:
|
|
// Increment the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CEnumCPICCCB::AddRef( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
InterlockedIncrement( &m_cRef );
|
|
|
|
CRETURN( m_cRef );
|
|
|
|
} //*** CEnumCPICCCB::AddRef
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CTaskCancelCleanup::Release
|
|
//
|
|
// Description:
|
|
// Decrement the reference count of this object by one.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Value:
|
|
// The new reference count.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP_(ULONG)
|
|
CEnumCPICCCB::Release( void )
|
|
{
|
|
TraceFunc( "[IUnknown]" );
|
|
|
|
LONG cRef;
|
|
|
|
cRef = InterlockedDecrement( &m_cRef );
|
|
|
|
if ( cRef == 0 )
|
|
{
|
|
TraceDo( delete this );
|
|
}
|
|
|
|
CRETURN( cRef );
|
|
|
|
} //*** CEnumCPICCCB::Release
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::QueryInterface
|
|
//
|
|
// Description:
|
|
// Query this object for the passed in interface.
|
|
//
|
|
// Arguments:
|
|
// riidIn
|
|
// Id of interface requested.
|
|
//
|
|
// ppvOut
|
|
// Pointer to the requested interface.
|
|
//
|
|
// Return Value:
|
|
// S_OK
|
|
// If the interface is available on this object.
|
|
//
|
|
// E_NOINTERFACE
|
|
// If the interface is not available.
|
|
//
|
|
// E_POINTER
|
|
// ppvOut was NULL.
|
|
//
|
|
// Remarks:
|
|
// None.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumCPICCCB::QueryInterface(
|
|
REFIID riidIn
|
|
, LPVOID * ppvOut
|
|
)
|
|
{
|
|
TraceQIFunc( riidIn, ppvOut );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
//
|
|
// Validate arguments.
|
|
//
|
|
|
|
Assert( ppvOut != NULL );
|
|
if ( ppvOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Handle known interfaces.
|
|
//
|
|
|
|
if ( IsEqualIID( riidIn, IID_IUnknown ) )
|
|
{
|
|
*ppvOut = static_cast< IEnumConnections * >( this );
|
|
} // if: IUnknown
|
|
else if ( IsEqualIID( riidIn, IID_IEnumConnections ) )
|
|
{
|
|
*ppvOut = TraceInterface( __THISCLASS__, IEnumConnections, this, 0 );
|
|
} // else if: IEnumConnections
|
|
else
|
|
{
|
|
*ppvOut = NULL;
|
|
hr = E_NOINTERFACE;
|
|
} // else
|
|
|
|
//
|
|
// Add a reference to the interface if successful.
|
|
//
|
|
|
|
if ( SUCCEEDED( hr ) )
|
|
{
|
|
((IUnknown *) *ppvOut)->AddRef();
|
|
} // if: success
|
|
|
|
Cleanup:
|
|
|
|
QIRETURN_IGNORESTDMARSHALLING( hr, riidIn );
|
|
|
|
} //*** CEnumCPICCCB::QueryInterface
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumCPICCCB -- IEnumConnectionPoints interface.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::Next
|
|
//
|
|
// Description:
|
|
// Enumerator Next method.
|
|
//
|
|
// Arguments:
|
|
// cConnectionsIn
|
|
// How many items requested. Also tells us how bing rgcd.
|
|
//
|
|
// rgcdOut
|
|
// Array that gets the data.
|
|
//
|
|
// pcFetchedOut
|
|
// How many did we place in the array.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// S_FALSE
|
|
// cConnectionsIn > *pcFetchedOut. Did not return as many items
|
|
// as the caller asked for.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumCPICCCB::Next(
|
|
ULONG cConnectionsIn,
|
|
LPCONNECTDATA rgcd,
|
|
ULONG *pcFetchedOut
|
|
)
|
|
{
|
|
TraceFunc( "[IEnumConnectionPoints]" );
|
|
|
|
ULONG cIter;
|
|
HRESULT hr = S_FALSE;
|
|
|
|
if ( pcFetchedOut != NULL )
|
|
{
|
|
*pcFetchedOut = 0;
|
|
} // if:
|
|
|
|
for( cIter = 0
|
|
; ( cIter < cConnectionsIn ) && ( m_cIter < m_cCurrent )
|
|
; m_cIter++
|
|
)
|
|
{
|
|
IUnknown * punk = m_pList[ m_cIter ];
|
|
if ( punk != NULL )
|
|
{
|
|
hr = THR( punk->TypeSafeQI( IUnknown, &rgcd[ cIter ].pUnk ) );
|
|
if ( FAILED( hr ) )
|
|
goto Error;
|
|
|
|
rgcd[ cIter ].pUnk = TraceInterface( L"EnumCPICCCB!IUnknown", IUnknown, rgcd[ cIter ].pUnk, 1 );
|
|
|
|
rgcd[ cIter ].dwCookie = m_cIter + 1;
|
|
|
|
cIter ++;
|
|
} // if:
|
|
|
|
} // for: cIter
|
|
|
|
if ( cIter != cConnectionsIn )
|
|
{
|
|
hr = S_FALSE;
|
|
} // if:
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
} // else:
|
|
|
|
if ( pcFetchedOut != NULL )
|
|
{
|
|
*pcFetchedOut = cIter;
|
|
} // if:
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
Error:
|
|
while ( cIter != 0 )
|
|
{
|
|
cIter --;
|
|
rgcd[ cIter ].pUnk->Release();
|
|
} // while:
|
|
|
|
goto Cleanup;
|
|
|
|
} //*** CEnumCPICCCB::Next
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::Skip
|
|
//
|
|
// Description:
|
|
// Enumerator Skip method.
|
|
//
|
|
// Arguments:
|
|
// cConnectionsIn
|
|
// Number of items to skip.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// S_FALSE
|
|
// The number to skip put us at the end of the list.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumCPICCCB::Skip(
|
|
ULONG cConnectionsIn
|
|
)
|
|
{
|
|
TraceFunc( "[IEnumConnectionPoints]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_cIter += cConnectionsIn;
|
|
if ( m_cIter >= m_cCurrent )
|
|
{
|
|
m_cIter = m_cCurrent;
|
|
hr = S_FALSE;
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::Skip
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::Reset
|
|
//
|
|
// Description:
|
|
// Enumerator Reset method.
|
|
//
|
|
// Arguments:
|
|
// None.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumCPICCCB::Reset( void )
|
|
{
|
|
TraceFunc( "[IEnumConnectionPoints]" );
|
|
|
|
HRESULT hr = S_OK;
|
|
|
|
m_cIter = 0;
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::Reset
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::Clone
|
|
//
|
|
// Description:
|
|
// Enumerator Clone method.
|
|
//
|
|
// Arguments:
|
|
// ppEnumOut
|
|
// The new enumerator that we are cloning ourselves into.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
STDMETHODIMP
|
|
CEnumCPICCCB::Clone(
|
|
IEnumConnections **ppEnumOut
|
|
)
|
|
{
|
|
TraceFunc( "[IEnumConnectionPoints]" );
|
|
|
|
HRESULT hr;
|
|
|
|
CEnumCPICCCB * pecp = new CEnumCPICCCB();
|
|
if ( pecp == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( pecp->HrInit( TRUE ) ); // fIsCloneIn = TRUE
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( pecp->HrCopy( this ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
hr = THR( pecp->TypeSafeQI( IEnumConnections, ppEnumOut ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
*ppEnumOut = TraceInterface( L"EnumCPICCCB!IEnumConnections", IEnumConnections, *ppEnumOut, 1 );
|
|
|
|
pecp->Release();
|
|
pecp = NULL;
|
|
|
|
Cleanup:
|
|
|
|
if ( pecp != NULL )
|
|
{
|
|
delete pecp;
|
|
} // if:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::Clone
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumCPINotifyUI -- Public methods.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::HrAddConnection
|
|
//
|
|
// Description:
|
|
// Add a connection point container to our list of clients.
|
|
//
|
|
// Arguments:
|
|
// punkIn
|
|
// The new client object.
|
|
//
|
|
// pdwCookieOut
|
|
// Cookie used to find this client object in our list.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumCPICCCB::HrAddConnection(
|
|
IUnknown * punkIn,
|
|
DWORD * pdwCookieOut
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
ULONG cIter;
|
|
|
|
if ( pdwCookieOut == NULL )
|
|
{
|
|
hr = THR( E_POINTER );
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// See if there is an openning in the currently allocated list.
|
|
//
|
|
|
|
for ( cIter = 0; cIter < m_cCurrent; cIter ++ )
|
|
{
|
|
if ( m_pList[ cIter ] == NULL )
|
|
{
|
|
//
|
|
// Found an openning... try to use it.
|
|
//
|
|
|
|
hr = THR( punkIn->TypeSafeQI( IUnknown, &m_pList[ cIter ] ) );
|
|
|
|
m_pList[ cIter ] = TraceInterface( L"CEnumCPICCCB!IUnknown", IUnknown, m_pList[ cIter ], 1 );
|
|
|
|
*pdwCookieOut = cIter + 1;
|
|
|
|
// Doesn't matter if it succeeded or fail, exit.
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
if ( m_cCurrent == m_cAlloced )
|
|
{
|
|
IUnknown ** pNewList;
|
|
|
|
//
|
|
// Try making some more space.
|
|
//
|
|
|
|
pNewList = (IUnknown **) TraceAlloc( HEAP_ZERO_MEMORY, ( m_cAlloced + PUNK_BUFFER_GROW_SIZE ) * sizeof( IUnknown * ) );
|
|
if ( pNewList == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
}
|
|
|
|
CopyMemory( pNewList, m_pList, m_cCurrent * sizeof( IUnknown * ) );
|
|
TraceFree( m_pList );
|
|
|
|
m_pList = pNewList;
|
|
m_cAlloced += PUNK_BUFFER_GROW_SIZE;
|
|
}
|
|
|
|
//
|
|
// Add it to the list.
|
|
//
|
|
|
|
hr = THR( punkIn->TypeSafeQI( IUnknown, &m_pList[ m_cCurrent ] ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
m_pList[ m_cCurrent ] = TraceInterface( L"CEnumCPICCCB!IUnknown", IUnknown, m_pList[ m_cCurrent ], 1 );
|
|
|
|
m_cCurrent ++;
|
|
*pdwCookieOut = m_cCurrent; // starts at ONE, not ZERO
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::HrAddConnection
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::HrRemoveConnection
|
|
//
|
|
// Description:
|
|
// Remove the client identified by the passed in cookie from the list.
|
|
//
|
|
// Arguments:
|
|
// dwCookieIn
|
|
// The cookie of the client that is to be removed from the list.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumCPICCCB::HrRemoveConnection(
|
|
DWORD dwCookieIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr;
|
|
|
|
if ( dwCookieIn == 0 || dwCookieIn > m_cCurrent )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
if ( m_pList[ dwCookieIn - 1 ] == NULL )
|
|
{
|
|
hr = THR( E_INVALIDARG );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_pList[ dwCookieIn - 1 ]->Release();
|
|
m_pList[ dwCookieIn - 1 ] = NULL;
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::HrRemoveConnection
|
|
|
|
|
|
//*************************************************************************//
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CEnumCPICCCB -- Private methods.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::HrInt
|
|
//
|
|
// Description:
|
|
// Do any initialization that may fail here.
|
|
//
|
|
// Arguments:
|
|
// fIsCloneIn
|
|
// Is this instance a clone?
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumCPICCCB::HrInit(
|
|
BOOL fIsCloneIn // = FALSE
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
// IUnknown stuff
|
|
Assert( m_cRef == 1 );
|
|
|
|
// IEnumConnectionPoints
|
|
Assert( m_cAlloced == 0 );
|
|
Assert( m_cCurrent == 0 );
|
|
Assert( m_cIter == 0 );
|
|
Assert( m_pList == NULL );
|
|
Assert( m_fIsClone == FALSE );
|
|
|
|
m_fIsClone = fIsCloneIn;
|
|
|
|
// INotifyUI
|
|
|
|
HRETURN( S_OK );
|
|
|
|
} //*** CEnumCPICCCB::HrInit
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
//++
|
|
//
|
|
// CEnumCPICCCB::HrCopy
|
|
//
|
|
// Description:
|
|
// Copy from the passed in enumerator.
|
|
//
|
|
// Arguments:
|
|
// pecpIn
|
|
// The source that we are to copy from.
|
|
//
|
|
// Return Values:
|
|
// S_OK
|
|
// Success.
|
|
//
|
|
// Other HRESULT errors.
|
|
//
|
|
//--
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
HRESULT
|
|
CEnumCPICCCB::HrCopy(
|
|
CEnumCPICCCB * pecpIn
|
|
)
|
|
{
|
|
TraceFunc( "" );
|
|
|
|
HRESULT hr = S_FALSE;
|
|
|
|
ULONG cIter;
|
|
|
|
Assert( m_cAlloced == 0 );
|
|
Assert( m_cCurrent == 0 );
|
|
Assert( m_pList == 0 );
|
|
|
|
m_pList = (IUnknown**) TraceAlloc( HEAP_ZERO_MEMORY, pecpIn->m_cCurrent * sizeof( IUnknown * ) );
|
|
if ( m_pList == NULL )
|
|
{
|
|
hr = THR( E_OUTOFMEMORY );
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_cCurrent = m_cAlloced = pecpIn->m_cCurrent;
|
|
m_cIter = 0;
|
|
|
|
for ( cIter = 0; cIter < pecpIn->m_cCurrent; cIter ++ )
|
|
{
|
|
//
|
|
// Does the source have a pointer at the current index? If it does then "copy" it,
|
|
// otherwise NULL out that index in our copy...
|
|
//
|
|
|
|
if ( pecpIn->m_pList[ cIter ] != NULL )
|
|
{
|
|
hr = THR( pecpIn->m_pList[ cIter ]->TypeSafeQI( IUnknown, &m_pList[ cIter ] ) );
|
|
if ( FAILED( hr ) )
|
|
{
|
|
goto Cleanup;
|
|
} // if:
|
|
|
|
m_pList[ cIter ] = TraceInterface( L"EnumCPICCCB!IUnknown", IUnknown, m_pList[ cIter ], 1 );
|
|
} // if:
|
|
else
|
|
{
|
|
m_pList[ cIter ] = NULL;
|
|
} // else:
|
|
} // for:
|
|
|
|
hr = S_OK;
|
|
|
|
Cleanup:
|
|
|
|
HRETURN( hr );
|
|
|
|
} //*** CEnumCPICCCB::HrCopy
|