From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/collection.c | 21 +++++++++++++++++++-- dlls/dmusic/dmusic_private.h | 6 +++++- dlls/dmusic/instrument.c | 11 +++++++---- 3 files changed, 31 insertions(+), 7 deletions(-)
diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c index 1c36f0b202d..cfe7589485d 100644 --- a/dlls/dmusic/collection.c +++ b/dlls/dmusic/collection.c @@ -48,6 +48,7 @@ struct collection { IDirectMusicCollection IDirectMusicCollection_iface; struct dmobject dmobj; + LONG internal_ref; LONG ref;
DLSHEADER header; @@ -56,6 +57,21 @@ struct collection struct list waves; };
+extern void collection_internal_addref(struct collection *collection) +{ + ULONG ref = InterlockedIncrement( &collection->internal_ref ); + TRACE( "collection %p, internal ref %lu.\n", collection, ref ); +} + +extern void collection_internal_release(struct collection *collection) +{ + ULONG ref = InterlockedDecrement( &collection->internal_ref ); + TRACE( "collection %p, internal ref %lu.\n", collection, ref ); + + if (!ref) + free(collection); +} + static inline struct collection *impl_from_IDirectMusicCollection(IDirectMusicCollection *iface) { return CONTAINING_RECORD(iface, struct collection, IDirectMusicCollection_iface); @@ -128,7 +144,7 @@ static ULONG WINAPI collection_Release(IDirectMusicCollection *iface) free(wave_entry); }
- free(This); + collection_internal_release(This); }
return ref; @@ -201,7 +217,7 @@ static HRESULT parse_lins_list(struct collection *This, IStream *stream, struct { case MAKE_IDTYPE(FOURCC_LIST, FOURCC_INS): if (!(entry = malloc(sizeof(*entry)))) return E_OUTOFMEMORY; - hr = instrument_create_from_chunk(stream, &chunk, &entry->desc, &entry->instrument); + hr = instrument_create_from_chunk(stream, &chunk, This, &entry->desc, &entry->instrument); if (SUCCEEDED(hr)) list_add_tail(&This->instruments, &entry->entry); else free(entry); break; @@ -435,6 +451,7 @@ HRESULT collection_create(IUnknown **ret_iface) *ret_iface = NULL; if (!(collection = calloc(1, sizeof(*collection)))) return E_OUTOFMEMORY; collection->IDirectMusicCollection_iface.lpVtbl = &collection_vtbl; + collection->internal_ref = 1; collection->ref = 1; dmobject_init(&collection->dmobj, &CLSID_DirectMusicCollection, (IUnknown *)&collection->IDirectMusicCollection_iface); diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 2fe6afde643..1f6b33ec34d 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -76,6 +76,10 @@ typedef struct port_info { * ClassFactory */
+struct collection; +extern void collection_internal_addref(struct collection *collection); +extern void collection_internal_release(struct collection *collection); + /* CLSID */ extern HRESULT music_create(IUnknown **ret_iface); extern HRESULT collection_create(IUnknown **ret_iface); @@ -87,7 +91,7 @@ extern HRESULT DMUSIC_CreateReferenceClockImpl (LPCGUID lpcGUID, LPVOID* ppobj, extern HRESULT download_create(DWORD size, IDirectMusicDownload **ret_iface);
extern HRESULT instrument_create_from_chunk(IStream *stream, struct chunk_entry *parent, - DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface); + struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface); extern HRESULT instrument_download_to_port(IDirectMusicInstrument *iface, IDirectMusicPortDownload *port, IDirectMusicDownloadedInstrument **downloaded); extern HRESULT instrument_unload_from_port(IDirectMusicDownloadedInstrument *iface, IDirectMusicPortDownload *port); diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 24b3c0305f8..b79e7671c5b 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -51,6 +51,7 @@ struct instrument
INSTHEADER header; IDirectMusicDownload *download; + struct collection *collection; struct list articulations; struct list regions; }; @@ -124,6 +125,7 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface) free(region); }
+ collection_internal_release(This->collection); free(This); }
@@ -201,7 +203,7 @@ static const IDirectMusicDownloadedInstrumentVtbl downloaded_instrument_vtbl = downloaded_instrument_Release, };
-static HRESULT instrument_create(IDirectMusicInstrument **ret_iface) +static HRESULT instrument_create(struct collection *collection, IDirectMusicInstrument **ret_iface) { struct instrument *instrument;
@@ -210,6 +212,7 @@ static HRESULT instrument_create(IDirectMusicInstrument **ret_iface) instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl; instrument->IDirectMusicDownloadedInstrument_iface.lpVtbl = &downloaded_instrument_vtbl; instrument->ref = 1; + collection_internal_addref((instrument->collection = collection)); list_init(&instrument->articulations); list_init(&instrument->regions);
@@ -377,15 +380,15 @@ static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct }
HRESULT instrument_create_from_chunk(IStream *stream, struct chunk_entry *parent, - DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface) + struct collection *collection, DMUS_OBJECTDESC *desc, IDirectMusicInstrument **ret_iface) { IDirectMusicInstrument *iface; struct instrument *This; HRESULT hr;
- TRACE("(%p, %p)\n", stream, ret_iface); + TRACE("(%p, %p, %p, %p, %p)\n", stream, parent, collection, desc, ret_iface);
- if (FAILED(hr = instrument_create(&iface))) return hr; + if (FAILED(hr = instrument_create(collection, &iface))) return hr; This = impl_from_IDirectMusicInstrument(iface);
if (FAILED(hr = parse_ins_chunk(This, stream, parent, desc)))