Commit c0b52aa3 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmime: Avoid leaking tracks in IDirectMusicSegment_Release.

parent 6699becf
...@@ -73,13 +73,6 @@ extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSo ...@@ -73,13 +73,6 @@ extern void set_audiopath_primary_dsound_buffer(IDirectMusicAudioPath*,IDirectSo
/***************************************************************************** /*****************************************************************************
* Auxiliary definitions * Auxiliary definitions
*/ */
typedef struct _DMUS_PRIVATE_SEGMENT_TRACK {
struct list entry; /* for listing elements */
DWORD dwGroupBits;
DWORD flags;
IDirectMusicTrack* pTrack;
} DMUS_PRIVATE_SEGMENT_TRACK, *LPDMUS_PRIVATE_SEGMENT_TRACK;
typedef struct _DMUS_PRIVATE_TEMPO_ITEM { typedef struct _DMUS_PRIVATE_TEMPO_ITEM {
struct list entry; /* for listing elements */ struct list entry; /* for listing elements */
DMUS_IO_TEMPO_ITEM item; DMUS_IO_TEMPO_ITEM item;
......
...@@ -23,6 +23,25 @@ ...@@ -23,6 +23,25 @@
WINE_DEFAULT_DEBUG_CHANNEL(dmime); WINE_DEFAULT_DEBUG_CHANNEL(dmime);
struct track_entry
{
struct list entry;
DWORD dwGroupBits;
DWORD flags;
IDirectMusicTrack *pTrack;
};
static void track_entry_destroy(struct track_entry *entry)
{
HRESULT hr;
if (FAILED(hr = IDirectMusicTrack_Init(entry->pTrack, NULL)))
WARN("Failed to de-init track %p, hr %#lx\n", entry->pTrack, hr);
IDirectMusicTrack_Release(entry->pTrack);
free(entry);
}
struct segment struct segment
{ {
IDirectMusicSegment8 IDirectMusicSegment8_iface; IDirectMusicSegment8 IDirectMusicSegment8_iface;
...@@ -30,7 +49,7 @@ struct segment ...@@ -30,7 +49,7 @@ struct segment
LONG ref; LONG ref;
DMUS_IO_SEGMENT_HEADER header; DMUS_IO_SEGMENT_HEADER header;
IDirectMusicGraph *pGraph; IDirectMusicGraph *pGraph;
struct list Tracks; struct list tracks;
PCMWAVEFORMAT wave_format; PCMWAVEFORMAT wave_format;
void *wave_data; void *wave_data;
...@@ -87,6 +106,14 @@ static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface) ...@@ -87,6 +106,14 @@ static ULONG WINAPI segment_Release(IDirectMusicSegment8 *iface)
TRACE("(%p) ref=%ld\n", This, ref); TRACE("(%p) ref=%ld\n", This, ref);
if (!ref) { if (!ref) {
struct track_entry *entry, *next;
LIST_FOR_EACH_ENTRY_SAFE(entry, next, &This->tracks, struct track_entry, entry)
{
list_remove(&entry->entry);
track_entry_destroy(entry);
}
if (This->wave_data) if (This->wave_data)
free(This->wave_data); free(This->wave_data);
...@@ -169,7 +196,7 @@ static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID rgui ...@@ -169,7 +196,7 @@ static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID rgui
struct segment *This = impl_from_IDirectMusicSegment8(iface); struct segment *This = impl_from_IDirectMusicSegment8(iface);
CLSID pIt_clsid; CLSID pIt_clsid;
struct list* pEntry = NULL; struct list* pEntry = NULL;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL; struct track_entry *pIt = NULL;
IPersistStream* pCLSIDStream = NULL; IPersistStream* pCLSIDStream = NULL;
HRESULT hr = S_OK; HRESULT hr = S_OK;
...@@ -179,8 +206,8 @@ static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID rgui ...@@ -179,8 +206,8 @@ static HRESULT WINAPI segment_GetTrack(IDirectMusicSegment8 *iface, REFGUID rgui
return E_POINTER; return E_POINTER;
} }
LIST_FOR_EACH (pEntry, &This->Tracks) { LIST_FOR_EACH (pEntry, &This->tracks) {
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry); pIt = LIST_ENTRY(pEntry, struct track_entry, entry);
TRACE(" - %p -> %#lx,%p\n", pIt, pIt->dwGroupBits, pIt->pTrack); TRACE(" - %p -> %#lx,%p\n", pIt, pIt->dwGroupBits, pIt->pTrack);
if (0xFFFFFFFF != dwGroupBits && 0 == (pIt->dwGroupBits & dwGroupBits)) continue ; if (0xFFFFFFFF != dwGroupBits && 0 == (pIt->dwGroupBits & dwGroupBits)) continue ;
if (FALSE == IsEqualGUID(&GUID_NULL, rguidType)) { if (FALSE == IsEqualGUID(&GUID_NULL, rguidType)) {
...@@ -216,7 +243,7 @@ static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirect ...@@ -216,7 +243,7 @@ static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirect
{ {
struct segment *This = impl_from_IDirectMusicSegment8(iface); struct segment *This = impl_from_IDirectMusicSegment8(iface);
struct list* pEntry = NULL; struct list* pEntry = NULL;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL; struct track_entry *pIt = NULL;
TRACE("(%p, %p, %p)\n", This, pTrack, pdwGroupBits); TRACE("(%p, %p, %p)\n", This, pTrack, pdwGroupBits);
...@@ -224,8 +251,8 @@ static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirect ...@@ -224,8 +251,8 @@ static HRESULT WINAPI segment_GetTrackGroup(IDirectMusicSegment8 *iface, IDirect
return E_POINTER; return E_POINTER;
} }
LIST_FOR_EACH (pEntry, &This->Tracks) { LIST_FOR_EACH (pEntry, &This->tracks) {
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry); pIt = LIST_ENTRY(pEntry, struct track_entry, entry);
TRACE(" - %p -> %#lx, %p\n", pIt, pIt->dwGroupBits, pIt->pTrack); TRACE(" - %p -> %#lx, %p\n", pIt, pIt->dwGroupBits, pIt->pTrack);
if (NULL != pIt && pIt->pTrack == pTrack) { if (NULL != pIt && pIt->pTrack == pTrack) {
*pdwGroupBits = pIt->dwGroupBits; *pdwGroupBits = pIt->dwGroupBits;
...@@ -241,17 +268,17 @@ static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMu ...@@ -241,17 +268,17 @@ static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMu
struct segment *This = impl_from_IDirectMusicSegment8(iface); struct segment *This = impl_from_IDirectMusicSegment8(iface);
DWORD i = 0; DWORD i = 0;
struct list* pEntry = NULL; struct list* pEntry = NULL;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL; struct track_entry *pIt = NULL;
LPDMUS_PRIVATE_SEGMENT_TRACK pNewSegTrack = NULL; struct track_entry *pNewSegTrack = NULL;
TRACE("(%p, %p, %#lx)\n", This, pTrack, group); TRACE("(%p, %p, %#lx)\n", This, pTrack, group);
if (!group) if (!group)
return E_INVALIDARG; return E_INVALIDARG;
LIST_FOR_EACH (pEntry, &This->Tracks) { LIST_FOR_EACH (pEntry, &This->tracks) {
i++; i++;
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry); pIt = LIST_ENTRY(pEntry, struct track_entry, entry);
TRACE(" - #%lu: %p -> %#lx, %p\n", i, pIt, pIt->dwGroupBits, pIt->pTrack); TRACE(" - #%lu: %p -> %#lx, %p\n", i, pIt, pIt->dwGroupBits, pIt->pTrack);
if (NULL != pIt && pIt->pTrack == pTrack) { if (NULL != pIt && pIt->pTrack == pTrack) {
ERR("(%p, %p): track is already in list\n", This, pTrack); ERR("(%p, %p): track is already in list\n", This, pTrack);
...@@ -265,7 +292,7 @@ static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMu ...@@ -265,7 +292,7 @@ static HRESULT WINAPI segment_InsertTrack(IDirectMusicSegment8 *iface, IDirectMu
pNewSegTrack->pTrack = pTrack; pNewSegTrack->pTrack = pTrack;
IDirectMusicTrack_Init(pTrack, (IDirectMusicSegment *)iface); IDirectMusicTrack_Init(pTrack, (IDirectMusicSegment *)iface);
IDirectMusicTrack_AddRef(pTrack); IDirectMusicTrack_AddRef(pTrack);
list_add_tail (&This->Tracks, &pNewSegTrack->entry); list_add_tail (&This->tracks, &pNewSegTrack->entry);
return S_OK; return S_OK;
} }
...@@ -274,12 +301,12 @@ static HRESULT WINAPI segment_RemoveTrack(IDirectMusicSegment8 *iface, IDirectMu ...@@ -274,12 +301,12 @@ static HRESULT WINAPI segment_RemoveTrack(IDirectMusicSegment8 *iface, IDirectMu
{ {
struct segment *This = impl_from_IDirectMusicSegment8(iface); struct segment *This = impl_from_IDirectMusicSegment8(iface);
struct list* pEntry = NULL; struct list* pEntry = NULL;
LPDMUS_PRIVATE_SEGMENT_TRACK pIt = NULL; struct track_entry *pIt = NULL;
TRACE("(%p, %p)\n", This, pTrack); TRACE("(%p, %p)\n", This, pTrack);
LIST_FOR_EACH (pEntry, &This->Tracks) { LIST_FOR_EACH (pEntry, &This->tracks) {
pIt = LIST_ENTRY(pEntry, DMUS_PRIVATE_SEGMENT_TRACK, entry); pIt = LIST_ENTRY(pEntry, struct track_entry, entry);
if (pIt->pTrack == pTrack) { if (pIt->pTrack == pTrack) {
TRACE("(%p, %p): track in list\n", This, pTrack); TRACE("(%p, %p): track in list\n", This, pTrack);
...@@ -397,7 +424,7 @@ static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME star ...@@ -397,7 +424,7 @@ static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME star
struct segment *This = impl_from_IDirectMusicSegment8(iface); struct segment *This = impl_from_IDirectMusicSegment8(iface);
struct segment *clone; struct segment *clone;
IDirectMusicTrack *track; IDirectMusicTrack *track;
DMUS_PRIVATE_SEGMENT_TRACK *track_item, *cloned_item; struct track_entry *track_item, *cloned_item;
HRESULT hr; HRESULT hr;
BOOL track_clone_fail = FALSE; BOOL track_clone_fail = FALSE;
...@@ -417,14 +444,14 @@ static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME star ...@@ -417,14 +444,14 @@ static HRESULT WINAPI segment_Clone(IDirectMusicSegment8 *iface, MUSIC_TIME star
if (clone->pGraph) if (clone->pGraph)
IDirectMusicGraph_AddRef(clone->pGraph); IDirectMusicGraph_AddRef(clone->pGraph);
LIST_FOR_EACH_ENTRY(track_item, &This->Tracks, DMUS_PRIVATE_SEGMENT_TRACK, entry) { LIST_FOR_EACH_ENTRY(track_item, &This->tracks, struct track_entry, entry) {
if (SUCCEEDED(hr = IDirectMusicTrack_Clone(track_item->pTrack, start, end, &track))) { if (SUCCEEDED(hr = IDirectMusicTrack_Clone(track_item->pTrack, start, end, &track))) {
if ((cloned_item = malloc(sizeof(*cloned_item)))) if ((cloned_item = malloc(sizeof(*cloned_item))))
{ {
cloned_item->dwGroupBits = track_item->dwGroupBits; cloned_item->dwGroupBits = track_item->dwGroupBits;
cloned_item->flags = track_item->flags; cloned_item->flags = track_item->flags;
cloned_item->pTrack = track; cloned_item->pTrack = track;
list_add_tail(&clone->Tracks, &cloned_item->entry); list_add_tail(&clone->tracks, &cloned_item->entry);
continue; continue;
} }
else else
...@@ -625,7 +652,7 @@ static HRESULT parse_track_form(struct segment *This, IStream *stream, const str ...@@ -625,7 +652,7 @@ static HRESULT parse_track_form(struct segment *This, IStream *stream, const str
DMUS_IO_TRACK_HEADER thdr; DMUS_IO_TRACK_HEADER thdr;
DMUS_IO_TRACK_EXTRAS_HEADER txhdr = {0}; DMUS_IO_TRACK_EXTRAS_HEADER txhdr = {0};
HRESULT hr; HRESULT hr;
DMUS_PRIVATE_SEGMENT_TRACK *item; struct track_entry *item;
TRACE("Parsing track form in %p: %s\n", stream, debugstr_chunk(riff)); TRACE("Parsing track form in %p: %s\n", stream, debugstr_chunk(riff));
...@@ -685,7 +712,7 @@ static HRESULT parse_track_form(struct segment *This, IStream *stream, const str ...@@ -685,7 +712,7 @@ static HRESULT parse_track_form(struct segment *This, IStream *stream, const str
if (FAILED(hr)) if (FAILED(hr))
goto done; goto done;
item = LIST_ENTRY(list_tail(&This->Tracks), DMUS_PRIVATE_SEGMENT_TRACK, entry); item = LIST_ENTRY(list_tail(&This->tracks), struct track_entry, entry);
item->flags = txhdr.dwFlags; item->flags = txhdr.dwFlags;
done: done:
...@@ -892,7 +919,7 @@ static struct segment *segment_create(void) ...@@ -892,7 +919,7 @@ static struct segment *segment_create(void)
dmobject_init(&obj->dmobj, &CLSID_DirectMusicSegment, (IUnknown *)&obj->IDirectMusicSegment8_iface); dmobject_init(&obj->dmobj, &CLSID_DirectMusicSegment, (IUnknown *)&obj->IDirectMusicSegment8_iface);
obj->dmobj.IDirectMusicObject_iface.lpVtbl = &segment_object_vtbl; obj->dmobj.IDirectMusicObject_iface.lpVtbl = &segment_object_vtbl;
obj->dmobj.IPersistStream_iface.lpVtbl = &segment_persist_stream_vtbl; obj->dmobj.IPersistStream_iface.lpVtbl = &segment_persist_stream_vtbl;
list_init (&obj->Tracks); list_init(&obj->tracks);
return obj; return obj;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment