|  | /* | 
|  | * 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; | 
|  | } |