2012-05-14 08:06:30 +02:00
/*
* IDirectMusicCollection Implementation
2003-07-22 00:10:14 +02:00
*
2004-01-20 01:21:40 +01:00
* Copyright ( C ) 2003 - 2004 Rok Mandeljc
2003-07-22 00:10:14 +02:00
*
2007-05-30 12:54:07 +02:00
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
2003-07-22 00:10:14 +02:00
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
2007-05-30 12:54:07 +02:00
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
2003-07-22 00:10:14 +02:00
*
2007-05-30 12:54:07 +02:00
* You should have received a copy of the GNU Lesser General Public
* License along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
2003-07-22 00:10:14 +02:00
*/
# include "dmusic_private.h"
WINE_DEFAULT_DEBUG_CHANNEL ( dmusic ) ;
2004-01-20 01:21:40 +01:00
WINE_DECLARE_DEBUG_CHANNEL ( dmfile ) ;
2003-07-22 00:10:14 +02:00
2012-05-14 08:06:30 +02:00
static inline IDirectMusicCollectionImpl * impl_from_IDirectMusicCollection ( IDirectMusicCollection * iface )
{
return CONTAINING_RECORD ( iface , IDirectMusicCollectionImpl , IDirectMusicCollection_iface ) ;
}
static inline IDirectMusicCollectionImpl * impl_from_IDirectMusicObject ( IDirectMusicObject * iface )
{
return CONTAINING_RECORD ( iface , IDirectMusicCollectionImpl , IDirectMusicObject_iface ) ;
}
static inline IDirectMusicCollectionImpl * impl_from_IPersistStream ( IPersistStream * iface )
{
return CONTAINING_RECORD ( iface , IDirectMusicCollectionImpl , IPersistStream_iface ) ;
}
2006-06-10 11:57:22 +02:00
2004-01-20 01:21:40 +01:00
/*****************************************************************************
* IDirectMusicCollectionImpl implementation
*/
/* IDirectMusicCollectionImpl IUnknown part: */
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_QueryInterface ( LPDIRECTMUSICCOLLECTION iface , REFIID riid , LPVOID * ret_iface )
{
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicCollection ( iface ) ;
TRACE ( " (%p/%p)->(%s, %p) \n " , iface , This , debugstr_dmguid ( riid ) , ret_iface ) ;
if ( IsEqualIID ( riid , & IID_IUnknown ) | |
IsEqualIID ( riid , & IID_IDirectMusicCollection ) )
{
* ret_iface = iface ;
IDirectMusicCollection_AddRef ( iface ) ;
return S_OK ;
}
else if ( IsEqualIID ( riid , & IID_IDirectMusicObject ) )
{
* ret_iface = & This - > IDirectMusicObject_iface ;
IDirectMusicCollection_AddRef ( iface ) ;
return S_OK ;
}
else if ( IsEqualIID ( riid , & IID_IPersistStream ) )
{
* ret_iface = & This - > IPersistStream_iface ;
IDirectMusicCollection_AddRef ( iface ) ;
return S_OK ;
}
* ret_iface = NULL ;
WARN ( " (%p/%p)->(%s, %p): not found \n " , iface , This , debugstr_dmguid ( riid ) , ret_iface ) ;
return E_NOINTERFACE ;
2003-07-22 00:10:14 +02:00
}
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef ( LPDIRECTMUSICCOLLECTION iface )
{
2012-05-18 12:01:36 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicCollection ( iface ) ;
ULONG ref = InterlockedIncrement ( & This - > ref ) ;
2005-01-14 17:02:20 +01:00
2012-05-18 12:01:36 +02:00
TRACE ( " (%p/%p)->(): new ref = %u) \n " , iface , This , ref ) ;
2005-01-14 17:02:20 +01:00
2012-05-18 12:01:36 +02:00
DMUSIC_LockModule ( ) ;
2005-01-26 20:41:43 +01:00
2012-05-18 12:01:36 +02:00
return ref ;
2003-07-22 00:10:14 +02:00
}
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_Release ( LPDIRECTMUSICCOLLECTION iface )
{
2012-05-18 12:01:36 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicCollection ( iface ) ;
ULONG ref = InterlockedDecrement ( & This - > ref ) ;
2005-01-14 17:02:20 +01:00
2012-05-18 12:01:36 +02:00
TRACE ( " (%p/%p)->(): new ref = %u) \n " , iface , This , ref ) ;
2005-01-14 17:02:20 +01:00
2012-05-18 12:01:36 +02:00
if ( ! ref )
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
2005-01-26 20:41:43 +01:00
2012-05-18 12:01:36 +02:00
DMUSIC_UnlockModule ( ) ;
2005-01-26 20:41:43 +01:00
2012-05-18 12:01:36 +02:00
return ref ;
2003-07-22 00:10:14 +02:00
}
2012-05-14 08:06:30 +02:00
/* IDirectMusicCollection Interface follows: */
2012-05-18 12:01:44 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstrument ( LPDIRECTMUSICCOLLECTION iface , DWORD patch , IDirectMusicInstrument * * instrument )
2012-05-14 08:06:30 +02:00
{
2012-05-18 12:01:44 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicCollection ( iface ) ;
DMUS_PRIVATE_INSTRUMENTENTRY * inst_entry ;
struct list * list_entry ;
DWORD inst_patch ;
TRACE ( " (%p/%p)->(%u, %p) \n " , iface , This , patch , instrument ) ;
LIST_FOR_EACH ( list_entry , & This - > Instruments ) {
inst_entry = LIST_ENTRY ( list_entry , DMUS_PRIVATE_INSTRUMENTENTRY , entry ) ;
IDirectMusicInstrument_GetPatch ( inst_entry - > pInstrument , & inst_patch ) ;
if ( patch = = inst_patch ) {
* instrument = inst_entry - > pInstrument ;
IDirectMusicInstrument_AddRef ( inst_entry - > pInstrument ) ;
IDirectMusicInstrumentImpl_Custom_Load ( inst_entry - > pInstrument , This - > pStm ) ;
TRACE ( " : returning instrument %p \n " , * instrument ) ;
return S_OK ;
}
}
2004-01-20 01:21:40 +01:00
2012-05-18 12:01:44 +02:00
TRACE ( " : instrument not found \n " ) ;
return DMUS_E_INVALIDPATCH ;
2003-07-22 00:10:14 +02:00
}
2012-05-18 12:01:55 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicCollection_EnumInstrument ( LPDIRECTMUSICCOLLECTION iface , DWORD index , DWORD * patch , LPWSTR name , DWORD name_length )
2012-05-14 08:06:30 +02:00
{
2012-05-18 12:01:55 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicCollection ( iface ) ;
DWORD i = 0 ;
DMUS_PRIVATE_INSTRUMENTENTRY * inst_entry ;
struct list * list_entry ;
DWORD length ;
TRACE ( " (%p/%p)->(%d, %p, %p, %d) \n " , iface , This , index , patch , name , name_length ) ;
LIST_FOR_EACH ( list_entry , & This - > Instruments ) {
inst_entry = LIST_ENTRY ( list_entry , DMUS_PRIVATE_INSTRUMENTENTRY , entry ) ;
if ( i = = index ) {
IDirectMusicInstrumentImpl * instrument = impl_from_IDirectMusicInstrument ( inst_entry - > pInstrument ) ;
IDirectMusicInstrument_GetPatch ( inst_entry - > pInstrument , patch ) ;
if ( name ) {
length = min ( strlenW ( instrument - > wszName ) , name_length - 1 ) ;
memcpy ( name , instrument - > wszName , length * sizeof ( WCHAR ) ) ;
name [ length ] = ' \0 ' ;
}
return S_OK ;
}
i + + ;
}
return S_FALSE ;
2003-07-22 00:10:14 +02:00
}
2005-06-01 21:57:42 +02:00
static const IDirectMusicCollectionVtbl DirectMusicCollection_Collection_Vtbl = {
2004-01-20 01:21:40 +01:00
IDirectMusicCollectionImpl_IDirectMusicCollection_QueryInterface ,
IDirectMusicCollectionImpl_IDirectMusicCollection_AddRef ,
IDirectMusicCollectionImpl_IDirectMusicCollection_Release ,
IDirectMusicCollectionImpl_IDirectMusicCollection_GetInstrument ,
IDirectMusicCollectionImpl_IDirectMusicCollection_EnumInstrument
2003-07-22 00:10:14 +02:00
} ;
2004-01-20 01:21:40 +01:00
/* IDirectMusicCollectionImpl IDirectMusicObject part: */
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_QueryInterface ( LPDIRECTMUSICOBJECT iface , REFIID riid , LPVOID * ret_iface )
{
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
return IDirectMusicCollection_QueryInterface ( & This - > IDirectMusicCollection_iface , riid , ret_iface ) ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_AddRef ( LPDIRECTMUSICOBJECT iface )
{
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
return IDirectMusicCollection_AddRef ( & This - > IDirectMusicCollection_iface ) ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_Release ( LPDIRECTMUSICOBJECT iface )
{
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
return IDirectMusicCollection_Release ( & This - > IDirectMusicCollection_iface ) ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_GetDescriptor ( LPDIRECTMUSICOBJECT iface , LPDMUS_OBJECTDESC pDesc )
{
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
TRACE ( " (%p/%p)->(%p) \n " , iface , This , pDesc ) ;
/* I think we shouldn't return pointer here since then values can be changed; it'd be a mess */
memcpy ( pDesc , This - > pDesc , This - > pDesc - > dwSize ) ;
return S_OK ;
2003-08-23 01:53:27 +02:00
}
2012-04-10 22:30:21 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_SetDescriptor ( LPDIRECTMUSICOBJECT iface , LPDMUS_OBJECTDESC pDesc )
{
2012-05-14 08:06:30 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
2012-04-10 22:30:21 +02:00
TRACE ( " (%p, %p) \n " , iface , pDesc ) ;
if ( ! pDesc )
return E_POINTER ;
if ( TRACE_ON ( dmusic ) )
{
TRACE ( " Setting descriptor: \n " ) ;
dump_DMUS_OBJECTDESC ( pDesc ) ;
}
2008-02-25 20:48:31 +01:00
2004-01-20 01:21:40 +01:00
/* According to MSDN, we should copy only given values, not whole struct */
if ( pDesc - > dwValidData & DMUS_OBJ_OBJECT )
2008-02-25 20:48:31 +01:00
This - > pDesc - > guidObject = pDesc - > guidObject ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_CLASS )
2008-02-25 20:48:31 +01:00
This - > pDesc - > guidClass = pDesc - > guidClass ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_NAME )
2005-04-18 17:36:20 +02:00
lstrcpynW ( This - > pDesc - > wszName , pDesc - > wszName , DMUS_MAX_NAME ) ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_CATEGORY )
2005-04-18 17:36:20 +02:00
lstrcpynW ( This - > pDesc - > wszCategory , pDesc - > wszCategory , DMUS_MAX_CATEGORY ) ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_FILENAME )
2005-04-18 17:36:20 +02:00
lstrcpynW ( This - > pDesc - > wszFileName , pDesc - > wszFileName , DMUS_MAX_FILENAME ) ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_VERSION )
2008-02-25 20:48:31 +01:00
This - > pDesc - > vVersion = pDesc - > vVersion ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_DATE )
2008-02-25 20:48:31 +01:00
This - > pDesc - > ftDate = pDesc - > ftDate ;
2004-01-20 01:21:40 +01:00
if ( pDesc - > dwValidData & DMUS_OBJ_MEMORY ) {
2011-10-18 05:22:10 +02:00
This - > pDesc - > llMemLength = pDesc - > llMemLength ;
memcpy ( This - > pDesc - > pbMemData , pDesc - > pbMemData , pDesc - > llMemLength ) ;
2004-01-20 01:21:40 +01:00
}
if ( pDesc - > dwValidData & DMUS_OBJ_STREAM ) {
/* according to MSDN, we copy the stream */
IStream_Clone ( pDesc - > pStream , & This - > pDesc - > pStream ) ;
}
/* add new flags */
This - > pDesc - > dwValidData | = pDesc - > dwValidData ;
2003-08-23 01:53:27 +02:00
return S_OK ;
}
2012-05-08 22:29:02 +02:00
static HRESULT read_from_stream ( IStream * stream , void * data , ULONG size )
2012-04-10 22:30:21 +02:00
{
2012-05-08 22:29:02 +02:00
ULONG read ;
HRESULT hr ;
hr = IStream_Read ( stream , data , size , & read ) ;
if ( FAILED ( hr ) ) {
TRACE ( " IStream_Read failed: %08x \n " , hr ) ;
return hr ;
}
if ( read < size ) {
TRACE ( " Didn't read full chunk: %u < %u \n " , read , size ) ;
return E_FAIL ;
}
return S_OK ;
}
2012-04-10 22:30:21 +02:00
2012-05-08 22:29:02 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IDirectMusicObject_ParseDescriptor ( LPDIRECTMUSICOBJECT iface , LPSTREAM stream , LPDMUS_OBJECTDESC desc )
{
2012-05-14 08:06:30 +02:00
IDirectMusicCollectionImpl * This = impl_from_IDirectMusicObject ( iface ) ;
2012-05-08 22:29:02 +02:00
DMUS_PRIVATE_CHUNK chunk ;
DWORD StreamSize , StreamCount , ListSize [ 1 ] , ListCount [ 1 ] ;
LARGE_INTEGER liMove ; /* used when skipping chunks */
HRESULT hr ;
TRACE ( " (%p)->(%p, %p) \n " , This , stream , desc ) ;
/* FIXME: should this be determined from stream? */
desc - > dwValidData | = DMUS_OBJ_CLASS ;
desc - > guidClass = CLSID_DirectMusicCollection ;
hr = read_from_stream ( stream , & chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) ) ;
if ( FAILED ( hr ) )
return hr ;
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( chunk . fccID ) , chunk . dwSize ) ;
if ( chunk . fccID ! = FOURCC_RIFF ) {
TRACE_ ( dmfile ) ( " : unexpected chunk; loading failed) \n " ) ;
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ; /* skip the rest of the chunk */
return DMUS_E_INVALIDFILE ;
}
hr = read_from_stream ( stream , & chunk . fccID , sizeof ( FOURCC ) ) ;
if ( FAILED ( hr ) )
return hr ;
TRACE_ ( dmfile ) ( " : RIFF chunk of type %s " , debugstr_fourcc ( chunk . fccID ) ) ;
StreamSize = chunk . dwSize - sizeof ( FOURCC ) ;
if ( chunk . fccID ! = mmioFOURCC ( ' D ' , ' L ' , ' S ' , ' ' ) ) {
TRACE_ ( dmfile ) ( " : unexpected chunk; loading failed) \n " ) ;
liMove . QuadPart = StreamSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ; /* skip the rest of the chunk */
return E_FAIL ;
}
StreamCount = 0 ;
TRACE_ ( dmfile ) ( " : collection form \n " ) ;
do {
hr = read_from_stream ( stream , & chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) ) ;
if ( FAILED ( hr ) )
return hr ;
StreamCount + = sizeof ( FOURCC ) + sizeof ( DWORD ) + chunk . dwSize ;
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( chunk . fccID ) , chunk . dwSize ) ;
switch ( chunk . fccID ) {
case FOURCC_DLID :
TRACE_ ( dmfile ) ( " : GUID chunk \n " ) ;
desc - > dwValidData | = DMUS_OBJ_OBJECT ;
hr = read_from_stream ( stream , & desc - > guidObject , chunk . dwSize ) ;
if ( FAILED ( hr ) )
return hr ;
break ;
case DMUS_FOURCC_VERSION_CHUNK :
TRACE_ ( dmfile ) ( " : version chunk \n " ) ;
desc - > dwValidData | = DMUS_OBJ_VERSION ;
hr = read_from_stream ( stream , & desc - > vVersion , chunk . dwSize ) ;
if ( FAILED ( hr ) )
return hr ;
break ;
case DMUS_FOURCC_CATEGORY_CHUNK :
TRACE_ ( dmfile ) ( " : category chunk \n " ) ;
desc - > dwValidData | = DMUS_OBJ_CATEGORY ;
hr = read_from_stream ( stream , desc - > wszCategory , chunk . dwSize ) ;
if ( FAILED ( hr ) )
return hr ;
break ;
case FOURCC_LIST :
hr = read_from_stream ( stream , & chunk . fccID , sizeof ( FOURCC ) ) ;
if ( FAILED ( hr ) )
return hr ;
TRACE_ ( dmfile ) ( " : LIST chunk of type %s " , debugstr_fourcc ( chunk . fccID ) ) ;
ListSize [ 0 ] = chunk . dwSize - sizeof ( FOURCC ) ;
ListCount [ 0 ] = 0 ;
switch ( chunk . fccID ) {
/* pure INFO list, such can be found in dls collections */
case mmioFOURCC ( ' I ' , ' N ' , ' F ' , ' O ' ) :
TRACE_ ( dmfile ) ( " : INFO list \n " ) ;
do {
hr = read_from_stream ( stream , & chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) ) ;
if ( FAILED ( hr ) )
return hr ;
ListCount [ 0 ] + = sizeof ( FOURCC ) + sizeof ( DWORD ) + chunk . dwSize ;
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( chunk . fccID ) , chunk . dwSize ) ;
switch ( chunk . fccID ) {
case mmioFOURCC ( ' I ' , ' N ' , ' A ' , ' M ' ) : {
CHAR szName [ DMUS_MAX_NAME ] ;
TRACE_ ( dmfile ) ( " : name chunk \n " ) ;
desc - > dwValidData | = DMUS_OBJ_NAME ;
hr = read_from_stream ( stream , szName , chunk . dwSize ) ;
if ( FAILED ( hr ) )
return hr ;
MultiByteToWideChar ( CP_ACP , 0 , szName , - 1 , desc - > wszName , DMUS_MAX_NAME ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
liMove . QuadPart = 1 ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
}
break ;
}
case mmioFOURCC ( ' I ' , ' A ' , ' R ' , ' T ' ) :
TRACE_ ( dmfile ) ( " : artist chunk (ignored) \n " ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
chunk . dwSize + + ;
}
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
case mmioFOURCC ( ' I ' , ' C ' , ' O ' , ' P ' ) :
TRACE_ ( dmfile ) ( " : copyright chunk (ignored) \n " ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
chunk . dwSize + + ;
}
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
case mmioFOURCC ( ' I ' , ' S ' , ' B ' , ' J ' ) :
TRACE_ ( dmfile ) ( " : subject chunk (ignored) \n " ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
chunk . dwSize + + ;
}
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
case mmioFOURCC ( ' I ' , ' C ' , ' M ' , ' T ' ) :
TRACE_ ( dmfile ) ( " : comment chunk (ignored) \n " ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
chunk . dwSize + + ;
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
default :
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
if ( even_or_odd ( chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
chunk . dwSize + + ;
}
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
TRACE_ ( dmfile ) ( " : ListCount[0] = %d < ListSize[0] = %d \n " , ListCount [ 0 ] , ListSize [ 0 ] ) ;
} while ( ListCount [ 0 ] < ListSize [ 0 ] ) ;
break ;
default :
TRACE_ ( dmfile ) ( " : unknown (skipping) \n " ) ;
liMove . QuadPart = chunk . dwSize - sizeof ( FOURCC ) ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
break ;
default :
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
liMove . QuadPart = chunk . dwSize ;
IStream_Seek ( stream , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
TRACE_ ( dmfile ) ( " : StreamCount[0] = %d < StreamSize[0] = %d \n " , StreamCount , StreamSize ) ;
} while ( StreamCount < StreamSize ) ;
TRACE_ ( dmfile ) ( " : reading finished \n " ) ;
if ( TRACE_ON ( dmusic ) ) {
TRACE ( " Returning descriptor: \n " ) ;
dump_DMUS_OBJECTDESC ( desc ) ;
}
return S_OK ;
2003-08-23 01:53:27 +02:00
}
2005-06-01 21:57:42 +02:00
static const IDirectMusicObjectVtbl DirectMusicCollection_Object_Vtbl = {
2004-01-20 01:21:40 +01:00
IDirectMusicCollectionImpl_IDirectMusicObject_QueryInterface ,
IDirectMusicCollectionImpl_IDirectMusicObject_AddRef ,
IDirectMusicCollectionImpl_IDirectMusicObject_Release ,
IDirectMusicCollectionImpl_IDirectMusicObject_GetDescriptor ,
IDirectMusicCollectionImpl_IDirectMusicObject_SetDescriptor ,
IDirectMusicCollectionImpl_IDirectMusicObject_ParseDescriptor
} ;
2003-08-23 01:53:27 +02:00
2004-01-20 01:21:40 +01:00
/* IDirectMusicCollectionImpl IPersistStream part: */
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_QueryInterface ( LPPERSISTSTREAM iface , REFIID riid , LPVOID * ret_iface )
{
IDirectMusicCollectionImpl * This = impl_from_IPersistStream ( iface ) ;
return IDirectMusicCollection_QueryInterface ( & This - > IDirectMusicCollection_iface , riid , ret_iface ) ;
2003-07-22 00:10:14 +02:00
}
2003-08-23 01:53:27 +02:00
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IPersistStream_AddRef ( LPPERSISTSTREAM iface )
{
IDirectMusicCollectionImpl * This = impl_from_IPersistStream ( iface ) ;
return IDirectMusicCollection_AddRef ( & This - > IDirectMusicCollection_iface ) ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static ULONG WINAPI IDirectMusicCollectionImpl_IPersistStream_Release ( LPPERSISTSTREAM iface )
{
IDirectMusicCollectionImpl * This = impl_from_IPersistStream ( iface ) ;
return IDirectMusicCollection_Release ( & This - > IDirectMusicCollection_iface ) ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_GetClassID ( LPPERSISTSTREAM iface , CLSID * pClassID )
{
return E_NOTIMPL ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_IsDirty ( LPPERSISTSTREAM iface )
{
return E_NOTIMPL ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Load ( LPPERSISTSTREAM iface , IStream * pStm )
{
IDirectMusicCollectionImpl * This = impl_from_IPersistStream ( iface ) ;
2004-01-20 01:21:40 +01:00
DMUS_PRIVATE_CHUNK Chunk ;
DWORD StreamSize , StreamCount , ListSize [ 3 ] , ListCount [ 3 ] ;
LARGE_INTEGER liMove ; /* used when skipping chunks */
ULARGE_INTEGER dlibCollectionPosition , dlibInstrumentPosition , dlibWavePoolPosition ;
2003-08-23 01:53:27 +02:00
2004-01-20 01:21:40 +01:00
IStream_AddRef ( pStm ) ; /* add count for later references */
liMove . QuadPart = 0 ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , & dlibCollectionPosition ) ; /* store offset, in case it'll be needed later */
This - > liCollectionPosition . QuadPart = dlibCollectionPosition . QuadPart ;
This - > pStm = pStm ;
IStream_Read ( pStm , & Chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) , NULL ) ;
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( Chunk . fccID ) , Chunk . dwSize ) ;
2004-01-20 01:21:40 +01:00
switch ( Chunk . fccID ) {
case FOURCC_RIFF : {
IStream_Read ( pStm , & Chunk . fccID , sizeof ( FOURCC ) , NULL ) ;
TRACE_ ( dmfile ) ( " : RIFF chunk of type %s " , debugstr_fourcc ( Chunk . fccID ) ) ;
StreamSize = Chunk . dwSize - sizeof ( FOURCC ) ;
StreamCount = 0 ;
switch ( Chunk . fccID ) {
case FOURCC_DLS : {
TRACE_ ( dmfile ) ( " : collection form \n " ) ;
do {
IStream_Read ( pStm , & Chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) , NULL ) ;
StreamCount + = sizeof ( FOURCC ) + sizeof ( DWORD ) + Chunk . dwSize ;
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( Chunk . fccID ) , Chunk . dwSize ) ;
2004-01-20 01:21:40 +01:00
switch ( Chunk . fccID ) {
case FOURCC_COLH : {
TRACE_ ( dmfile ) ( " : collection header chunk \n " ) ;
This - > pHeader = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , Chunk . dwSize ) ;
IStream_Read ( pStm , This - > pHeader , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_DLID : {
TRACE_ ( dmfile ) ( " : DLID (GUID) chunk \n " ) ;
This - > pDesc - > dwValidData | = DMUS_OBJ_OBJECT ;
IStream_Read ( pStm , & This - > pDesc - > guidObject , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_VERS : {
TRACE_ ( dmfile ) ( " : version chunk \n " ) ;
This - > pDesc - > dwValidData | = DMUS_OBJ_VERSION ;
IStream_Read ( pStm , & This - > pDesc - > vVersion , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_PTBL : {
TRACE_ ( dmfile ) ( " : pool table chunk \n " ) ;
This - > pPoolTable = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( POOLTABLE ) ) ;
IStream_Read ( pStm , This - > pPoolTable , sizeof ( POOLTABLE ) , NULL ) ;
Chunk . dwSize - = sizeof ( POOLTABLE ) ;
This - > pPoolCues = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , This - > pPoolTable - > cCues * sizeof ( POOLCUE ) ) ;
IStream_Read ( pStm , This - > pPoolCues , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_LIST : {
IStream_Read ( pStm , & Chunk . fccID , sizeof ( FOURCC ) , NULL ) ;
TRACE_ ( dmfile ) ( " : LIST chunk of type %s " , debugstr_fourcc ( Chunk . fccID ) ) ;
ListSize [ 0 ] = Chunk . dwSize - sizeof ( FOURCC ) ;
ListCount [ 0 ] = 0 ;
switch ( Chunk . fccID ) {
case mmioFOURCC ( ' I ' , ' N ' , ' F ' , ' O ' ) : {
TRACE_ ( dmfile ) ( " : INFO list \n " ) ;
do {
IStream_Read ( pStm , & Chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) , NULL ) ;
ListCount [ 0 ] + = sizeof ( FOURCC ) + sizeof ( DWORD ) + Chunk . dwSize ;
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( Chunk . fccID ) , Chunk . dwSize ) ;
2004-01-20 01:21:40 +01:00
switch ( Chunk . fccID ) {
case mmioFOURCC ( ' I ' , ' N ' , ' A ' , ' M ' ) : {
CHAR szName [ DMUS_MAX_NAME ] ;
TRACE_ ( dmfile ) ( " : name chunk \n " ) ;
This - > pDesc - > dwValidData | = DMUS_OBJ_NAME ;
IStream_Read ( pStm , szName , Chunk . dwSize , NULL ) ;
MultiByteToWideChar ( CP_ACP , 0 , szName , - 1 , This - > pDesc - > wszName , DMUS_MAX_NAME ) ;
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
liMove . QuadPart = 1 ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
}
break ;
}
case mmioFOURCC ( ' I ' , ' A ' , ' R ' , ' T ' ) : {
TRACE_ ( dmfile ) ( " : artist chunk (ignored) \n " ) ;
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
Chunk . dwSize + + ;
}
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
case mmioFOURCC ( ' I ' , ' C ' , ' O ' , ' P ' ) : {
TRACE_ ( dmfile ) ( " : copyright chunk \n " ) ;
This - > szCopyright = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , Chunk . dwSize ) ;
IStream_Read ( pStm , This - > szCopyright , Chunk . dwSize , NULL ) ;
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
liMove . QuadPart = 1 ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
}
break ;
}
case mmioFOURCC ( ' I ' , ' S ' , ' B ' , ' J ' ) : {
TRACE_ ( dmfile ) ( " : subject chunk (ignored) \n " ) ;
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
Chunk . dwSize + + ;
}
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
case mmioFOURCC ( ' I ' , ' C ' , ' M ' , ' T ' ) : {
TRACE_ ( dmfile ) ( " : comment chunk (ignored) \n " ) ;
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
Chunk . dwSize + + ;
}
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
default : {
2011-07-27 13:38:43 +02:00
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
2004-01-20 01:21:40 +01:00
if ( even_or_odd ( Chunk . dwSize ) ) {
ListCount [ 0 ] + + ;
Chunk . dwSize + + ;
}
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : ListCount[0] = %d < ListSize[0] = %d \n " , ListCount [ 0 ] , ListSize [ 0 ] ) ;
2004-01-20 01:21:40 +01:00
} while ( ListCount [ 0 ] < ListSize [ 0 ] ) ;
break ;
}
case FOURCC_WVPL : {
TRACE_ ( dmfile ) ( " : wave pool list (mark & skip) \n " ) ;
liMove . QuadPart = 0 ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , & dlibWavePoolPosition ) ; /* store position */
This - > liWavePoolTablePosition . QuadPart = dlibWavePoolPosition . QuadPart ;
liMove . QuadPart = Chunk . dwSize - sizeof ( FOURCC ) ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
case FOURCC_LINS : {
TRACE_ ( dmfile ) ( " : instruments list \n " ) ;
do {
IStream_Read ( pStm , & Chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) , NULL ) ;
ListCount [ 0 ] + = sizeof ( FOURCC ) + sizeof ( DWORD ) + Chunk . dwSize ;
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( Chunk . fccID ) , Chunk . dwSize ) ;
2004-01-20 01:21:40 +01:00
switch ( Chunk . fccID ) {
case FOURCC_LIST : {
IStream_Read ( pStm , & Chunk . fccID , sizeof ( FOURCC ) , NULL ) ;
TRACE_ ( dmfile ) ( " : LIST chunk of type %s " , debugstr_fourcc ( Chunk . fccID ) ) ;
ListSize [ 1 ] = Chunk . dwSize - sizeof ( FOURCC ) ;
ListCount [ 1 ] = 0 ;
switch ( Chunk . fccID ) {
case FOURCC_INS : {
LPDMUS_PRIVATE_INSTRUMENTENTRY pNewInstrument = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( DMUS_PRIVATE_INSTRUMENTENTRY ) ) ;
TRACE_ ( dmfile ) ( " : instrument list \n " ) ;
2008-04-02 22:10:47 +02:00
DMUSIC_CreateDirectMusicInstrumentImpl ( & IID_IDirectMusicInstrument , ( LPVOID * ) & pNewInstrument - > pInstrument , NULL ) ; /* only way to create this one... even M$ does it discretely */
2004-01-20 01:21:40 +01:00
{
2012-05-04 20:51:30 +02:00
IDirectMusicInstrumentImpl * pInstrument = impl_from_IDirectMusicInstrument ( pNewInstrument - > pInstrument ) ;
2004-01-20 01:21:40 +01:00
liMove . QuadPart = 0 ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , & dlibInstrumentPosition ) ;
pInstrument - > liInstrumentPosition . QuadPart = dlibInstrumentPosition . QuadPart - ( 2 * sizeof ( FOURCC ) + sizeof ( DWORD ) ) ; /* store offset, it'll be needed later */
do {
IStream_Read ( pStm , & Chunk , sizeof ( FOURCC ) + sizeof ( DWORD ) , NULL ) ;
ListCount [ 1 ] + = sizeof ( FOURCC ) + sizeof ( DWORD ) + Chunk . dwSize ;
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : %s chunk (size = 0x%04x) " , debugstr_fourcc ( Chunk . fccID ) , Chunk . dwSize ) ;
2004-01-20 01:21:40 +01:00
switch ( Chunk . fccID ) {
case FOURCC_INSH : {
TRACE_ ( dmfile ) ( " : instrument header chunk \n " ) ;
pInstrument - > pHeader = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , Chunk . dwSize ) ;
IStream_Read ( pStm , pInstrument - > pHeader , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_DLID : {
TRACE_ ( dmfile ) ( " : DLID (GUID) chunk \n " ) ;
pInstrument - > pInstrumentID = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , Chunk . dwSize ) ;
IStream_Read ( pStm , pInstrument - > pInstrumentID , Chunk . dwSize , NULL ) ;
break ;
}
case FOURCC_LIST : {
IStream_Read ( pStm , & Chunk . fccID , sizeof ( FOURCC ) , NULL ) ;
TRACE_ ( dmfile ) ( " : LIST chunk of type %s " , debugstr_fourcc ( Chunk . fccID ) ) ;
ListSize [ 2 ] = Chunk . dwSize - sizeof ( FOURCC ) ;
ListCount [ 2 ] = 0 ;
switch ( Chunk . fccID ) {
default : {
TRACE_ ( dmfile ) ( " : unknown (skipping) \n " ) ;
liMove . QuadPart = Chunk . dwSize - sizeof ( FOURCC ) ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
break ;
}
default : {
2011-07-27 13:38:43 +02:00
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
2004-01-20 01:21:40 +01:00
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : ListCount[1] = %d < ListSize[1] = %d \n " , ListCount [ 1 ] , ListSize [ 1 ] ) ;
2004-01-20 01:21:40 +01:00
} while ( ListCount [ 1 ] < ListSize [ 1 ] ) ;
/* DEBUG: dumps whole instrument object tree: */
if ( TRACE_ON ( dmusic ) ) {
TRACE ( " *** IDirectMusicInstrument (%p) *** \n " , pInstrument ) ;
if ( pInstrument - > pInstrumentID )
2004-02-25 02:30:03 +01:00
TRACE ( " - GUID = %s \n " , debugstr_dmguid ( pInstrument - > pInstrumentID ) ) ;
2004-01-20 01:21:40 +01:00
TRACE ( " - Instrument header: \n " ) ;
2006-10-12 21:34:50 +02:00
TRACE ( " - cRegions: %d \n " , pInstrument - > pHeader - > cRegions ) ;
2004-01-20 01:21:40 +01:00
TRACE ( " - Locale: \n " ) ;
2006-10-12 21:34:50 +02:00
TRACE ( " - ulBank: %d \n " , pInstrument - > pHeader - > Locale . ulBank ) ;
TRACE ( " - ulInstrument: %d \n " , pInstrument - > pHeader - > Locale . ulInstrument ) ;
TRACE ( " => dwPatch: %d \n " , MIDILOCALE2Patch ( & pInstrument - > pHeader - > Locale ) ) ;
2004-01-20 01:21:40 +01:00
}
list_add_tail ( & This - > Instruments , & pNewInstrument - > entry ) ;
}
break ;
}
}
break ;
}
default : {
2011-07-27 13:38:43 +02:00
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
2004-01-20 01:21:40 +01:00
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : ListCount[0] = %d < ListSize[0] = %d \n " , ListCount [ 0 ] , ListSize [ 0 ] ) ;
2004-01-20 01:21:40 +01:00
} while ( ListCount [ 0 ] < ListSize [ 0 ] ) ;
break ;
}
default : {
TRACE_ ( dmfile ) ( " : unknown (skipping) \n " ) ;
liMove . QuadPart = Chunk . dwSize - sizeof ( FOURCC ) ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
break ;
}
default : {
2011-07-27 13:38:43 +02:00
TRACE_ ( dmfile ) ( " : unknown chunk (irrelevant & skipping) \n " ) ;
2004-01-20 01:21:40 +01:00
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ;
break ;
}
}
2006-10-12 21:34:50 +02:00
TRACE_ ( dmfile ) ( " : StreamCount = %d < StreamSize = %d \n " , StreamCount , StreamSize ) ;
2004-01-20 01:21:40 +01:00
} while ( StreamCount < StreamSize ) ;
break ;
}
default : {
TRACE_ ( dmfile ) ( " : unexpected chunk; loading failed) \n " ) ;
liMove . QuadPart = StreamSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ; /* skip the rest of the chunk */
return E_FAIL ;
}
}
TRACE_ ( dmfile ) ( " : reading finished \n " ) ;
break ;
}
default : {
TRACE_ ( dmfile ) ( " : unexpected chunk; loading failed) \n " ) ;
liMove . QuadPart = Chunk . dwSize ;
IStream_Seek ( pStm , liMove , STREAM_SEEK_CUR , NULL ) ; /* skip the rest of the chunk */
return E_FAIL ;
}
}
/* DEBUG: dumps whole collection object tree: */
if ( TRACE_ON ( dmusic ) ) {
int r = 0 ;
DMUS_PRIVATE_INSTRUMENTENTRY * tmpEntry ;
struct list * listEntry ;
2012-05-14 08:06:30 +02:00
TRACE ( " *** IDirectMusicCollection (%p) *** \n " , & This - > IDirectMusicCollection_iface ) ;
2004-01-20 01:21:40 +01:00
if ( This - > pDesc - > dwValidData & DMUS_OBJ_OBJECT )
2004-02-25 02:30:03 +01:00
TRACE ( " - GUID = %s \n " , debugstr_dmguid ( & This - > pDesc - > guidObject ) ) ;
2004-01-20 01:21:40 +01:00
if ( This - > pDesc - > dwValidData & DMUS_OBJ_VERSION )
2007-01-09 00:39:49 +01:00
TRACE ( " - Version = %i,%i,%i,%i \n " , ( This - > pDesc - > vVersion . dwVersionMS > > 8 ) & 0x0000FFFF , This - > pDesc - > vVersion . dwVersionMS & 0x0000FFFF ,
2006-11-09 15:40:55 +01:00
( This - > pDesc - > vVersion . dwVersionLS > > 8 ) & 0x0000FFFF , This - > pDesc - > vVersion . dwVersionLS & 0x0000FFFF ) ;
2004-01-20 01:21:40 +01:00
if ( This - > pDesc - > dwValidData & DMUS_OBJ_NAME )
TRACE ( " - Name = %s \n " , debugstr_w ( This - > pDesc - > wszName ) ) ;
TRACE ( " - Collection header: \n " ) ;
2006-10-12 21:34:50 +02:00
TRACE ( " - cInstruments: %d \n " , This - > pHeader - > cInstruments ) ;
2004-01-20 01:21:40 +01:00
TRACE ( " - Instruments: \n " ) ;
LIST_FOR_EACH ( listEntry , & This - > Instruments ) {
tmpEntry = LIST_ENTRY ( listEntry , DMUS_PRIVATE_INSTRUMENTENTRY , entry ) ;
TRACE ( " - Instrument[%i]: %p \n " , r , tmpEntry - > pInstrument ) ;
r + + ;
}
2003-08-23 01:53:27 +02:00
}
return S_OK ;
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_Save ( LPPERSISTSTREAM iface , IStream * pStm , BOOL fClearDirty )
{
return E_NOTIMPL ;
2003-08-23 01:53:27 +02:00
}
2012-05-14 08:06:30 +02:00
static HRESULT WINAPI IDirectMusicCollectionImpl_IPersistStream_GetSizeMax ( LPPERSISTSTREAM iface , ULARGE_INTEGER * pcbSize )
{
return E_NOTIMPL ;
2003-08-23 01:53:27 +02:00
}
2005-06-01 21:57:42 +02:00
static const IPersistStreamVtbl DirectMusicCollection_PersistStream_Vtbl = {
2004-01-20 01:21:40 +01:00
IDirectMusicCollectionImpl_IPersistStream_QueryInterface ,
IDirectMusicCollectionImpl_IPersistStream_AddRef ,
IDirectMusicCollectionImpl_IPersistStream_Release ,
IDirectMusicCollectionImpl_IPersistStream_GetClassID ,
IDirectMusicCollectionImpl_IPersistStream_IsDirty ,
IDirectMusicCollectionImpl_IPersistStream_Load ,
IDirectMusicCollectionImpl_IPersistStream_Save ,
IDirectMusicCollectionImpl_IPersistStream_GetSizeMax
2003-08-23 01:53:27 +02:00
} ;
2004-01-20 01:21:40 +01:00
/* for ClassFactory */
2012-05-14 08:06:30 +02:00
HRESULT WINAPI DMUSIC_CreateDirectMusicCollectionImpl ( LPCGUID lpcGUID , LPVOID * ppobj , LPUNKNOWN pUnkOuter )
{
2004-01-20 01:21:40 +01:00
IDirectMusicCollectionImpl * obj ;
obj = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( IDirectMusicCollectionImpl ) ) ;
if ( NULL = = obj ) {
2004-12-22 16:13:20 +01:00
* ppobj = NULL ;
2004-01-20 01:21:40 +01:00
return E_OUTOFMEMORY ;
}
2012-05-14 08:06:30 +02:00
obj - > IDirectMusicCollection_iface . lpVtbl = & DirectMusicCollection_Collection_Vtbl ;
obj - > IDirectMusicObject_iface . lpVtbl = & DirectMusicCollection_Object_Vtbl ;
obj - > IPersistStream_iface . lpVtbl = & DirectMusicCollection_PersistStream_Vtbl ;
2004-01-20 01:21:40 +01:00
obj - > pDesc = HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( DMUS_OBJECTDESC ) ) ;
DM_STRUCT_INIT ( obj - > pDesc ) ;
obj - > pDesc - > dwValidData | = DMUS_OBJ_CLASS ;
2008-02-25 20:48:31 +01:00
obj - > pDesc - > guidClass = CLSID_DirectMusicCollection ;
2004-01-20 01:21:40 +01:00
obj - > ref = 0 ; /* will be inited by QueryInterface */
list_init ( & obj - > Instruments ) ;
2008-02-25 20:48:31 +01:00
2012-05-14 08:06:30 +02:00
return IDirectMusicCollection_QueryInterface ( & obj - > IDirectMusicCollection_iface , lpcGUID , ppobj ) ;
2004-01-20 01:21:40 +01:00
}