/* * List of components. (for internal use) * * hidenori@a2.ctktv.ne.jp */ #include "config.h" #include "windef.h" #include "winbase.h" #include "winerror.h" #include "wine/obj_base.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(quartz); #include "quartz_private.h" #include "complist.h" struct QUARTZ_CompList { QUARTZ_CompListItem* pFirst; QUARTZ_CompListItem* pLast; CRITICAL_SECTION csList; }; struct QUARTZ_CompListItem { IUnknown* punk; QUARTZ_CompListItem* pNext; QUARTZ_CompListItem* pPrev; void* pvData; DWORD dwDataLen; }; QUARTZ_CompList* QUARTZ_CompList_Alloc( void ) { QUARTZ_CompList* pList; pList = (QUARTZ_CompList*)QUARTZ_AllocMem( sizeof(QUARTZ_CompList) ); if ( pList != NULL ) { /* construct. */ pList->pFirst = NULL; pList->pLast = NULL; InitializeCriticalSection( &pList->csList ); } return pList; } void QUARTZ_CompList_Free( QUARTZ_CompList* pList ) { QUARTZ_CompListItem* pCur; QUARTZ_CompListItem* pNext; if ( pList != NULL ) { pCur = pList->pFirst; while ( pCur != NULL ) { pNext = pCur->pNext; if ( pCur->punk != NULL ) IUnknown_Release( pCur->punk ); if ( pCur->pvData != NULL ) QUARTZ_FreeMem( pCur->pvData ); QUARTZ_FreeMem( pCur ); pCur = pNext; } DeleteCriticalSection( &pList->csList ); QUARTZ_FreeMem( pList ); } } void QUARTZ_CompList_Lock( QUARTZ_CompList* pList ) { EnterCriticalSection( &pList->csList ); } void QUARTZ_CompList_Unlock( QUARTZ_CompList* pList ) { LeaveCriticalSection( &pList->csList ); } QUARTZ_CompList* QUARTZ_CompList_Dup( const QUARTZ_CompList* pList, BOOL fDupData ) { QUARTZ_CompList* pNewList; const QUARTZ_CompListItem* pCur; HRESULT hr; pNewList = QUARTZ_CompList_Alloc(); if ( pNewList == NULL ) return NULL; pCur = pList->pFirst; while ( pCur != NULL ) { if ( pCur->punk != NULL ) { if ( fDupData ) hr = QUARTZ_CompList_AddComp( pNewList, pCur->punk, pCur->pvData, pCur->dwDataLen ); else hr = QUARTZ_CompList_AddComp( pNewList, pCur->punk, NULL, 0 ); if ( FAILED(hr) ) { QUARTZ_CompList_Free( pNewList ); return NULL; } } pCur = pCur->pNext; } return pNewList; } static QUARTZ_CompListItem* QUARTZ_CompList_AllocComp( QUARTZ_CompList* pList, IUnknown* punk, const void* pvData, DWORD dwDataLen ) { QUARTZ_CompListItem* pItem; pItem = (QUARTZ_CompListItem*)QUARTZ_AllocMem( sizeof(QUARTZ_CompListItem) ); if ( pItem == NULL ) return NULL; pItem->pvData = NULL; pItem->dwDataLen = 0; if ( pvData != NULL ) { pItem->pvData = (void*)QUARTZ_AllocMem( dwDataLen ); if ( pItem->pvData == NULL ) { QUARTZ_FreeMem( pItem ); return NULL; } memcpy( pItem->pvData, pvData, dwDataLen ); pItem->dwDataLen = dwDataLen; } pItem->punk = punk; IUnknown_AddRef(punk); return pItem; } HRESULT QUARTZ_CompList_AddComp( QUARTZ_CompList* pList, IUnknown* punk, const void* pvData, DWORD dwDataLen ) { QUARTZ_CompListItem* pItem; pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); if ( pItem == NULL ) return E_OUTOFMEMORY; if ( pList->pFirst != NULL ) pList->pFirst->pPrev = pItem; else pList->pLast = pItem; pItem->pNext = pList->pFirst; pList->pFirst = pItem; pItem->pPrev = NULL; return S_OK; } HRESULT QUARTZ_CompList_AddTailComp( QUARTZ_CompList* pList, IUnknown* punk, const void* pvData, DWORD dwDataLen ) { QUARTZ_CompListItem* pItem; pItem = QUARTZ_CompList_AllocComp( pList, punk, pvData, dwDataLen ); if ( pItem == NULL ) return E_OUTOFMEMORY; if ( pList->pLast != NULL ) pList->pLast->pNext = pItem; else pList->pFirst = pItem; pItem->pPrev = pList->pLast; pList->pLast = pItem; pItem->pNext = NULL; return S_OK; } HRESULT QUARTZ_CompList_RemoveComp( QUARTZ_CompList* pList, IUnknown* punk ) { QUARTZ_CompListItem* pCur; pCur = QUARTZ_CompList_SearchComp( pList, punk ); if ( pCur == NULL ) return S_FALSE; /* already removed. */ /* remove from list. */ if ( pCur->pNext != NULL ) pCur->pNext->pPrev = pCur->pPrev; else pList->pLast = pCur->pPrev; if ( pCur->pPrev != NULL ) pCur->pPrev->pNext = pCur->pNext; else pList->pFirst = pCur->pNext; /* release this item. */ if ( pCur->punk != NULL ) IUnknown_Release( pCur->punk ); if ( pCur->pvData != NULL ) QUARTZ_FreeMem( pCur->pvData ); QUARTZ_FreeMem( pCur ); return S_OK; } QUARTZ_CompListItem* QUARTZ_CompList_SearchComp( QUARTZ_CompList* pList, IUnknown* punk ) { QUARTZ_CompListItem* pCur; pCur = pList->pFirst; while ( pCur != NULL ) { if ( pCur->punk == punk ) return pCur; pCur = pCur->pNext; } return NULL; } QUARTZ_CompListItem* QUARTZ_CompList_SearchData( QUARTZ_CompList* pList, const void* pvData, DWORD dwDataLen ) { QUARTZ_CompListItem* pCur; pCur = pList->pFirst; while ( pCur != NULL ) { if ( pCur->dwDataLen == dwDataLen && !memcmp( pCur->pvData, pvData, dwDataLen ) ) return pCur; pCur = pCur->pNext; } return NULL; } QUARTZ_CompListItem* QUARTZ_CompList_GetFirst( QUARTZ_CompList* pList ) { return pList->pFirst; } QUARTZ_CompListItem* QUARTZ_CompList_GetLast( QUARTZ_CompList* pList ) { return pList->pLast; } QUARTZ_CompListItem* QUARTZ_CompList_GetNext( QUARTZ_CompList* pList, QUARTZ_CompListItem* pPrev ) { return pPrev->pNext; } QUARTZ_CompListItem* QUARTZ_CompList_GetPrev( QUARTZ_CompList* pList, QUARTZ_CompListItem* pNext ) { return pNext->pPrev; } IUnknown* QUARTZ_CompList_GetItemPtr( QUARTZ_CompListItem* pItem ) { return pItem->punk; } const void* QUARTZ_CompList_GetDataPtr( QUARTZ_CompListItem* pItem ) { return pItem->pvData; } DWORD QUARTZ_CompList_GetDataLength( QUARTZ_CompListItem* pItem ) { return pItem->dwDataLen; }