windows-nt/Source/XPSP1/NT/base/cluster/mgmt/cluscfg/middletier/objectmanager.cpp
2020-09-26 16:20:57 +08:00

1218 lines
29 KiB
C++

//////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1999-2001 Microsoft Corporation
//
// Module Name:
// ObjectManager.cpp
//
// Description:
// Object Manager implementation.
//
// Documentation:
// Yes.
//
// Maintained By:
// Galen Barbee (GalenB) 22-NOV-1999
//
//////////////////////////////////////////////////////////////////////////////
#include "pch.h"
#include "ObjectManager.h"
#include "ConnectionInfo.h"
#include "StandardInfo.h"
#include "EnumCookies.h"
DEFINE_THISCLASS("CObjectManager")
#define COOKIE_BUFFER_GROW_SIZE 100
// ************************************************************************
//
// Constructor / Destructor
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// LPUNKNOWN
// CObjectManager::S_HrCreateInstance(
// IUnknown ** ppunkOut
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CObjectManager::S_HrCreateInstance(
IUnknown ** ppunkOut
)
{
TraceFunc( "" );
Assert( ppunkOut != NULL );
HRESULT hr;
IServiceProvider * psp;
// Don't wrap - this can fail with E_POINTER.
hr = CServiceManager::S_HrGetManagerPointer( &psp );
if ( SUCCEEDED( hr ) )
{
hr = THR( psp->TypeSafeQS( CLSID_ObjectManager,
IUnknown,
ppunkOut
) );
psp->Release( );
} // if: service manager
else if ( hr == E_POINTER )
{
//
// This happens when the Service Manager is first started.
//
CObjectManager * pom = new CObjectManager( );
if ( pom != NULL )
{
hr = THR( pom->Init( ) );
if ( SUCCEEDED( hr ) )
{
hr = THR( pom->TypeSafeQI( IUnknown, ppunkOut ) );
} // if: success
pom->Release( );
} // if: got object
else
{
hr = E_OUTOFMEMORY;
}
} // if: service manager doesn't exists
else
{
THR( hr );
} // else:
HRETURN( hr );
} // S_HrCreateInstance( )
//////////////////////////////////////////////////////////////////////////////
//
// CObjectManager::CObjectManager( void )
//
//////////////////////////////////////////////////////////////////////////////
CObjectManager::CObjectManager( void )
{
TraceFunc( "" );
InterlockedIncrement( &g_cObjects );
TraceFuncExit();
} // CObjectManager( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::Init( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::Init( void )
{
TraceFunc( "" );
HRESULT hr = S_OK;
// IUnknown stuff
Assert( m_cRef == 0 );
AddRef( ); // Add one count
// IObjectManager
Assert( m_cAllocSize == 0 );
Assert( m_cCurrentUsed == 0 );
Assert( m_pCookies == NULL );
HRETURN( hr );
} // Init( )
//////////////////////////////////////////////////////////////////////////////
//
// CObjectManager::~CObjectManager( )
//
//////////////////////////////////////////////////////////////////////////////
CObjectManager::~CObjectManager( )
{
TraceFunc( "" );
if ( m_pCookies != NULL )
{
while ( m_cCurrentUsed != 0 )
{
m_cCurrentUsed --;
if ( m_pCookies[ m_cCurrentUsed ] != NULL )
{
m_pCookies[ m_cCurrentUsed ]->Release( );
}
}
TraceFree( m_pCookies );
}
InterlockedDecrement( &g_cObjects );
TraceFuncExit();
} // ~CObjectManager( )
// ************************************************************************
//
// IUnknown
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::QueryInterface(
// REFIID riid,
// LPVOID *ppv
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::QueryInterface(
REFIID riid,
LPVOID *ppv
)
{
TraceQIFunc( riid, ppv );
HRESULT hr = E_NOINTERFACE;
if ( IsEqualIID( riid, IID_IUnknown ) )
{
*ppv = static_cast< LPUNKNOWN >( this );
hr = S_OK;
} // if: IUnknown
else if ( IsEqualIID( riid, IID_IObjectManager ) )
{
*ppv = TraceInterface( __THISCLASS__, IObjectManager, this, 0 );
hr = S_OK;
} // else if: IObjectManager
if ( SUCCEEDED( hr ) )
{
((IUnknown*) *ppv)->AddRef( );
} // if: success
QIRETURN_IGNORESTDMARSHALLING( hr, riid );
}
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP_(ULONG)
// CObjectManager::AddRef( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CObjectManager::AddRef( void )
{
TraceFunc( "[IUnknown]" );
InterlockedIncrement( &m_cRef );
RETURN( m_cRef );
} // AddRef( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP_(ULONG)
// CObjectManager::Release( void )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP_(ULONG)
CObjectManager::Release( void )
{
TraceFunc( "[IUnknown]" );
InterlockedDecrement( &m_cRef );
if ( m_cRef )
RETURN( m_cRef );
TraceDo( delete this );
RETURN(0);
} // Release( )
// ************************************************************************
//
// IObjectManager
//
// ************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::FindObject(
// REFCLSID rclsidTypeIn,
// OBJECTCOOKIE cookieParentIn,
// LPCWSTR pcszNameIn,
// REFCLSID rclsidFormatIn,
// OBJECTCOOKIE * cookieOut,
// LPUNKNOWN * punkOut
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::FindObject(
REFCLSID rclsidTypeIn,
OBJECTCOOKIE cookieParentIn,
LPCWSTR pcszNameIn,
REFCLSID rclsidFormatIn,
OBJECTCOOKIE * pcookieOut,
LPUNKNOWN * ppunkOut
)
{
TraceFunc( "[IObjectManager]" );
ExtObjectEntry * pentry;
HRESULT hr = E_UNEXPECTED;
OBJECTCOOKIE cookie = 0;
CStandardInfo * pcsi = NULL; // don't free
BOOL fTempCookie = FALSE;
CEnumCookies * pcec = NULL;
IUnknown * punk = NULL;
IExtendObjectManager * peom = NULL;
//
// Check to see if we already have an object.
//
if ( pcszNameIn != NULL )
{
hr = STHR( HrSearchForExistingCookie( rclsidTypeIn, cookieParentIn, pcszNameIn, &cookie ) );
if ( FAILED( hr ) )
goto Cleanup;
if ( hr == S_FALSE )
{
hr = THR( HrCreateNewCookie( rclsidTypeIn, cookieParentIn, pcszNameIn, &cookie ) );
if ( FAILED( hr ) )
goto Cleanup;
pcsi = m_pCookies[ cookie ];
Assert( pcsi != NULL );
}
else if ( hr == S_OK )
{
//
// Found an existing cookie.
//
if ( pcookieOut != NULL )
{
*pcookieOut = cookie;
}
if ( ppunkOut != NULL )
{
pcsi = m_pCookies[ cookie ];
//
// Is the object still in an failed state or still pending?
//
if ( FAILED( pcsi->m_hrStatus ) )
{
hr = pcsi->m_hrStatus;
goto Cleanup;
}
//
// Retrieve the requested format.
//
hr = THR( GetObject( rclsidFormatIn, cookie, ppunkOut ) );
// we always jump to cleanup. No need to check hr here.
goto Cleanup;
}
}
else
{
//
// Unexpected error_success - now what?
//
Assert( !hr );
goto Cleanup;
}
} // if: named object
else
{
Assert( pcsi == NULL );
}
//
// Create a new object.
//
if ( IsEqualIID( rclsidFormatIn, IID_NULL )
|| ppunkOut == NULL
)
{
//
// No-op.
//
hr = S_OK;
}
else if ( IsEqualIID( rclsidFormatIn, DFGUID_StandardInfo ) )
{
hr = THR( pcsi->QueryInterface( DFGUID_StandardInfo,
reinterpret_cast< void ** >( ppunkOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
}
else if ( IsEqualIID( rclsidFormatIn, DFGUID_ConnectionInfoFormat ) )
{
if ( pcsi->m_pci != NULL )
{
*ppunkOut = TraceInterface( L"CConnectionInfo!ObjectManager", IConnectionInfo, pcsi->m_pci, 0 );
(*ppunkOut)->AddRef( );
hr = S_OK;
}
else
{
hr = THR( CConnectionInfo::S_HrCreateInstance( &punk,
pcsi->m_cookieParent
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->TypeSafeQI( IConnectionInfo,
&pcsi->m_pci
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->QueryInterface( IID_IConnectionInfo,
reinterpret_cast< void ** >( ppunkOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
}
}
else if ( IsEqualIID( rclsidFormatIn, DFGUID_EnumCookies ) )
{
ULONG cIter;
//
// Create a new cookie enumerator.
//
pcec = new CEnumCookies;
if ( pcec == NULL )
goto OutOfMemory;
//
// Initialize the enumerator. This also cause an AddRef( ).
//
hr = THR( pcec->Init( ) );
if ( FAILED( hr ) )
goto Cleanup;
//
// See who matches our citeria.
//
pcec->m_cIter = 0;
for( cIter = 1; cIter < m_cCurrentUsed; cIter ++ )
{
pcsi = m_pCookies[ cIter ];
if ( pcsi != NULL )
{
if ( rclsidTypeIn == IID_NULL
|| pcsi->m_clsidType == rclsidTypeIn
)
{
if ( cookieParentIn == NULL
|| pcsi->m_cookieParent == cookieParentIn
)
{
if ( ( pcszNameIn == NULL )
|| ( ( pcsi->m_bstrName != NULL )
&& ( StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 )
)
)
{
//
// Match!
//
pcec->m_cIter ++;
} // if: names match
} // if: parents match
} // if: match parent and type
} // if: valid element
} // for: cIter
if ( pcec->m_cIter == 0 )
goto ErrorNotFound;
//
// Alloc an array to hold the cookies.
//
pcec->m_pList = (OBJECTCOOKIE*) TraceAlloc( HEAP_ZERO_MEMORY, pcec->m_cIter * sizeof(OBJECTCOOKIE) );
if ( pcec->m_pList == NULL )
goto OutOfMemory;
pcec->m_cAlloced = pcec->m_cIter;
pcec->m_cIter = 0;
for( cIter = 1; cIter < m_cCurrentUsed; cIter ++ )
{
pcsi = m_pCookies[ cIter ];
if ( pcsi != NULL )
{
if ( rclsidTypeIn == IID_NULL
|| pcsi->m_clsidType == rclsidTypeIn
)
{
if ( cookieParentIn == NULL
|| pcsi->m_cookieParent == cookieParentIn
)
{
if ( ( pcszNameIn == NULL )
|| ( ( pcsi->m_bstrName != NULL )
&& ( StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 )
)
)
{
//
// Match!
//
pcec->m_pList[ pcec->m_cIter ] = cIter;
pcec->m_cIter ++;
} // if: names match
} // if: parents match
} // if: match parent and type
} // if: valid element
} // for: cIter
Assert( pcec->m_cIter != 0 );
pcec->m_cCookies = pcec->m_cIter;
pcec->m_cIter = 0;
//
// Grab the inteface on the way out.
//
hr = THR( pcec->QueryInterface( IID_IEnumCookies,
reinterpret_cast< void ** >( ppunkOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
}
else
{
//
// Check for extension formats.
//
//
// See if the format already exists for this cookie.
//
if ( punk != NULL )
{
punk->Release( );
punk = NULL;
}
if ( pcsi != NULL )
{
for( pentry = pcsi->m_pExtObjList; pentry != NULL; pentry = pentry->pNext )
{
if ( pentry->iid == rclsidFormatIn )
{
hr = THR( pentry->punk->QueryInterface( rclsidFormatIn,
reinterpret_cast< void ** >( &punk )
) );
if ( FAILED( hr ) )
goto Cleanup;
break; // exit loop
}
} // for: pentry
} // if: have cookie
else
{
//
// Create a temporary cookie.
//
Assert( pcszNameIn == NULL );
hr = THR( HrCreateNewCookie( IID_NULL, cookieParentIn, NULL, &cookie ) );
if ( FAILED( hr ) )
goto Cleanup;
fTempCookie = TRUE;
Assert( pcsi == NULL );
} // else: need a temporary cookie
if ( punk == NULL )
{
//
// Possibly a new or externally object, try creating it and querying.
//
hr = THR( HrCoCreateInternalInstance( rclsidFormatIn,
NULL,
CLSCTX_ALL,
TypeSafeParams( IExtendObjectManager, &peom )
) );
if ( FAILED( hr ) )
goto Cleanup;
Assert( punk == NULL );
// Can't wrap with THR because it can return E_PENDING.
hr = peom->FindObject( cookie,
rclsidTypeIn,
pcszNameIn,
&punk
);
if ( hr == E_PENDING )
{
// ignore
}
else if ( FAILED( hr ) )
{
THR( hr );
goto Cleanup;
}
if ( fTempCookie )
{
(m_pCookies[ cookie ])->Release( );
m_pCookies[ cookie ] = NULL;
}
else
{
//
// Keep track of the format (if extension wants)
//
if ( ( ( SUCCEEDED( hr )
&& hr != S_FALSE
)
|| hr == E_PENDING
)
&& punk != NULL
&& pcsi != NULL
)
{
pentry = (ExtObjectEntry *) TraceAlloc( 0, sizeof(ExtObjectEntry) );
if ( pentry == NULL )
goto OutOfMemory;
pentry->iid = rclsidFormatIn;
pentry->pNext = pcsi->m_pExtObjList;
pentry->punk = punk;
pentry->punk->AddRef( );
pcsi->m_pExtObjList = pentry; // update header of list (LIFO)
pcsi->m_hrStatus = hr; // update status
}
} // else: persistent cookie
if ( SUCCEEDED( hr ) )
{
// Give up ownership
*ppunkOut = punk;
punk = NULL;
}
} // if: creating new object
} // else: possible extension format
//
// Save stuff for the caller.
//
if ( pcookieOut != NULL )
{
*pcookieOut = cookie;
}
Cleanup:
if ( punk != NULL )
{
punk->Release( );
}
if ( peom != NULL )
{
peom->Release( );
}
if ( pcec != NULL )
{
pcec->Release( );
}
HRETURN( hr );
OutOfMemory:
hr = E_OUTOFMEMORY;
goto Cleanup;
ErrorNotFound:
// The error text is better than the coding value.
hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
goto Cleanup;
} // FindObject( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::GetObject(
// REFCLSID rclsidFormatIn,
// OBJECTCOOKIE cookieIn,
// LPUNKNOWN * ppunkOut
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::GetObject(
REFCLSID rclsidFormatIn,
OBJECTCOOKIE cookieIn,
LPUNKNOWN * ppunkOut
)
{
TraceFunc( "[IObjectManager]" );
CStandardInfo * pcsi;
ExtObjectEntry * pentry;
HRESULT hr = E_UNEXPECTED;
IUnknown * punk = NULL;
IExtendObjectManager * peom = NULL;
//
// Check parameters
//
if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
goto InvalidArg;
pcsi = m_pCookies[ cookieIn ];
if ( pcsi == NULL )
goto ErrorNotFound;
//
// Create the request format object.
//
if ( IsEqualIID( rclsidFormatIn, IID_NULL )
|| ppunkOut == NULL
)
{
//
// No-op.
//
hr = S_OK;
}
else if ( IsEqualIID( rclsidFormatIn, DFGUID_StandardInfo ) )
{
hr = THR( pcsi->QueryInterface( DFGUID_StandardInfo,
reinterpret_cast< void ** >( ppunkOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
}
else if ( IsEqualIID( rclsidFormatIn, DFGUID_ConnectionInfoFormat ) )
{
if ( pcsi->m_pci != NULL )
{
*ppunkOut = pcsi->m_pci;
(*ppunkOut)->AddRef( );
hr = S_OK;
}
else
{
hr = THR( CConnectionInfo::S_HrCreateInstance( &punk,
pcsi->m_cookieParent
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->TypeSafeQI( IConnectionInfo,
&pcsi->m_pci
) );
if ( FAILED( hr ) )
goto Cleanup;
hr = THR( punk->QueryInterface( IID_IConnectionInfo,
reinterpret_cast< void ** >( ppunkOut )
) );
if ( FAILED( hr ) )
goto Cleanup;
}
}
else
{
//
// See if the format already exists for this cookie.
//
if ( punk != NULL )
{
punk->Release( );
punk = NULL;
}
for( pentry = pcsi->m_pExtObjList; pentry != NULL; pentry = pentry->pNext )
{
if ( pentry->iid == rclsidFormatIn )
{
hr = THR( pentry->punk->QueryInterface( rclsidFormatIn,
reinterpret_cast< void ** >( &punk )
) );
if ( FAILED( hr ) )
goto Cleanup;
break; // exit loop
}
} // for: pentry
if ( punk == NULL )
goto ErrorNotFound;
// Give up ownership
*ppunkOut = punk;
punk = NULL;
} // else: external?
Cleanup:
if ( punk != NULL )
{
punk->Release( );
}
if ( peom != NULL )
{
peom->Release( );
}
HRETURN( hr );
InvalidArg:
hr = THR( E_INVALIDARG );
goto Cleanup;
ErrorNotFound:
hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
goto Cleanup;
#if 0
OutOfMemory:
hr = E_OUTOFMEMORY;
goto Cleanup;
#endif
} // GetObject( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::RemoveObject(
// OBJECTCOOKIE cookieIn
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::RemoveObject(
OBJECTCOOKIE cookieIn
)
{
TraceFunc( "[IObjectManager]" );
HRESULT hr = E_UNEXPECTED;
CStandardInfo * pcsi;
BOOL fLocked = FALSE;
//
// Check parameters
//
if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
goto InvalidArg;
pcsi = m_pCookies[ cookieIn ];
if ( pcsi == NULL )
goto ErrorNotFound;
hr = THR( HrDeleteInstanceAndChildren( cookieIn ) );
if ( FAILED( hr ) )
goto Cleanup;
Cleanup:
HRETURN( hr );
InvalidArg:
hr = THR( E_INVALIDARG );
goto Cleanup;
ErrorNotFound:
hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
goto Cleanup;
} // RemoveObject( )
//////////////////////////////////////////////////////////////////////////////
//
// STDMETHODIMP
// CObjectManager::SetObjectStatus(
// OBJECTCOOKIE cookieIn,
// HRESULT hrIn
// )
//
//////////////////////////////////////////////////////////////////////////////
STDMETHODIMP
CObjectManager::SetObjectStatus(
OBJECTCOOKIE cookieIn,
HRESULT hrIn
)
{
TraceFunc( "[IObjectManager]" );
HRESULT hr = S_OK;
CStandardInfo * pcsi;
//
// Check parameters
//
if ( cookieIn == 0 || cookieIn >= m_cCurrentUsed )
goto InvalidArg;
pcsi = m_pCookies[ cookieIn ];
if ( pcsi == NULL )
goto ErrorNotFound;
//
// Update the status.
//
pcsi->m_hrStatus = hrIn;
Cleanup:
HRETURN( hr );
InvalidArg:
hr = THR( E_INVALIDARG );
goto Cleanup;
ErrorNotFound:
hr = THR( HRESULT_FROM_WIN32( ERROR_NOT_FOUND ) );
goto Cleanup;
} // SetObjectStatus( )
//****************************************************************************
//
// Privates
//
//****************************************************************************
//////////////////////////////////////////////////////////////////////////////
//
// HRESULT
// CObjectManager::HrDeleteCookie(
// OBJECTCOOKIE cookieIn
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CObjectManager::HrDeleteCookie(
OBJECTCOOKIE cookieIn
)
{
TraceFunc1( "cookieIn = %#X", cookieIn );
HRESULT hr = S_OK;
CStandardInfo * pcsi;
Assert( cookieIn != 0 && cookieIn < m_cCurrentUsed );
pcsi = m_pCookies[ cookieIn ];
Assert( pcsi != NULL );
pcsi->Release( );
m_pCookies[ cookieIn ] = NULL;
HRETURN( hr );
} // HrDeleteCookie( )
//////////////////////////////////////////////////////////////////////////////
//
// HRESULT
// CObjectManager::HrSearchForExistingCookie(
// OBJECTCOOKIE cookieIn,
// LPUNKNOWN ppunkOut
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CObjectManager::HrSearchForExistingCookie(
REFCLSID rclsidTypeIn,
OBJECTCOOKIE cookieParentIn,
LPCWSTR pcszNameIn,
OBJECTCOOKIE * pcookieOut
)
{
TraceFunc( "" );
Assert( pcszNameIn != NULL );
Assert( pcookieOut != NULL );
HRESULT hr = S_FALSE;
ULONG idx;
CStandardInfo * pcsi;
//
// Search the list.
//
for( idx = 1; idx < m_cCurrentUsed; idx ++ )
{
pcsi = m_pCookies[ idx ];
if ( pcsi != NULL )
{
if ( pcsi->m_cookieParent == cookieParentIn // matching parents
&& IsEqualIID( pcsi->m_clsidType, rclsidTypeIn ) // matching types
&& StrCmpI( pcsi->m_bstrName, pcszNameIn ) == 0 // matching names
)
{
//
// Found a match.
//
*pcookieOut = idx;
hr = S_OK;
break; // exit loop
} // if: match
} // if: cookie exists
} // while: pcsi
HRETURN( hr );
} // HrSearchForExistingCookie( )
//////////////////////////////////////////////////////////////////////////////
//
// HRESULT
// CObjectManager::HrDeleteInstanceAndChildren(
// OBJECTCOOKIE pcsiIn
// )
//
// Notes:
// This should be called while the ListLock is held!
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CObjectManager::HrDeleteInstanceAndChildren(
OBJECTCOOKIE cookieIn
)
{
TraceFunc1( "cookieIn = %#X", cookieIn );
ULONG idx;
CStandardInfo * pcsi;
HRESULT hr = S_OK;
hr = THR( HrDeleteCookie( cookieIn ) );
if ( FAILED( hr ) )
goto Cleanup;
for ( idx = 1; idx < m_cCurrentUsed; idx ++ )
{
pcsi = m_pCookies[ idx ];
if ( pcsi != NULL
&& pcsi->m_cookieParent == cookieIn )
{
hr = THR( HrDeleteInstanceAndChildren( idx ) );
if ( FAILED( hr ) )
goto Cleanup;
} // if:
} // while:
Cleanup:
HRETURN( hr );
} // HrDeleteInstanceAndChildren( )
//////////////////////////////////////////////////////////////////////////////
//
// HRESULT
// CObjectManager::HrCreateNewCookie(
// REFCLSID rclsidTypeIn
// OBJECTCOOKIE cookieParentIn,
// BSTR pcszNameIn,
// OBJECTCOOKIE * pcookieOut
// )
//
//////////////////////////////////////////////////////////////////////////////
HRESULT
CObjectManager::HrCreateNewCookie(
REFCLSID rclsidTypeIn,
OBJECTCOOKIE cookieParentIn,
LPCWSTR pcszNameIn,
OBJECTCOOKIE * pcookieOut
)
{
TraceFunc( "" );
HRESULT hr = E_UNEXPECTED;
CStandardInfo * pcsi = NULL;
Assert( pcookieOut != NULL );
*pcookieOut = 0;
//
// Create some space for it.
//
if ( m_cCurrentUsed == m_cAllocSize )
{
CStandardInfo ** pnew = (CStandardInfo **) TraceAlloc( HEAP_ZERO_MEMORY, sizeof(CStandardInfo *) * ( m_cAllocSize + COOKIE_BUFFER_GROW_SIZE ) );
if ( pnew == NULL )
goto OutOfMemory;
if ( m_pCookies != NULL )
{
CopyMemory( pnew, m_pCookies, sizeof(CStandardInfo *) * m_cCurrentUsed );
TraceFree( m_pCookies );
}
m_pCookies = pnew;
m_cAllocSize += COOKIE_BUFFER_GROW_SIZE;
if ( m_cCurrentUsed == 0 )
{
//
// Always skip zero.
//
m_cCurrentUsed = 1;
}
}
pcsi = new CStandardInfo( );
if ( pcsi == NULL )
goto OutOfMemory;
hr = THR( pcsi->Init( ) );
if ( FAILED( hr ) )
goto Cleanup;
m_pCookies[ m_cCurrentUsed ] = pcsi;
//
// Initialize the rest of the structure.
//
pcsi->m_cookieParent = cookieParentIn;
pcsi->m_hrStatus = E_PENDING;
CopyMemory( &pcsi->m_clsidType, &rclsidTypeIn, sizeof( pcsi->m_clsidType ) );
if ( pcszNameIn != NULL )
{
pcsi->m_bstrName = TraceSysAllocString( pcszNameIn );
if ( pcsi->m_bstrName == NULL )
{
m_cCurrentUsed --;
goto OutOfMemory;
} // if: out of memory
}
Assert( pcsi->m_pci == NULL );
Assert( pcsi->m_pExtObjList == NULL );
//
// Keep it around and return SUCCESS!
//
pcsi = NULL;
*pcookieOut = m_cCurrentUsed;
m_cCurrentUsed ++;
hr = S_OK;
Cleanup:
if ( pcsi != NULL )
{
pcsi->Release( );
}
HRETURN( hr );
OutOfMemory:
hr = E_OUTOFMEMORY;
goto Cleanup;
} // HrCreateNewCookie( )