[PATCH 2/6] dmusic: Reimplement ParseDescriptor() for DirectMusicCollection

Michael Stefaniuc mstefani at winehq.org
Sun Jul 15 14:08:44 CDT 2018


Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
 dlls/dmusic/collection.c   | 208 ++++-----------------------------------------
 dlls/dmusic/tests/dmusic.c |  18 ++--
 2 files changed, 28 insertions(+), 198 deletions(-)

diff --git a/dlls/dmusic/collection.c b/dlls/dmusic/collection.c
index ec9914faa1..28202228bc 100644
--- a/dlls/dmusic/collection.c
+++ b/dlls/dmusic/collection.c
@@ -176,210 +176,34 @@ static const IDirectMusicCollectionVtbl DirectMusicCollection_Collection_Vtbl =
 };
 
 /* IDirectMusicCollectionImpl IDirectMusicObject part: */
-static HRESULT read_from_stream(IStream *stream, void *data, ULONG size)
-{
-    ULONG read;
-    HRESULT hr;
-
-    hr = IStream_Read(stream, data, size, &read);
-    if (FAILED(hr)) {
-        TRACE("IStream_Read failed: %08x\n", hr);
-        return hr;
-    }
-    if (read < size) {
-        TRACE("Didn't read full chunk: %u < %u\n", read, size);
-        return E_FAIL;
-    }
-
-    return S_OK;
-}
-
-static HRESULT WINAPI IDirectMusicObjectImpl_ParseDescriptor(IDirectMusicObject *iface,
+static HRESULT WINAPI col_IDirectMusicObject_ParseDescriptor(IDirectMusicObject *iface,
         IStream *stream, DMUS_OBJECTDESC *desc)
 {
-    struct dmobject *This = impl_from_IDirectMusicObject(iface);
-    DMUS_PRIVATE_CHUNK chunk;
-    DWORD StreamSize, StreamCount, ListSize[1], ListCount[1];
-    LARGE_INTEGER liMove; /* used when skipping chunks */
+    struct chunk_entry riff = {0};
     HRESULT hr;
 
-    TRACE("(%p)->(%p, %p)\n", This, stream, desc);
+    TRACE("(%p, %p, %p)\n", iface, stream, desc);
 
-    /* FIXME: should this be determined from stream? */
-    desc->dwValidData |= DMUS_OBJ_CLASS;
-    desc->guidClass = This->desc.guidClass;
+    if (!stream || !desc)
+        return E_POINTER;
 
-    hr = read_from_stream(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD));
-    if (FAILED(hr))
+    if ((hr = stream_get_chunk(stream, &riff)) != S_OK)
         return hr;
-    TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
-
-    if (chunk.fccID != FOURCC_RIFF) {
-        TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
-        liMove.QuadPart = chunk.dwSize;
-        IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
-        return DMUS_E_INVALIDFILE;
+    if (riff.id != FOURCC_RIFF || riff.type != FOURCC_DLS) {
+        TRACE("loading failed: unexpected %s\n", debugstr_chunk(&riff));
+        stream_skip_chunk(stream, &riff);
+        return DMUS_E_NOTADLSCOL;
     }
 
-    hr = read_from_stream(stream, &chunk.fccID, sizeof(FOURCC));
+    hr = dmobj_parsedescriptor(stream, &riff, desc, DMUS_OBJ_NAME_INFO|DMUS_OBJ_VERSION);
     if (FAILED(hr))
         return hr;
-    TRACE_(dmfile)(": RIFF chunk of type %s", debugstr_fourcc(chunk.fccID));
-    StreamSize = chunk.dwSize - sizeof(FOURCC);
-
-    if (chunk.fccID != FOURCC_DLS) {
-        TRACE_(dmfile)(": unexpected chunk; loading failed)\n");
-        liMove.QuadPart = StreamSize;
-        IStream_Seek(stream, liMove, STREAM_SEEK_CUR, NULL); /* skip the rest of the chunk */
-        return E_FAIL;
-    }
-
-    StreamCount = 0;
-    TRACE_(dmfile)(": collection form\n");
-
-    do {
-        hr = read_from_stream(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD));
-        if (FAILED(hr))
-            return hr;
-        StreamCount += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
-        TRACE_(dmfile)(": %s chunk (size = 0x%04x)", debugstr_fourcc(chunk.fccID), chunk.dwSize);
-        switch (chunk.fccID) {
-            case FOURCC_DLID:
-                TRACE_(dmfile)(": GUID chunk\n");
-                desc->dwValidData |= DMUS_OBJ_OBJECT;
-                hr = read_from_stream(stream, &desc->guidObject, chunk.dwSize);
-                if (FAILED(hr))
-                    return hr;
-                break;
-
-            case DMUS_FOURCC_VERSION_CHUNK:
-                TRACE_(dmfile)(": version chunk\n");
-                desc->dwValidData |= DMUS_OBJ_VERSION;
-                hr = read_from_stream(stream, &desc->vVersion, chunk.dwSize);
-                if (FAILED(hr))
-                    return hr;
-                break;
-
-            case DMUS_FOURCC_CATEGORY_CHUNK:
-                TRACE_(dmfile)(": category chunk\n");
-                desc->dwValidData |= DMUS_OBJ_CATEGORY;
-                hr = read_from_stream(stream, desc->wszCategory, chunk.dwSize);
-                if (FAILED(hr))
-                    return hr;
-                break;
-
-            case FOURCC_LIST:
-                hr = read_from_stream(stream, &chunk.fccID, sizeof(FOURCC));
-                if (FAILED(hr))
-                    return hr;
-                TRACE_(dmfile)(": LIST chunk of type %s", debugstr_fourcc(chunk.fccID));
-                ListSize[0] = chunk.dwSize - sizeof(FOURCC);
-                ListCount[0] = 0;
-                switch (chunk.fccID) {
-                    /* pure INFO list, such can be found in dls collections */
-                    case DMUS_FOURCC_INFO_LIST:
-                        TRACE_(dmfile)(": INFO list\n");
-                        do {
-                            hr = read_from_stream(stream, &chunk, sizeof(FOURCC) + sizeof(DWORD));
-                            if (FAILED(hr))
-                                return hr;
-                            ListCount[0] += sizeof(FOURCC) + sizeof(DWORD) + chunk.dwSize;
-                            TRACE_(dmfile)(": %s chunk (size = 0x%04x)", 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");
-                                    desc->dwValidData |= DMUS_OBJ_NAME;
-                                    hr = read_from_stream(stream, szName, chunk.dwSize);
-                                    if (FAILED(hr))
-                                        return hr;
-                                    MultiByteToWideChar (CP_ACP, 0, szName, -1, 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 (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','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] = %d < ListSize[0] = %d\n", ListCount[0], ListSize[0]);
-                         } while (ListCount[0] < ListSize[0]);
-                         break;
-
-                     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)(": StreamCount[0] = %d < StreamSize[0] = %d\n", StreamCount, StreamSize);
-    } while (StreamCount < StreamSize);
-
-    TRACE_(dmfile)(": reading finished\n");
-
-    if (TRACE_ON(dmusic)) {
-        TRACE("Returning descriptor:\n");
-        dump_DMUS_OBJECTDESC(desc);
-    }
+    desc->guidClass = CLSID_DirectMusicCollection;
+    desc->dwValidData |= DMUS_OBJ_CLASS;
 
+    TRACE("returning descriptor:\n");
+    dump_DMUS_OBJECTDESC(desc);
     return S_OK;
 }
 
@@ -389,7 +213,7 @@ static const IDirectMusicObjectVtbl dmobject_vtbl = {
     dmobj_IDirectMusicObject_Release,
     dmobj_IDirectMusicObject_GetDescriptor,
     dmobj_IDirectMusicObject_SetDescriptor,
-    IDirectMusicObjectImpl_ParseDescriptor
+    col_IDirectMusicObject_ParseDescriptor
 };
 
 /* IDirectMusicCollectionImpl IPersistStream part: */
diff --git a/dlls/dmusic/tests/dmusic.c b/dlls/dmusic/tests/dmusic.c
index e69de25e9f..19890d17dc 100644
--- a/dlls/dmusic/tests/dmusic.c
+++ b/dlls/dmusic/tests/dmusic.c
@@ -627,7 +627,7 @@ static IStream *gen_riff_stream(const FOURCC *ids)
                 ck->size = 5;
                 p += CHUNK_HDR_SIZE;
                 strcpy(p, "INAM");
-                p += ck->size;
+                p += ck->size + 1; /* WORD aligned */
                 break;
             default:
             {
@@ -700,7 +700,7 @@ static void test_parsedescriptor(void)
     stream = gen_riff_stream(empty);
     memset(&desc, 0, sizeof(desc));
     hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
-    todo_wine ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
+    ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
     ok(desc.dwValidData == DMUS_OBJ_CLASS, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
             desc.dwValidData);
     ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicCollection),
@@ -708,19 +708,25 @@ static void test_parsedescriptor(void)
             wine_dbgstr_guid(&desc.guidClass));
     IStream_Release(stream);
 
+    /* NULL pointers */
+    memset(&desc, 0, sizeof(desc));
+    hr = IDirectMusicObject_ParseDescriptor(dmo, NULL, &desc);
+    ok(hr == E_POINTER, "ParseDescriptor failed: %08x, expected E_POINTER\n", hr);
+    hr = IDirectMusicObject_ParseDescriptor(dmo, stream, NULL);
+    ok(hr == E_POINTER, "ParseDescriptor failed: %08x, expected E_POINTER\n", hr);
+
     /* Wrong form */
     empty[1] = DMUS_FOURCC_CONTAINER_FORM;
     stream = gen_riff_stream(empty);
     hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
-    todo_wine ok(hr == DMUS_E_NOTADLSCOL,
-            "ParseDescriptor failed: %08x, expected DMUS_E_NOTADLSCOL\n", hr);
+    ok(hr == DMUS_E_NOTADLSCOL, "ParseDescriptor failed: %08x, expected DMUS_E_NOTADLSCOL\n", hr);
 
     /* All desc chunks */
     stream = gen_riff_stream(alldesc);
     memset(&desc, 0, sizeof(desc));
     hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
     ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
-    todo_wine ok(desc.dwValidData == (DMUS_OBJ_CLASS | DMUS_OBJ_VERSION),
+    ok(desc.dwValidData == (DMUS_OBJ_CLASS | DMUS_OBJ_VERSION),
             "Got valid data %#x, expected DMUS_OBJ_CLASS | DMUS_OBJ_VERSION\n", desc.dwValidData);
     ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicCollection),
             "Got class guid %s, expected CLSID_DirectMusicCollection\n",
@@ -759,7 +765,7 @@ static void test_parsedescriptor(void)
     memset(&desc, 0, sizeof(desc));
     hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
     ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
-    todo_wine ok(desc.dwValidData == (DMUS_OBJ_CLASS | DMUS_OBJ_NAME | DMUS_OBJ_VERSION),
+    ok(desc.dwValidData == (DMUS_OBJ_CLASS | DMUS_OBJ_NAME | DMUS_OBJ_VERSION),
             "Got valid data %#x, expected DMUS_OBJ_CLASS | DMUS_OBJ_NAME | DMUS_OBJ_VERSION\n",
             desc.dwValidData);
     ok(!memcmp(desc.wszName, s_inam, sizeof(s_inam)), "Got name '%s', expected 'INAM'\n",
-- 
2.14.4




More information about the wine-devel mailing list