Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
v2: Clear desc before calling GetDescriptor()
dlls/dmime/tests/dmime.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 222 insertions(+)
diff --git a/dlls/dmime/tests/dmime.c b/dlls/dmime/tests/dmime.c
index 62a977eeb7..b7b8095725 100644
--- a/dlls/dmime/tests/dmime.c
+++ b/dlls/dmime/tests/dmime.c
@@ -21,7 +21,9 @@
#include <stdarg.h>
#include <windef.h>
#include <wine/test.h>
+#include <ole2.h>
#include <dmusici.h>
+#include <dmusicf.h>
#include <audioclient.h>
#include <guiddef.h>
@@ -617,6 +619,225 @@ static void test_track(void)
}
}
+struct chunk {
+ FOURCC id;
+ DWORD size;
+ FOURCC type;
+};
+
+#define CHUNK_HDR_SIZE (sizeof(FOURCC) + sizeof(DWORD))
+
+/* Generate a RIFF file format stream from an array of FOURCC ids.
+ RIFF and LIST need to be followed by the form type respectively list type,
+ followed by the chunks of the list and terminated with 0. */
+static IStream *gen_riff_stream(const FOURCC *ids)
+{
+ static const LARGE_INTEGER zero;
+ int level = -1;
+ DWORD *sizes[4]; /* Stack for the sizes of RIFF and LIST chunks */
+ char riff[1024];
+ char *p = riff;
+ struct chunk *ck;
+ IStream *stream;
+
+ do {
+ ck = (struct chunk *)p;
+ ck->id = *ids++;
+ switch (ck->id) {
+ case 0:
+ *sizes[level] = p - (char *)sizes[level] - sizeof(DWORD);
+ level--;
+ break;
+ case FOURCC_LIST:
+ case FOURCC_RIFF:
+ level++;
+ sizes[level] = &ck->size;
+ ck->type = *ids++;
+ p += sizeof(*ck);
+ break;
+ case DMUS_FOURCC_GUID_CHUNK:
+ ck->size = sizeof(GUID_NULL);
+ p += CHUNK_HDR_SIZE;
+ memcpy(p, &GUID_NULL, sizeof(GUID_NULL));
+ p += ck->size;
+ break;
+ case DMUS_FOURCC_VERSION_CHUNK:
+ {
+ DMUS_VERSION ver = {5, 8};
+
+ ck->size = sizeof(ver);
+ p += CHUNK_HDR_SIZE;
+ memcpy(p, &ver, sizeof(ver));
+ p += ck->size;
+ break;
+ }
+ default:
+ {
+ /* Just convert the FOURCC id to a WCHAR string */
+ WCHAR *s;
+
+ ck->size = 5 * sizeof(WCHAR);
+ p += CHUNK_HDR_SIZE;
+ s = (WCHAR *)p;
+ s[0] = (char)(ck->id);
+ s[1] = (char)(ck->id >> 8);
+ s[2] = (char)(ck->id >> 16);
+ s[3] = (char)(ck->id >> 24);
+ s[4] = 0;
+ p += ck->size;
+ }
+ }
+ } while (level >= 0);
+
+ ck = (struct chunk *)riff;
+ CreateStreamOnHGlobal(NULL, TRUE, &stream);
+ IStream_Write(stream, riff, ck->size + CHUNK_HDR_SIZE, NULL);
+ IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
+
+ return stream;
+}
+
+static void test_parsedescriptor(void)
+{
+ IDirectMusicObject *dmo;
+ IStream *stream;
+ DMUS_OBJECTDESC desc;
+ HRESULT hr;
+ DWORD valid;
+ unsigned int i;
+ const WCHAR s_unam[] = {'U','N','A','M','\0'};
+ const WCHAR s_inam[] = {'I','\0'};
+ /* fourcc ~0 will be replaced later on */
+ FOURCC alldesc[] =
+ {
+ FOURCC_RIFF, ~0, DMUS_FOURCC_CATEGORY_CHUNK, FOURCC_LIST, DMUS_FOURCC_UNFO_LIST,
+ DMUS_FOURCC_UNAM_CHUNK, DMUS_FOURCC_UCOP_CHUNK, DMUS_FOURCC_UCMT_CHUNK,
+ DMUS_FOURCC_USBJ_CHUNK, 0, DMUS_FOURCC_VERSION_CHUNK, DMUS_FOURCC_GUID_CHUNK, 0
+ };
+ FOURCC dupes[] =
+ {
+ FOURCC_RIFF, ~0, DMUS_FOURCC_CATEGORY_CHUNK, DMUS_FOURCC_CATEGORY_CHUNK,
+ DMUS_FOURCC_VERSION_CHUNK, DMUS_FOURCC_VERSION_CHUNK, DMUS_FOURCC_GUID_CHUNK,
+ DMUS_FOURCC_GUID_CHUNK, FOURCC_LIST, DMUS_FOURCC_UNFO_LIST, DMUS_FOURCC_UNAM_CHUNK, 0,
+ FOURCC_LIST, DMUS_FOURCC_UNFO_LIST, mmioFOURCC('I','N','A','M'), 0, 0
+ };
+ FOURCC empty[] = {FOURCC_RIFF, ~0, 0};
+ FOURCC inam[] = {FOURCC_RIFF, ~0, FOURCC_LIST, ~0, mmioFOURCC('I','N','A','M'), 0, 0};
+#define X(form) form, #form
+ const struct {
+ FOURCC form;
+ const char *name;
+ } forms[] = {
+ { X(DMUS_FOURCC_SEGMENT_FORM) },
+ { X(mmioFOURCC('W','A','V','E')) },
+ };
+#undef X
+
+ hr = CoCreateInstance(&CLSID_DirectMusicSegment, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IDirectMusicObject, (void **)&dmo);
+ if (hr != S_OK) {
+ win_skip("Could not create DirectMusicSegment object: %08x\n", hr);
+ return;
+ }
+ for (i = 0; i < ARRAY_SIZE(forms); i++) {
+ trace("Testing %s\n", forms[i].name);
+
+ /* Nothing loaded */
+ memset(&desc, 0, sizeof(desc));
+ hr = IDirectMusicObject_GetDescriptor(dmo, &desc);
+ ok(hr == S_OK, "GetDescriptor 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_DirectMusicSegment),
+ "Got class guid %s, expected CLSID_DirectMusicSegment\n",
+ wine_dbgstr_guid(&desc.guidClass));
+
+ /* Empty RIFF stream */
+ empty[1] = forms[i].form;
+ stream = gen_riff_stream(empty);
+ memset(&desc, 0, sizeof(desc));
+ hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
+ 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_DirectMusicSegment),
+ "Got class guid %s, expected CLSID_DirectMusicSegment\n",
+ wine_dbgstr_guid(&desc.guidClass));
+ IStream_Release(stream);
+
+ /* Wrong form */
+ empty[1] = DMUS_FOURCC_CONTAINER_FORM;
+ stream = gen_riff_stream(empty);
+ memset(&desc, 0, sizeof(desc));
+ hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
+ ok(hr == E_FAIL, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
+ todo_wine ok(!desc.dwValidData, "Got valid data %#x, expected 0\n", desc.dwValidData);
+
+ /* All desc chunks */
+ alldesc[1] = forms[i].form;
+ 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);
+ valid = DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS | DMUS_OBJ_VERSION;
+ if (forms[i].form == DMUS_FOURCC_SEGMENT_FORM)
+ valid |= DMUS_OBJ_NAME | DMUS_OBJ_CATEGORY;
+ todo_wine_if(forms[i].form == mmioFOURCC('W','A','V','E'))
+ ok(desc.dwValidData == valid, "Got valid data %#x, expected %#x\n", desc.dwValidData,
+ valid);
+ ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicSegment),
+ "Got class guid %s, expected %s\n", wine_dbgstr_guid(&desc.guidClass),
+ wine_dbgstr_guid(&CLSID_DirectMusicSegment));
+ ok(IsEqualGUID(&desc.guidObject, &GUID_NULL), "Got object guid %s, expected GUID_NULL\n",
+ wine_dbgstr_guid(&desc.guidClass));
+ if (forms[i].form == DMUS_FOURCC_SEGMENT_FORM)
+ ok(!memcmp(desc.wszName, s_unam, sizeof(s_unam)), "Got name '%s', expected 'UNAM'\n",
+ wine_dbgstr_w(desc.wszName));
+ IStream_Release(stream);
+
+ /* Duplicated chunks */
+ dupes[1] = forms[i].form;
+ stream = gen_riff_stream(dupes);
+ 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_if(forms[i].form == mmioFOURCC('W','A','V','E'))
+ ok(desc.dwValidData == valid, "Got valid data %#x, expected %#x\n", desc.dwValidData,
+ valid);
+ IStream_Release(stream);
+
+ /* UNFO list with INAM */
+ inam[1] = forms[i].form;
+ inam[3] = DMUS_FOURCC_UNFO_LIST;
+ stream = gen_riff_stream(inam);
+ 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_if(forms[i].form == DMUS_FOURCC_SEGMENT_FORM)
+ ok(desc.dwValidData == DMUS_OBJ_CLASS, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
+ desc.dwValidData);
+ IStream_Release(stream);
+
+ /* INFO list with INAM */
+ inam[3] = DMUS_FOURCC_INFO_LIST;
+ stream = gen_riff_stream(inam);
+ memset(&desc, 0, sizeof(desc));
+ hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
+ ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
+ valid = DMUS_OBJ_CLASS;
+ if (forms[i].form == mmioFOURCC('W','A','V','E'))
+ valid |= DMUS_OBJ_NAME;
+ todo_wine_if(forms[i].form == mmioFOURCC('W','A','V','E'))
+ ok(desc.dwValidData == valid, "Got valid data %#x, expected %#x\n", desc.dwValidData,
+ valid);
+ if (forms[i].form == mmioFOURCC('W','A','V','E'))
+ todo_wine ok(!memcmp(desc.wszName, s_inam, sizeof(s_inam)),
+ "Got name '%s', expected 'I'\n", wine_dbgstr_w(desc.wszName));
+ IStream_Release(stream);
+ }
+ IDirectMusicObject_Release(dmo);
+}
+
START_TEST(dmime)
{
CoInitialize(NULL);
@@ -637,6 +858,7 @@ START_TEST(dmime)
test_graph();
test_segment();
test_track();
+ test_parsedescriptor();
CoUninitialize();
}
--
2.14.3