From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/dmusic_private.h | 9 ++---- dlls/dmusic/instrument.c | 60 ++++++++++++++++++++---------------- 2 files changed, 35 insertions(+), 34 deletions(-)
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 4eae993f259..bdc86b6883c 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -79,11 +79,6 @@ typedef struct instrument_region { BOOL loop_present; } instrument_region;
-typedef struct instrument_articulation { - CONNECTIONLIST connections_list; - CONNECTION *connections; -} instrument_articulation; - /***************************************************************************** * ClassFactory */ @@ -186,8 +181,8 @@ struct instrument /* instrument data */ BOOL loaded; instrument_region *regions; - ULONG nb_articulations; - instrument_articulation *articulations; + + struct list articulations; };
static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface) diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 5677f128060..a65826976f3 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -25,6 +25,15 @@ WINE_DEFAULT_DEBUG_CHANNEL(dmusic);
static const GUID IID_IDirectMusicInstrumentPRIVATE = { 0xbcb20080, 0xa40c, 0x11d1, { 0x86, 0xbc, 0x00, 0xc0, 0x4f, 0xbf, 0x8f, 0xef } };
+struct articulation +{ + struct list entry; + CONNECTIONLIST list; + CONNECTION connections[]; +}; + +C_ASSERT(sizeof(struct articulation) == offsetof(struct articulation, connections[0])); + static HRESULT WINAPI instrument_QueryInterface(LPDIRECTMUSICINSTRUMENT iface, REFIID riid, LPVOID *ret_iface) { TRACE("(%p)->(%s, %p)\n", iface, debugstr_dmguid(riid), ret_iface); @@ -74,12 +83,16 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface)
if (!ref) { - ULONG i; + struct articulation *articulation, *next_articulation;
free(This->regions); - for (i = 0; i < This->nb_articulations; i++) - free(This->articulations->connections); - free(This->articulations); + + LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry) + { + list_remove(&articulation->entry); + free(articulation); + } + free(This); }
@@ -125,6 +138,7 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface) if (!(instrument = calloc(1, sizeof(*instrument)))) return E_OUTOFMEMORY; instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl; instrument->ref = 1; + list_init(&instrument->articulations);
TRACE("Created DirectMusicInstrument %p\n", instrument); *ret_iface = &instrument->IDirectMusicInstrument_iface; @@ -244,35 +258,27 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_
static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) { - HRESULT ret; - instrument_articulation *articulation; - - This->articulations = realloc(This->articulations, sizeof(*This->articulations) * (This->nb_articulations + 1)); - if (!This->articulations) - return E_OUTOFMEMORY; + struct articulation *articulation; + CONNECTIONLIST list; + HRESULT hr; + UINT size;
- articulation = &This->articulations[This->nb_articulations]; + if (FAILED(hr = read_from_stream(stream, &list, sizeof(list)))) return hr; + if (list.cbSize != sizeof(list)) return E_INVALIDARG;
- ret = read_from_stream(stream, &articulation->connections_list, sizeof(CONNECTIONLIST)); - if (FAILED(ret)) - return ret; - - articulation->connections = malloc(sizeof(CONNECTION) * articulation->connections_list.cConnections); - if (!articulation->connections) - return E_OUTOFMEMORY; + size = offsetof(struct articulation, connections[list.cConnections]); + if (!(articulation = malloc(size))) return E_OUTOFMEMORY; + articulation->list = list;
- ret = read_from_stream(stream, articulation->connections, sizeof(CONNECTION) * articulation->connections_list.cConnections); - if (FAILED(ret)) + size = sizeof(CONNECTION) * list.cConnections; + if (FAILED(hr = read_from_stream(stream, articulation->connections, size))) free(articulation); + else { - free(articulation->connections); - return ret; + subtract_bytes(length, sizeof(list) + sizeof(CONNECTION) * list.cConnections); + list_add_tail(&This->articulations, &articulation->entry); }
- subtract_bytes(length, sizeof(CONNECTIONLIST) + sizeof(CONNECTION) * articulation->connections_list.cConnections); - - This->nb_articulations++; - - return S_OK; + return hr; }
/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/dmusic_private.h | 8 +++--- dlls/dmusic/instrument.c | 50 ++++++++++++++++++------------------ dlls/dmusic/port.c | 19 ++++++++------ 3 files changed, 41 insertions(+), 36 deletions(-)
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index bdc86b6883c..3fb32d73691 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -71,13 +71,15 @@ typedef struct port_info { ULONG device; } port_info;
-typedef struct instrument_region { +struct region +{ + struct list entry; RGNHEADER header; WAVELINK wave_link; WSMPL wave_sample; WLOOP wave_loop; BOOL loop_present; -} instrument_region; +};
/***************************************************************************** * ClassFactory @@ -180,9 +182,9 @@ struct instrument WCHAR wszName[DMUS_MAX_NAME]; /* instrument data */ BOOL loaded; - instrument_region *regions;
struct list articulations; + struct list regions; };
static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicInstrument *iface) diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index a65826976f3..bcd2ef58265 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -84,8 +84,7 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface) if (!ref) { struct articulation *articulation, *next_articulation; - - free(This->regions); + struct region *region, *next_region;
LIST_FOR_EACH_ENTRY_SAFE(articulation, next_articulation, &This->articulations, struct articulation, entry) { @@ -93,6 +92,12 @@ static ULONG WINAPI instrument_Release(LPDIRECTMUSICINSTRUMENT iface) free(articulation); }
+ LIST_FOR_EACH_ENTRY_SAFE(region, next_region, &This->regions, struct region, entry) + { + list_remove(®ion->entry); + free(region); + } + free(This); }
@@ -139,6 +144,7 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface) instrument->IDirectMusicInstrument_iface.lpVtbl = &instrument_vtbl; instrument->ref = 1; list_init(&instrument->articulations); + list_init(&instrument->regions);
TRACE("Created DirectMusicInstrument %p\n", instrument); *ret_iface = &instrument->IDirectMusicInstrument_iface; @@ -186,18 +192,20 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes) return ret; }
-static HRESULT load_region(struct instrument *This, IStream *stream, instrument_region *region, ULONG length) +static HRESULT load_region(struct instrument *This, IStream *stream, ULONG length) { + struct region *region; HRESULT ret; DMUS_PRIVATE_CHUNK chunk;
- TRACE("(%p, %p, %p, %lu)\n", This, stream, region, length); + TRACE("(%p, %p, %lu)\n", This, stream, length); + + if (!(region = malloc(sizeof(*region)))) return E_OUTOFMEMORY;
while (length) { ret = read_from_stream(stream, &chunk, sizeof(chunk)); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed;
length = subtract_bytes(length, sizeof(chunk));
@@ -207,8 +215,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ TRACE("RGNH chunk (region header): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, ®ion->header, sizeof(region->header)); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed;
length = subtract_bytes(length, sizeof(region->header)); break; @@ -217,16 +224,14 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ TRACE("WSMP chunk (wave sample): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, ®ion->wave_sample, sizeof(region->wave_sample)); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed; length = subtract_bytes(length, sizeof(region->wave_sample));
if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample)))) break;
ret = read_from_stream(stream, ®ion->wave_loop, sizeof(region->wave_loop)); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed;
length = subtract_bytes(length, sizeof(region->wave_loop)); break; @@ -235,8 +240,7 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ TRACE("WLNK chunk (wave link): %lu bytes\n", chunk.dwSize);
ret = read_from_stream(stream, ®ion->wave_link, sizeof(region->wave_link)); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed;
length = subtract_bytes(length, sizeof(region->wave_link)); break; @@ -245,15 +249,19 @@ static HRESULT load_region(struct instrument *This, IStream *stream, instrument_ TRACE("Unknown chunk %s (skipping): %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
ret = advance_stream(stream, chunk.dwSize); - if (FAILED(ret)) - return ret; + if (FAILED(ret)) goto failed;
length = subtract_bytes(length, chunk.dwSize); break; } }
+ list_add_tail(&This->regions, ®ion->entry); return S_OK; + +failed: + free(region); + return ret; }
static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) @@ -287,7 +295,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) struct instrument *This = impl_from_IDirectMusicInstrument(iface); HRESULT hr; DMUS_PRIVATE_CHUNK chunk; - ULONG i = 0; ULONG length = This->length;
TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length); @@ -302,10 +309,6 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) return DMUS_E_UNSUPPORTED_STREAM; }
- This->regions = malloc(sizeof(*This->regions) * This->header.cRegions); - if (!This->regions) - return E_OUTOFMEMORY; - while (length) { hr = read_from_stream(stream, &chunk, sizeof(chunk)); @@ -362,7 +365,7 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) if (chunk.fccID == FOURCC_RGN) { TRACE("RGN chunk (region): %lu bytes\n", chunk.dwSize); - hr = load_region(This, stream, &This->regions[i++], chunk.dwSize - sizeof(chunk.fccID)); + hr = load_region(This, stream, chunk.dwSize - sizeof(chunk.fccID)); } else { @@ -431,8 +434,5 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) return S_OK;
error: - free(This->regions); - This->regions = NULL; - return DMUS_E_UNSUPPORTED_STREAM; } diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c index 95a02704a5f..a5ff9bac16e 100644 --- a/dlls/dmusic/port.c +++ b/dlls/dmusic/port.c @@ -267,6 +267,7 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi { struct synth_port *This = synth_from_IDirectMusicPort(iface); struct instrument *instrument_object; + struct region *instrument_region; HRESULT ret; BOOL on_heap; HANDLE download; @@ -312,22 +313,24 @@ static HRESULT WINAPI synth_port_DownloadInstrument(IDirectMusicPort *iface, IDi instrument_info->ulCopyrightIdx = 0; /* FIXME */ instrument_info->ulFlags = 0; /* FIXME */
- for (i = 0; i < nb_regions; i++) + i = 0; + LIST_FOR_EACH_ENTRY(instrument_region, &instrument_object->regions, struct region, entry) { DMUS_REGION *region = (DMUS_REGION*)(data + offset);
offset_table->ulOffsetTable[1 + i] = offset; offset += sizeof(DMUS_REGION); - region->RangeKey = instrument_object->regions[i].header.RangeKey; - region->RangeVelocity = instrument_object->regions[i].header.RangeVelocity; - region->fusOptions = instrument_object->regions[i].header.fusOptions; - region->usKeyGroup = instrument_object->regions[i].header.usKeyGroup; + region->RangeKey = instrument_region->header.RangeKey; + region->RangeVelocity = instrument_region->header.RangeVelocity; + region->fusOptions = instrument_region->header.fusOptions; + region->usKeyGroup = instrument_region->header.usKeyGroup; region->ulRegionArtIdx = 0; /* FIXME */ region->ulNextRegionIdx = i != (nb_regions - 1) ? (i + 2) : 0; region->ulFirstExtCkIdx = 0; /* FIXME */ - region->WaveLink = instrument_object->regions[i].wave_link; - region->WSMP = instrument_object->regions[i].wave_sample; - region->WLOOP[0] = instrument_object->regions[i].wave_loop; + region->WaveLink = instrument_region->wave_link; + region->WSMP = instrument_region->wave_sample; + region->WLOOP[0] = instrument_region->wave_loop; + i++; }
ret = IDirectMusicSynth8_Download(This->synth, &download, (void*)data, &on_heap);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/dmobject.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index 07d887a376c..a08db8cba58 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -338,11 +338,10 @@ HRESULT stream_get_chunk(IStream *stream, struct chunk_entry *chunk) } }
- if (chunk->id == FOURCC_LIST || chunk->id == FOURCC_RIFF) { - hr = stream_read(stream, &chunk->type, sizeof(FOURCC)); - if (hr != S_OK) - return hr != S_FALSE ? hr : E_FAIL; - } + if (chunk->id != FOURCC_LIST && chunk->id != FOURCC_RIFF) + chunk->type = 0; + else if ((hr = stream_read(stream, &chunk->type, sizeof(FOURCC))) != S_OK) + return hr != S_FALSE ? hr : E_FAIL;
TRACE_(dmfile)("Returning %s\n", debugstr_chunk(chunk));
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/dmobject.c | 2 +- dlls/dmusic/dmobject.h | 2 + dlls/dmusic/instrument.c | 176 ++++++++++++++++----------------------- 3 files changed, 77 insertions(+), 103 deletions(-)
diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index a08db8cba58..2bef5511851 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -287,7 +287,7 @@ const char *debugstr_chunk(const struct chunk_entry *chunk) return wine_dbg_sprintf("%s chunk, %ssize %lu", debugstr_fourcc(chunk->id), type, chunk->size); }
-static HRESULT stream_read(IStream *stream, void *data, ULONG size) +HRESULT stream_read(IStream *stream, void *data, ULONG size) { ULONG read; HRESULT hr; diff --git a/dlls/dmusic/dmobject.h b/dlls/dmusic/dmobject.h index 772be015c80..98069de8cc4 100644 --- a/dlls/dmusic/dmobject.h +++ b/dlls/dmusic/dmobject.h @@ -30,7 +30,9 @@ struct chunk_entry { ULARGE_INTEGER offset; /* chunk offset from start of stream */ const struct chunk_entry *parent; /* enclosing RIFF or LIST chunk */ }; +#define MAKE_IDTYPE(id, type) (((UINT64)type << 32) | (UINT64)id)
+HRESULT stream_read(IStream *stream, void *data, ULONG size); HRESULT stream_get_chunk(IStream *stream, struct chunk_entry *chunk); HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk); HRESULT stream_skip_chunk(IStream *stream, const struct chunk_entry *chunk); diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index bcd2ef58265..5941042caa1 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -192,98 +192,95 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes) return ret; }
-static HRESULT load_region(struct instrument *This, IStream *stream, ULONG length) +static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) { - struct region *region; - HRESULT ret; - DMUS_PRIVATE_CHUNK chunk; + struct articulation *articulation; + CONNECTIONLIST list; + HRESULT hr; + UINT size;
- TRACE("(%p, %p, %lu)\n", This, stream, length); + if (FAILED(hr = read_from_stream(stream, &list, sizeof(list)))) return hr; + if (list.cbSize != sizeof(list)) return E_INVALIDARG;
- if (!(region = malloc(sizeof(*region)))) return E_OUTOFMEMORY; + size = offsetof(struct articulation, connections[list.cConnections]); + if (!(articulation = malloc(size))) return E_OUTOFMEMORY; + articulation->list = list;
- while (length) + size = sizeof(CONNECTION) * list.cConnections; + if (FAILED(hr = read_from_stream(stream, articulation->connections, size))) free(articulation); + else { - ret = read_from_stream(stream, &chunk, sizeof(chunk)); - if (FAILED(ret)) goto failed; - - length = subtract_bytes(length, sizeof(chunk)); - - switch (chunk.fccID) - { - case FOURCC_RGNH: - TRACE("RGNH chunk (region header): %lu bytes\n", chunk.dwSize); - - ret = read_from_stream(stream, ®ion->header, sizeof(region->header)); - if (FAILED(ret)) goto failed; - - length = subtract_bytes(length, sizeof(region->header)); - break; - - case FOURCC_WSMP: - TRACE("WSMP chunk (wave sample): %lu bytes\n", chunk.dwSize); - - ret = read_from_stream(stream, ®ion->wave_sample, sizeof(region->wave_sample)); - if (FAILED(ret)) goto failed; - length = subtract_bytes(length, sizeof(region->wave_sample)); - - if (!(region->loop_present = (chunk.dwSize != sizeof(region->wave_sample)))) - break; - - ret = read_from_stream(stream, ®ion->wave_loop, sizeof(region->wave_loop)); - if (FAILED(ret)) goto failed; - - length = subtract_bytes(length, sizeof(region->wave_loop)); - break; + subtract_bytes(length, sizeof(list) + sizeof(CONNECTION) * list.cConnections); + list_add_tail(&This->articulations, &articulation->entry); + }
- case FOURCC_WLNK: - TRACE("WLNK chunk (wave link): %lu bytes\n", chunk.dwSize); + return hr; +}
- ret = read_from_stream(stream, ®ion->wave_link, sizeof(region->wave_link)); - if (FAILED(ret)) goto failed; +static HRESULT parse_rgn_chunk(struct instrument *This, IStream *stream, struct chunk_entry *parent) +{ + struct chunk_entry chunk = {.parent = parent}; + struct region *region; + HRESULT hr;
- length = subtract_bytes(length, sizeof(region->wave_link)); - break; + if (!(region = malloc(sizeof(*region)))) return E_OUTOFMEMORY;
- default: - TRACE("Unknown chunk %s (skipping): %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case FOURCC_RGNH: + hr = stream_chunk_get_data(stream, &chunk, ®ion->header, sizeof(region->header)); + break; + + case FOURCC_WSMP: + if (chunk.size < sizeof(region->wave_sample)) hr = E_INVALIDARG; + else hr = stream_read(stream, ®ion->wave_sample, sizeof(region->wave_sample)); + if (SUCCEEDED(hr) && region->wave_sample.cSampleLoops) + { + if (region->wave_sample.cSampleLoops > 1) FIXME("More than one wave loop is not implemented\n"); + if (chunk.size != sizeof(WSMPL) + region->wave_sample.cSampleLoops * sizeof(WLOOP)) hr = E_INVALIDARG; + else hr = stream_read(stream, ®ion->wave_loop, sizeof(region->wave_loop)); + } + break;
- ret = advance_stream(stream, chunk.dwSize); - if (FAILED(ret)) goto failed; + case FOURCC_WLNK: + hr = stream_chunk_get_data(stream, &chunk, ®ion->wave_link, sizeof(region->wave_link)); + break;
- length = subtract_bytes(length, chunk.dwSize); - break; + default: + FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + break; } + + if (FAILED(hr)) break; }
- list_add_tail(&This->regions, ®ion->entry); - return S_OK; + if (FAILED(hr)) free(region); + else list_add_tail(&This->regions, ®ion->entry);
-failed: - free(region); - return ret; + return hr; }
-static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) +static HRESULT parse_lrgn_list(struct instrument *This, IStream *stream, struct chunk_entry *parent) { - struct articulation *articulation; - CONNECTIONLIST list; + struct chunk_entry chunk = {.parent = parent}; HRESULT hr; - UINT size;
- if (FAILED(hr = read_from_stream(stream, &list, sizeof(list)))) return hr; - if (list.cbSize != sizeof(list)) return E_INVALIDARG; + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case MAKE_IDTYPE(FOURCC_LIST, FOURCC_RGN): + hr = parse_rgn_chunk(This, stream, &chunk); + break;
- size = offsetof(struct articulation, connections[list.cConnections]); - if (!(articulation = malloc(size))) return E_OUTOFMEMORY; - articulation->list = list; + default: + FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + break; + }
- size = sizeof(CONNECTION) * list.cConnections; - if (FAILED(hr = read_from_stream(stream, articulation->connections, size))) free(articulation); - else - { - subtract_bytes(length, sizeof(list) + sizeof(CONNECTION) * list.cConnections); - list_add_tail(&This->articulations, &articulation->entry); + if (FAILED(hr)) break; }
return hr; @@ -344,40 +341,15 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) switch (chunk.fccID) { case FOURCC_LRGN: + { + static const LARGE_INTEGER zero = {0}; + struct chunk_entry list_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID}; TRACE("LRGN chunk (regions list): %lu bytes\n", size); - - while (size) - { - hr = read_from_stream(stream, &chunk, sizeof(chunk)); - if (FAILED(hr)) - goto error; - - if (chunk.fccID != FOURCC_LIST) - { - TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - goto error; - } - - hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID)); - if (FAILED(hr)) - goto error; - - if (chunk.fccID == FOURCC_RGN) - { - TRACE("RGN chunk (region): %lu bytes\n", chunk.dwSize); - hr = load_region(This, stream, chunk.dwSize - sizeof(chunk.fccID)); - } - else - { - TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID)); - } - if (FAILED(hr)) - goto error; - - size = subtract_bytes(size, chunk.dwSize + sizeof(chunk)); - } + IStream_Seek(stream, zero, STREAM_SEEK_CUR, &list_chunk.offset); + list_chunk.offset.QuadPart -= 12; + hr = parse_lrgn_list(This, stream, &list_chunk); break; + }
case FOURCC_LART: TRACE("LART chunk (articulations list): %lu bytes\n", size);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/instrument.c | 63 ++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 28 deletions(-)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 5941042caa1..1e171048008 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -192,14 +192,16 @@ static inline HRESULT advance_stream(IStream *stream, ULONG bytes) return ret; }
-static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG length) +static HRESULT parse_art1_chunk(struct instrument *This, IStream *stream, struct chunk_entry *chunk) { struct articulation *articulation; CONNECTIONLIST list; HRESULT hr; UINT size;
- if (FAILED(hr = read_from_stream(stream, &list, sizeof(list)))) return hr; + if (chunk->size < sizeof(list)) return E_INVALIDARG; + if (FAILED(hr = stream_read(stream, &list, sizeof(list)))) return hr; + if (chunk->size != list.cbSize + sizeof(CONNECTION) * list.cConnections) return E_INVALIDARG; if (list.cbSize != sizeof(list)) return E_INVALIDARG;
size = offsetof(struct articulation, connections[list.cConnections]); @@ -207,11 +209,31 @@ static HRESULT load_articulation(struct instrument *This, IStream *stream, ULONG articulation->list = list;
size = sizeof(CONNECTION) * list.cConnections; - if (FAILED(hr = read_from_stream(stream, articulation->connections, size))) free(articulation); - else + if (FAILED(hr = stream_read(stream, articulation->connections, size))) free(articulation); + else list_add_tail(&This->articulations, &articulation->entry); + + return hr; +} + +static HRESULT parse_lart_list(struct instrument *This, IStream *stream, struct chunk_entry *parent) +{ + struct chunk_entry chunk = {.parent = parent}; + HRESULT hr; + + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) { - subtract_bytes(length, sizeof(list) + sizeof(CONNECTION) * list.cConnections); - list_add_tail(&This->articulations, &articulation->entry); + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case FOURCC_ART1: + hr = parse_art1_chunk(This, stream, &chunk); + break; + + default: + FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + break; + } + + if (FAILED(hr)) break; }
return hr; @@ -352,30 +374,15 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) }
case FOURCC_LART: + { + static const LARGE_INTEGER zero = {0}; + struct chunk_entry list_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID}; TRACE("LART chunk (articulations list): %lu bytes\n", size); - - while (size) - { - hr = read_from_stream(stream, &chunk, sizeof(chunk)); - if (FAILED(hr)) - goto error; - - if (chunk.fccID == FOURCC_ART1) - { - TRACE("ART1 chunk (level 1 articulation): %lu bytes\n", chunk.dwSize); - hr = load_articulation(This, stream, chunk.dwSize); - } - else - { - TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - hr = advance_stream(stream, chunk.dwSize); - } - if (FAILED(hr)) - goto error; - - size = subtract_bytes(size, chunk.dwSize + sizeof(chunk)); - } + IStream_Seek(stream, zero, STREAM_SEEK_CUR, &list_chunk.offset); + list_chunk.offset.QuadPart -= 12; + hr = parse_lart_list(This, stream, &list_chunk); break; + }
default: TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/instrument.c | 163 +++++++++++---------------------------- 1 file changed, 45 insertions(+), 118 deletions(-)
diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index 1e171048008..cbcebcb5902 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -151,47 +151,6 @@ HRESULT instrument_create(IDirectMusicInstrument **ret_iface) return S_OK; }
-static HRESULT read_from_stream(IStream *stream, void *data, ULONG size) -{ - ULONG bytes_read; - HRESULT hr; - - hr = IStream_Read(stream, data, size, &bytes_read); - if(FAILED(hr)){ - TRACE("IStream_Read failed: %08lx\n", hr); - return hr; - } - if (bytes_read < size) { - TRACE("Didn't read full chunk: %lu < %lu\n", bytes_read, size); - return E_FAIL; - } - - return S_OK; -} - -static inline DWORD subtract_bytes(DWORD len, DWORD bytes) -{ - if(bytes > len){ - TRACE("Apparent mismatch in chunk lengths? %lu bytes remaining, %lu bytes read\n", len, bytes); - return 0; - } - return len - bytes; -} - -static inline HRESULT advance_stream(IStream *stream, ULONG bytes) -{ - LARGE_INTEGER move; - HRESULT ret; - - move.QuadPart = bytes; - - ret = IStream_Seek(stream, move, STREAM_SEEK_CUR, NULL); - if (FAILED(ret)) - WARN("IStream_Seek failed: %08lx\n", ret); - - return ret; -} - static HRESULT parse_art1_chunk(struct instrument *This, IStream *stream, struct chunk_entry *chunk) { struct articulation *articulation; @@ -308,13 +267,45 @@ static HRESULT parse_lrgn_list(struct instrument *This, IStream *stream, struct return hr; }
+static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct chunk_entry *parent) +{ + struct chunk_entry chunk = {.parent = parent}; + HRESULT hr; + + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case FOURCC_INSH: + case FOURCC_DLID: + /* Instrument header and id are already set so just skip */ + break; + + case MAKE_IDTYPE(FOURCC_LIST, FOURCC_LRGN): + hr = parse_lrgn_list(This, stream, &chunk); + break; + + case MAKE_IDTYPE(FOURCC_LIST, FOURCC_LART): + hr = parse_lart_list(This, stream, &chunk); + break; + + default: + FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + break; + } + + if (FAILED(hr)) break; + } + + return hr; +} + /* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) { struct instrument *This = impl_from_IDirectMusicInstrument(iface); + struct chunk_entry chunk = {0}; HRESULT hr; - DMUS_PRIVATE_CHUNK chunk; - ULONG length = This->length;
TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length);
@@ -328,90 +319,26 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) return DMUS_E_UNSUPPORTED_STREAM; }
- while (length) + if ((hr = stream_next_chunk(stream, &chunk)) == S_OK) { - hr = read_from_stream(stream, &chunk, sizeof(chunk)); - if (FAILED(hr)) - goto error; - - length = subtract_bytes(length, sizeof(chunk) + chunk.dwSize); - - switch (chunk.fccID) + switch (MAKE_IDTYPE(chunk.id, chunk.type)) { - case FOURCC_INSH: - case FOURCC_DLID: - TRACE("Chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - - /* Instrument header and id are already set so just skip */ - hr = advance_stream(stream, chunk.dwSize); - if (FAILED(hr)) - goto error; - - break; - - case FOURCC_LIST: { - DWORD size = chunk.dwSize; - - TRACE("LIST chunk: %lu bytes\n", chunk.dwSize); - - hr = read_from_stream(stream, &chunk.fccID, sizeof(chunk.fccID)); - if (FAILED(hr)) - goto error; - - size = subtract_bytes(size, sizeof(chunk.fccID)); - - switch (chunk.fccID) - { - case FOURCC_LRGN: - { - static const LARGE_INTEGER zero = {0}; - struct chunk_entry list_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID}; - TRACE("LRGN chunk (regions list): %lu bytes\n", size); - IStream_Seek(stream, zero, STREAM_SEEK_CUR, &list_chunk.offset); - list_chunk.offset.QuadPart -= 12; - hr = parse_lrgn_list(This, stream, &list_chunk); - break; - } - - case FOURCC_LART: - { - static const LARGE_INTEGER zero = {0}; - struct chunk_entry list_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID}; - TRACE("LART chunk (articulations list): %lu bytes\n", size); - IStream_Seek(stream, zero, STREAM_SEEK_CUR, &list_chunk.offset); - list_chunk.offset.QuadPart -= 12; - hr = parse_lart_list(This, stream, &list_chunk); - break; - } - - default: - TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - - hr = advance_stream(stream, chunk.dwSize - sizeof(chunk.fccID)); - if (FAILED(hr)) - goto error; - - size = subtract_bytes(size, chunk.dwSize - sizeof(chunk.fccID)); - break; - } - break; - } - - default: - TRACE("Unknown chunk %s: %lu bytes\n", debugstr_fourcc(chunk.fccID), chunk.dwSize); - - hr = advance_stream(stream, chunk.dwSize); - if (FAILED(hr)) - goto error; + case MAKE_IDTYPE(FOURCC_LIST, FOURCC_INS): + hr = parse_ins_chunk(This, stream, &chunk); + break;
- break; + default: + WARN("Invalid instrument chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + goto error; } }
- This->loaded = TRUE; + if (FAILED(hr)) goto error;
+ This->loaded = TRUE; return S_OK;
error: + stream_skip_chunk(stream, &chunk); return DMUS_E_UNSUPPORTED_STREAM; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/collection.c | 68 +++--------------------------------- dlls/dmusic/dmusic_private.h | 7 +--- dlls/dmusic/instrument.c | 46 +++++++++++++++--------- 3 files changed, 35 insertions(+), 86 deletions(-)
diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c index 5332adff084..cca23870f9d 100644 --- a/dlls/dmusic/collection.c +++ b/dlls/dmusic/collection.c @@ -115,7 +115,6 @@ static HRESULT WINAPI collection_GetInstrument(IDirectMusicCollection *iface, if (patch == inst_patch) { *instrument = inst_entry->pInstrument; IDirectMusicInstrument_AddRef(inst_entry->pInstrument); - instrument_load(inst_entry->pInstrument, This->pStm); TRACE(": returning instrument %p\n", *instrument); return S_OK; } @@ -212,7 +211,6 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, DMUS_PRIVATE_CHUNK chunk; DWORD StreamSize, StreamCount, ListSize[2], ListCount[2]; LARGE_INTEGER liMove; /* used when skipping chunks */ - ULARGE_INTEGER dlibInstrumentPosition;
IStream_AddRef(stream); /* add count for later references */ This->pStm = stream; @@ -374,68 +372,12 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, ListCount[1] = 0; switch (chunk.fccID) { case FOURCC_INS: { - DMUS_PRIVATE_INSTRUMENTENTRY *new_instrument = calloc(1, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY)); + DMUS_PRIVATE_INSTRUMENTENTRY *entry = calloc(1, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY)); TRACE_(dmfile)(": instrument list\n"); - /* Only way to create this one... even M$ does it discretely */ - instrument_create(&new_instrument->pInstrument); - { - struct instrument *instrument = impl_from_IDirectMusicInstrument(new_instrument->pInstrument); - /* Store offset and length, they will be needed when loading the instrument */ - liMove.QuadPart = 0; - IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &dlibInstrumentPosition); - instrument->liInstrumentPosition.QuadPart = dlibInstrumentPosition.QuadPart; - instrument->length = ListSize[1]; - do { - IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL); - ListCount[1] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize; - TRACE_(dmfile)(": %s chunk (size = %#04lx)", debugstr_fourcc(chunk.fccID), chunk.dwSize); - switch (chunk.fccID) { - case FOURCC_INSH: { - TRACE_(dmfile)(": instrument header chunk\n"); - IStream_Read(stream, &instrument->header, chunk.dwSize, NULL); - break; - } - case FOURCC_DLID: { - TRACE_(dmfile)(": DLID (GUID) chunk\n"); - IStream_Read(stream, &instrument->id, chunk.dwSize, NULL); - break; - } - case FOURCC_LIST: { - IStream_Read(stream, &chunk.fccID, sizeof(FOURCC), NULL); - TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID)); - switch (chunk.fccID) { - 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)(": ListCount[1] = %ld < ListSize[1] = %ld\n", ListCount[1], ListSize[1]); - } while (ListCount[1] < ListSize[1]); - /* DEBUG: dumps whole instrument object tree: */ - if (TRACE_ON(dmusic)) { - TRACE("*** IDirectMusicInstrument (%p) ***\n", instrument); - if (!IsEqualGUID(&instrument->id, &GUID_NULL)) - TRACE(" - GUID = %s\n", debugstr_dmguid(&instrument->id)); - TRACE(" - Instrument header:\n"); - TRACE(" - cRegions: %ld\n", instrument->header.cRegions); - TRACE(" - Locale:\n"); - TRACE(" - ulBank: %ld\n", instrument->header.Locale.ulBank); - TRACE(" - ulInstrument: %ld\n", instrument->header.Locale.ulInstrument); - TRACE(" => dwPatch: %ld\n", MIDILOCALE2Patch(&instrument->header.Locale)); - } - list_add_tail(&This->Instruments, &new_instrument->entry); - } + liMove.QuadPart = -12; + IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); + if (FAILED(instrument_create_from_stream(stream, &entry->pInstrument))) free(entry); + else list_add_tail(&This->Instruments, &entry->entry); break; } } diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 3fb32d73691..387c787fd2e 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -95,7 +95,7 @@ extern HRESULT DMUSIC_CreateReferenceClockImpl (LPCGUID lpcGUID, LPVOID* ppobj,
extern HRESULT download_create(DWORD size, IDirectMusicDownload **ret_iface);
-extern HRESULT instrument_create(IDirectMusicInstrument **ret_iface); +extern HRESULT instrument_create_from_stream(IStream *stream, IDirectMusicInstrument **ret_iface);
/***************************************************************************** * IDirectMusic8Impl implementation structure @@ -175,13 +175,10 @@ struct instrument IDirectMusicInstrument IDirectMusicInstrument_iface; LONG ref;
- LARGE_INTEGER liInstrumentPosition; /* offset in a stream where instrument chunk can be found */ - ULONG length; /* Length of the instrument in the stream */ GUID id; INSTHEADER header; WCHAR wszName[DMUS_MAX_NAME]; /* instrument data */ - BOOL loaded;
struct list articulations; struct list regions; @@ -192,8 +189,6 @@ static inline struct instrument *impl_from_IDirectMusicInstrument(IDirectMusicIn return CONTAINING_RECORD(iface, struct instrument, IDirectMusicInstrument_iface); }
-extern HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream); - /***************************************************************************** * Misc. */ diff --git a/dlls/dmusic/instrument.c b/dlls/dmusic/instrument.c index cbcebcb5902..b62b053c542 100644 --- a/dlls/dmusic/instrument.c +++ b/dlls/dmusic/instrument.c @@ -135,7 +135,7 @@ static const IDirectMusicInstrumentVtbl instrument_vtbl = instrument_SetPatch, };
-HRESULT instrument_create(IDirectMusicInstrument **ret_iface) +static HRESULT instrument_create(IDirectMusicInstrument **ret_iface) { struct instrument *instrument;
@@ -277,8 +277,11 @@ static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct switch (MAKE_IDTYPE(chunk.id, chunk.type)) { case FOURCC_INSH: + hr = stream_chunk_get_data(stream, &chunk, &This->header, sizeof(This->header)); + break; + case FOURCC_DLID: - /* Instrument header and id are already set so just skip */ + hr = stream_chunk_get_data(stream, &chunk, &This->id, sizeof(This->id)); break;
case MAKE_IDTYPE(FOURCC_LIST, FOURCC_LRGN): @@ -300,24 +303,17 @@ static HRESULT parse_ins_chunk(struct instrument *This, IStream *stream, struct return hr; }
-/* Function that loads all instrument data and which is called from IDirectMusicCollection_GetInstrument as in native */ -HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream) +HRESULT instrument_create_from_stream(IStream *stream, IDirectMusicInstrument **ret_iface) { - struct instrument *This = impl_from_IDirectMusicInstrument(iface); struct chunk_entry chunk = {0}; + IDirectMusicInstrument *iface; + struct instrument *This; HRESULT hr;
- TRACE("(%p, %p): offset = 0x%s, length = %lu)\n", This, stream, wine_dbgstr_longlong(This->liInstrumentPosition.QuadPart), This->length); + TRACE("(%p, %p)\n", stream, ret_iface);
- if (This->loaded) - return S_OK; - - hr = IStream_Seek(stream, This->liInstrumentPosition, STREAM_SEEK_SET, NULL); - if (FAILED(hr)) - { - WARN("IStream_Seek failed: %08lx\n", hr); - return DMUS_E_UNSUPPORTED_STREAM; - } + if (FAILED(hr = instrument_create(&iface))) return hr; + This = impl_from_IDirectMusicInstrument(iface);
if ((hr = stream_next_chunk(stream, &chunk)) == S_OK) { @@ -329,16 +325,32 @@ HRESULT instrument_load(IDirectMusicInstrument *iface, IStream *stream)
default: WARN("Invalid instrument chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); - goto error; + hr = E_INVALIDARG; + break; } }
if (FAILED(hr)) goto error;
- This->loaded = TRUE; + if (TRACE_ON(dmusic)) + { + TRACE("Created DirectMusicInstrument (%p) ***\n", This); + if (!IsEqualGUID(&This->id, &GUID_NULL)) + TRACE(" - GUID = %s\n", debugstr_dmguid(&This->id)); + TRACE(" - Instrument header:\n"); + TRACE(" - cRegions: %ld\n", This->header.cRegions); + TRACE(" - Locale:\n"); + TRACE(" - ulBank: %ld\n", This->header.Locale.ulBank); + TRACE(" - ulInstrument: %ld\n", This->header.Locale.ulInstrument); + TRACE(" => dwPatch: %ld\n", MIDILOCALE2Patch(&This->header.Locale)); + } + + *ret_iface = iface; return S_OK;
error: + IDirectMusicInstrument_Release(iface); + stream_skip_chunk(stream, &chunk); return DMUS_E_UNSUPPORTED_STREAM; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/collection.c | 83 ++++++++++++++++++------------------ dlls/dmusic/dmusic_private.h | 5 --- 2 files changed, 41 insertions(+), 47 deletions(-)
diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c index cca23870f9d..0b4e23b34f4 100644 --- a/dlls/dmusic/collection.c +++ b/dlls/dmusic/collection.c @@ -24,6 +24,12 @@ WINE_DEFAULT_DEBUG_CHANNEL(dmusic); WINE_DECLARE_DEBUG_CHANNEL(dmfile);
+struct instrument_entry +{ + struct list entry; + IDirectMusicInstrument *instrument; +}; + struct collection { IDirectMusicCollection IDirectMusicCollection_iface; @@ -36,8 +42,8 @@ struct collection /* pool table */ POOLTABLE *pPoolTable; POOLCUE *pPoolCues; - /* instruments */ - struct list Instruments; + + struct list instruments; };
static inline struct collection *impl_from_IDirectMusicCollection(IDirectMusicCollection *iface) @@ -103,25 +109,25 @@ static HRESULT WINAPI collection_GetInstrument(IDirectMusicCollection *iface, DWORD patch, IDirectMusicInstrument **instrument) { struct collection *This = impl_from_IDirectMusicCollection(iface); - DMUS_PRIVATE_INSTRUMENTENTRY *inst_entry; - struct list *list_entry; + struct instrument_entry *entry; DWORD inst_patch; + HRESULT hr;
TRACE("(%p, %lu, %p)\n", iface, 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); - TRACE(": returning instrument %p\n", *instrument); + LIST_FOR_EACH_ENTRY(entry, &This->instruments, struct instrument_entry, entry) + { + if (FAILED(hr = IDirectMusicInstrument_GetPatch(entry->instrument, &inst_patch))) return hr; + if (patch == inst_patch) + { + *instrument = entry->instrument; + IDirectMusicInstrument_AddRef(entry->instrument); + TRACE(": returning instrument %p\n", entry->instrument); return S_OK; } }
TRACE(": instrument not found\n"); - return DMUS_E_INVALIDPATCH; }
@@ -129,26 +135,23 @@ static HRESULT WINAPI collection_EnumInstrument(IDirectMusicCollection *iface, DWORD index, DWORD *patch, LPWSTR name, DWORD name_length) { struct collection *This = impl_from_IDirectMusicCollection(iface); - DWORD i = 0; - DMUS_PRIVATE_INSTRUMENTENTRY *inst_entry; - struct list *list_entry; - DWORD length; + struct instrument_entry *entry; + HRESULT hr;
TRACE("(%p, %ld, %p, %p, %ld)\n", iface, 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) { - struct instrument *instrument = impl_from_IDirectMusicInstrument(inst_entry->pInstrument); - IDirectMusicInstrument_GetPatch(inst_entry->pInstrument, patch); - if (name) { - length = min(lstrlenW(instrument->wszName), name_length - 1); - memcpy(name, instrument->wszName, length * sizeof(WCHAR)); - name[length] = '\0'; - } - return S_OK; + LIST_FOR_EACH_ENTRY(entry, &This->instruments, struct instrument_entry, entry) + { + if (index--) continue; + if (FAILED(hr = IDirectMusicInstrument_GetPatch(entry->instrument, patch))) return hr; + if (name) + { + struct instrument *instrument = impl_from_IDirectMusicInstrument(entry->instrument); + DWORD length = min(lstrlenW(instrument->wszName), name_length - 1); + memcpy(name, instrument->wszName, length * sizeof(WCHAR)); + name[length] = '\0'; } - i++; + return S_OK; }
return S_FALSE; @@ -372,12 +375,12 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, ListCount[1] = 0; switch (chunk.fccID) { case FOURCC_INS: { - DMUS_PRIVATE_INSTRUMENTENTRY *entry = calloc(1, sizeof(DMUS_PRIVATE_INSTRUMENTENTRY)); + struct instrument_entry *entry = calloc(1, sizeof(*entry)); TRACE_(dmfile)(": instrument list\n"); liMove.QuadPart = -12; IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); - if (FAILED(instrument_create_from_stream(stream, &entry->pInstrument))) free(entry); - else list_add_tail(&This->Instruments, &entry->entry); + if (FAILED(instrument_create_from_stream(stream, &entry->instrument))) free(entry); + else list_add_tail(&This->instruments, &entry->entry); break; } } @@ -417,10 +420,10 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface,
/* DEBUG: dumps whole collection object tree: */ - if (TRACE_ON(dmusic)) { - int r = 0; - DMUS_PRIVATE_INSTRUMENTENTRY *tmpEntry; - struct list *listEntry; + if (TRACE_ON(dmusic)) + { + struct instrument_entry *entry; + int i = 0;
TRACE("*** IDirectMusicCollection (%p) ***\n", &This->IDirectMusicCollection_iface); dump_DMUS_OBJECTDESC(&This->dmobj.desc); @@ -429,11 +432,8 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, TRACE(" - cInstruments: %ld\n", This->pHeader->cInstruments); 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++; - } + LIST_FOR_EACH_ENTRY(entry, &This->instruments, struct instrument_entry, entry) + TRACE(" - Instrument[%i]: %p\n", i++, entry->instrument); }
return S_OK; @@ -463,8 +463,7 @@ HRESULT collection_create(IUnknown **ret_iface) (IUnknown *)&collection->IDirectMusicCollection_iface); collection->dmobj.IDirectMusicObject_iface.lpVtbl = &collection_object_vtbl; collection->dmobj.IPersistStream_iface.lpVtbl = &collection_stream_vtbl; - - list_init(&collection->Instruments); + list_init(&collection->instruments);
TRACE("Created DirectMusicCollection %p\n", collection); *ret_iface = (IUnknown *)&collection->IDirectMusicCollection_iface; diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index 387c787fd2e..2ae47217ddf 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -161,11 +161,6 @@ struct IReferenceClockImpl { DMUS_CLOCKINFO pClockInfo; };
-typedef struct _DMUS_PRIVATE_INSTRUMENT_ENTRY { - struct list entry; /* for listing elements */ - IDirectMusicInstrument* pInstrument; -} DMUS_PRIVATE_INSTRUMENTENTRY, *LPDMUS_PRIVATE_INSTRUMENTENTRY; - typedef struct _DMUS_PRIVATE_POOLCUE { struct list entry; /* for listing elements */ } DMUS_PRIVATE_POOLCUE, *LPDMUS_PRIVATE_POOLCUE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/collection.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c index 0b4e23b34f4..2d4a7f855ae 100644 --- a/dlls/dmusic/collection.c +++ b/dlls/dmusic/collection.c @@ -98,7 +98,18 @@ static ULONG WINAPI collection_Release(IDirectMusicCollection *iface)
TRACE("(%p): new ref = %lu\n", iface, ref);
- if (!ref) { + if (!ref) + { + struct instrument_entry *instrument_entry; + void *next; + + LIST_FOR_EACH_ENTRY_SAFE(instrument_entry, next, &This->instruments, struct instrument_entry, entry) + { + list_remove(&instrument_entry->entry); + IDirectMusicInstrument_Release(instrument_entry->instrument); + free(instrument_entry); + } + free(This); }
This merge request was approved by Michael Stefaniuc.