From: Rémi Bernon rbernon@codeweavers.com
--- dlls/dmusic/collection.c | 82 +++--------------------------------- dlls/dmusic/dmobject.c | 50 +++++++++++++++------- dlls/dmusic/dmobject.h | 2 + dlls/dmusic/dmusic_main.c | 5 --- dlls/dmusic/dmusic_private.h | 2 - 5 files changed, 44 insertions(+), 97 deletions(-)
diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c index acd85768cec..f64e8de258f 100644 --- a/dlls/dmusic/collection.c +++ b/dlls/dmusic/collection.c @@ -250,7 +250,7 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, { struct collection *This = impl_from_IPersistStream(iface); DMUS_PRIVATE_CHUNK chunk; - DWORD StreamSize, StreamCount, ListSize[2], ListCount[2]; + DWORD StreamSize, StreamCount; LARGE_INTEGER liMove; /* used when skipping chunks */
IStream_AddRef(stream); /* add count for later references */ @@ -314,83 +314,15 @@ static HRESULT WINAPI collection_stream_Load(IPersistStream *iface, case FOURCC_LIST: { IStream_Read(stream, &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 DMUS_FOURCC_INFO_LIST: { + struct chunk_entry info_chunk = {.id = FOURCC_LIST, .size = chunk.dwSize, .type = chunk.fccID}; TRACE_(dmfile)(": INFO list\n"); - do { - IStream_Read(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD), NULL); - ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize; - TRACE_(dmfile)(": %s chunk (size = %#04lx)", 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"); - This->dmobj.desc.dwValidData |= DMUS_OBJ_NAME; - IStream_Read(stream, szName, chunk.dwSize, NULL); - MultiByteToWideChar(CP_ACP, 0, szName, -1, This->dmobj.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\n"); - This->szCopyright = calloc(1, chunk.dwSize); - IStream_Read(stream, This->szCopyright, chunk.dwSize, NULL); - if (even_or_odd(chunk.dwSize)) { - ListCount[0]++; - liMove.QuadPart = 1; - 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] = %ld < ListSize[0] = %ld\n", ListCount[0], ListSize[0]); - } while (ListCount[0] < ListSize[0]); + liMove.QuadPart = 0; + IStream_Seek(stream, liMove, STREAM_SEEK_CUR, &info_chunk.offset); + info_chunk.offset.QuadPart -= 12; + stream_chunk_parse_info_list(stream, &info_chunk, &This->dmobj.desc); + stream_skip_chunk(stream, &info_chunk); break; } case FOURCC_WVPL: { diff --git a/dlls/dmusic/dmobject.c b/dlls/dmusic/dmobject.c index 2bef5511851..5bf856e2a04 100644 --- a/dlls/dmusic/dmobject.c +++ b/dlls/dmusic/dmobject.c @@ -528,24 +528,44 @@ HRESULT WINAPI dmobj_IDirectMusicObject_SetDescriptor(IDirectMusicObject *iface, return ret; }
-/* Helper for IDirectMusicObject::ParseDescriptor */ -static inline void info_get_name(IStream *stream, const struct chunk_entry *info, - DMUS_OBJECTDESC *desc) +HRESULT stream_chunk_parse_info_list(IStream *stream, const struct chunk_entry *parent, DMUS_OBJECTDESC *desc) { - struct chunk_entry chunk = {.parent = info}; - char name[DMUS_MAX_NAME]; - ULONG len; - HRESULT hr = E_FAIL; + struct chunk_entry chunk = {.parent = parent}; + char *buffer; + HRESULT hr;
- while (stream_next_chunk(stream, &chunk) == S_OK) - if (chunk.id == mmioFOURCC('I','N','A','M')) - hr = IStream_Read(stream, name, min(chunk.size, sizeof(name)), &len); + while ((hr = stream_next_chunk(stream, &chunk)) == S_OK) + { + switch (MAKE_IDTYPE(chunk.id, chunk.type)) + { + case mmioFOURCC('I','N','A','M'): + if (desc->dwValidData & DMUS_OBJ_NAME) continue; + if (!(buffer = malloc(chunk.size))) return E_OUTOFMEMORY; + if ((hr = stream_chunk_get_data(stream, &chunk, buffer, chunk.size)) == S_OK) + { + DWORD len = MultiByteToWideChar(CP_ACP, 0, buffer, chunk.size, + desc->wszName, ARRAY_SIZE(desc->wszName)); + desc->wszName[min(len, sizeof(desc->wszName) - 1)] = 0; + desc->dwValidData |= DMUS_OBJ_NAME; + } + free(buffer); + break; + + case mmioFOURCC('I','C','O','P'): + case mmioFOURCC('I','E','N','G'): + case mmioFOURCC('I','S','B','J'): + case mmioFOURCC('I','S','F','T'): + break; + + default: + FIXME("Ignoring chunk %s %s\n", debugstr_fourcc(chunk.id), debugstr_fourcc(chunk.type)); + break; + }
- if (SUCCEEDED(hr)) { - len = MultiByteToWideChar(CP_ACP, 0, name, len, desc->wszName, sizeof(desc->wszName)); - desc->wszName[min(len, sizeof(desc->wszName) - 1)] = 0; - desc->dwValidData |= DMUS_OBJ_NAME; + if (FAILED(hr)) break; } + + return hr; }
static inline void unfo_get_name(IStream *stream, const struct chunk_entry *unfo, @@ -606,7 +626,7 @@ HRESULT dmobj_parsedescriptor(IStream *stream, const struct chunk_entry *riff, if (chunk.type == DMUS_FOURCC_UNFO_LIST && (supported & DMUS_OBJ_NAME)) unfo_get_name(stream, &chunk, desc, supported & DMUS_OBJ_NAME_INAM); else if (chunk.type == DMUS_FOURCC_INFO_LIST && (supported & DMUS_OBJ_NAME_INFO)) - info_get_name(stream, &chunk, desc); + stream_chunk_parse_info_list(stream, &chunk, desc); break; } } diff --git a/dlls/dmusic/dmobject.h b/dlls/dmusic/dmobject.h index 98069de8cc4..8aed294c43c 100644 --- a/dlls/dmusic/dmobject.h +++ b/dlls/dmusic/dmobject.h @@ -44,6 +44,8 @@ HRESULT stream_chunk_get_data(IStream *stream, const struct chunk_entry *chunk, HRESULT stream_chunk_get_wstr(IStream *stream, const struct chunk_entry *chunk, WCHAR *str, ULONG size);
+HRESULT stream_chunk_parse_info_list(IStream *stream, const struct chunk_entry *parent, DMUS_OBJECTDESC *desc); + static inline HRESULT stream_reset_chunk_data(IStream *stream, const struct chunk_entry *chunk) { LARGE_INTEGER offset; diff --git a/dlls/dmusic/dmusic_main.c b/dlls/dmusic/dmusic_main.c index 52607e1d936..eabf9f131b9 100644 --- a/dlls/dmusic/dmusic_main.c +++ b/dlls/dmusic/dmusic_main.c @@ -165,11 +165,6 @@ void Patch2MIDILOCALE (DWORD dwPatch, LPMIDILOCALE pLocale) { pLocale->ulBank |= (dwPatch & F_INSTRUMENT_DRUMS); /* get drum bit */ }
-/* check whether the given DWORD is even (return 0) or odd (return 1) */ -int even_or_odd (DWORD number) { - return (number & 0x1); /* basically, check if bit 0 is set ;) */ -} - /* generic flag-dumping function */ static const char* debugstr_flags (DWORD flags, const flag_info* names, size_t num_names){ char buffer[128] = "", *ptr = &buffer[0]; diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h index fe2cbaef9b8..bb5c8ce44c6 100644 --- a/dlls/dmusic/dmusic_private.h +++ b/dlls/dmusic/dmusic_private.h @@ -211,8 +211,6 @@ extern DWORD MIDILOCALE2Patch (const MIDILOCALE *pLocale); /* MIDILOCALE from dwPatch */ extern void Patch2MIDILOCALE (DWORD dwPatch, LPMIDILOCALE pLocale);
-/* check whether the given DWORD is even (return 0) or odd (return 1) */ -extern int even_or_odd (DWORD number); /* Dump whole DMUS_PORTPARAMS struct */ extern void dump_DMUS_PORTPARAMS(LPDMUS_PORTPARAMS params);