From: Michael Stefaniuc mstefani@winehq.org
Not documented in the official headers but multiple pre-DX8 games have the DMUS_IO_STYLEPART without the dwFlags.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58493 --- dlls/dmstyle/style.c | 9 ++++++++- include/dmusicf.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/dmstyle/style.c b/dlls/dmstyle/style.c index c64e7e3d525..baf2cb22e7c 100644 --- a/dlls/dmstyle/style.c +++ b/dlls/dmstyle/style.c @@ -482,7 +482,14 @@ static HRESULT parse_part_list(struct style *This, IStream *stream, struct chunk switch (MAKE_IDTYPE(chunk.id, chunk.type)) { case DMUS_FOURCC_PART_CHUNK: - hr = stream_chunk_get_data(stream, &chunk, &part->header, sizeof(part->header)); + if (chunk.size != sizeof(part->header) && + chunk.size != ((offsetof(DMUS_IO_STYLEPART, bPad) + 1 ) & ~1)) /* DX7 */ + { + WARN("Invalid size of %s\n", debugstr_chunk(&chunk)); + hr = E_FAIL; + break; + } + hr = stream_chunk_get_data(stream, &chunk, &part->header, chunk.size); break;
case MAKE_IDTYPE(FOURCC_LIST, DMUS_FOURCC_UNFO_LIST): diff --git a/include/dmusicf.h b/include/dmusicf.h index da8363c4b04..24b8c585bfe 100644 --- a/include/dmusicf.h +++ b/include/dmusicf.h @@ -516,6 +516,7 @@ struct _DMUS_IO_STYLEPART { BYTE bPlayModeFlags; BYTE bInvertUpper; BYTE bInvertLower; + /* DX8 */ BYTE bPad[3]; DWORD dwFlags; };
From: Michael Stefaniuc mstefani@winehq.org
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=58493 --- dlls/dmstyle/style.c | 8 ++++---- dlls/dmusic/dmobject.c | 30 ++++++++++++++++++++++-------- dlls/dmusic/dmobject.h | 2 ++ 3 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/dlls/dmstyle/style.c b/dlls/dmstyle/style.c index baf2cb22e7c..5ae41198643 100644 --- a/dlls/dmstyle/style.c +++ b/dlls/dmstyle/style.c @@ -497,13 +497,13 @@ static HRESULT parse_part_list(struct style *This, IStream *stream, struct chunk break;
case DMUS_FOURCC_NOTE_CHUNK: - hr = stream_chunk_get_array(stream, &chunk, (void **)&part->notes, - &part->notes_count, sizeof(*part->notes)); + hr = stream_chunk_get_array_alt(stream, &chunk, (void **)&part->notes, + &part->notes_count, sizeof(*part->notes), offsetof(DMUS_IO_STYLENOTE, bNoteFlags)); break;
case DMUS_FOURCC_CURVE_CHUNK: - hr = stream_chunk_get_array(stream, &chunk, (void **)&part->curves, - &part->curves_count, sizeof(*part->curves)); + hr = stream_chunk_get_array_alt(stream, &chunk, (void **)&part->curves, + &part->curves_count, sizeof(*part->curves), offsetof(DMUS_IO_STYLECURVE, wParamType)); break;
case DMUS_FOURCC_MARKER_CHUNK: diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index 9ba1f239167..03ee9bd41bf 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -375,10 +375,12 @@ HRESULT stream_next_chunk(IStream *stream, struct chunk_entry *chunk) element[] - Array of elements The caller needs to free() the array. */ -HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, - unsigned int *count, DWORD elem_size) +HRESULT stream_chunk_get_array_alt(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size, DWORD alt_size) { DWORD size; + unsigned int i; + void *p; HRESULT hr;
*array = NULL; @@ -390,23 +392,29 @@ HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, } if (FAILED(hr = stream_read(stream, &size, sizeof(DWORD)))) return hr; - if (size != elem_size) { + if (!(size == elem_size || (alt_size && size == alt_size))) { WARN_(dmfile)("%s: Array element size mismatch: got %lu, expected %lu\n", debugstr_chunk(chunk), size, elem_size); return DMUS_E_UNSUPPORTED_STREAM; }
- *count = (chunk->size - sizeof(DWORD)) / elem_size; - size = *count * elem_size; - if (!(*array = malloc(size))) + *count = (chunk->size - sizeof(DWORD)) / size; + if (!(*array = calloc(*count, elem_size))) return E_OUTOFMEMORY; - if (FAILED(hr = stream_read(stream, *array, size))) { + if (size == elem_size) + hr = stream_read(stream, *array, *count * elem_size); + else + for (i = 0, p = *array; i < *count; i++, p = (char *)p + elem_size) + if (FAILED(hr = stream_read(stream, p, size))) + break; + + if (FAILED(hr)) { free(*array); *array = NULL; return hr; }
- if (chunk->size > size + sizeof(DWORD)) { + if (chunk->size > *count * size + sizeof(DWORD)) { WARN_(dmfile)("%s: Extraneous data at end of array\n", debugstr_chunk(chunk)); stream_skip_chunk(stream, chunk); return S_FALSE; @@ -414,6 +422,12 @@ HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, return S_OK; }
+HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size) +{ + return stream_chunk_get_array_alt(stream, chunk, array, count, elem_size, 0); +} + HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size) { diff --git a/dlls/dmusic/dmobject.h b/dlls/dmusic/dmobject.h index bab96c77724..f2f3ab5215d 100644 --- a/dlls/dmusic/dmobject.h +++ b/dlls/dmusic/dmobject.h @@ -39,6 +39,8 @@ HRESULT stream_skip_chunk(IStream *stream, const struct chunk_entry *chunk);
HRESULT stream_chunk_get_array(IStream *stream, const struct chunk_entry *chunk, void **array, unsigned int *count, DWORD elem_size); +HRESULT stream_chunk_get_array_alt(IStream *stream, const struct chunk_entry *chunk, void **array, + unsigned int *count, DWORD elem_size, DWORD alt_size); HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, void *data, ULONG size); HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str,