From 9e74cdc6397a79e7ca671eab5b3ac9393455077b Mon Sep 17 00:00:00 2001 From: Michael Stefaniuc Date: Tue, 6 Mar 2018 01:07:26 +0100 Subject: [PATCH] dmloader/tests: Add IDirectMusicObject::ParseDescriptor() tests. Signed-off-by: Michael Stefaniuc Signed-off-by: Alexandre Julliard --- dlls/dmloader/tests/loader.c | 204 +++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/dlls/dmloader/tests/loader.c b/dlls/dmloader/tests/loader.c index ff084b6e4b7..46e46d4baf4 100644 --- a/dlls/dmloader/tests/loader.c +++ b/dlls/dmloader/tests/loader.c @@ -19,11 +19,14 @@ #define COBJMACROS #include "initguid.h" +#include #include "dmusici.h" +#include #include "wine/test.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); static unsigned char mp3file[] = "\xFF\xFB\x92\x04"; /* MP3 header */ static unsigned char rifffile[8+4+8+16+8+256] = "RIFF\x24\x01\x00\x00WAVE" /* header: 4 ("WAVE") + (8 + 16) (format segment) + (8 + 256) (data segment) = 0x124 */ "fmt \x10\x00\x00\x00\x01\x00\x20\x00\xAC\x44\x00\x00\x10\xB1\x02\x00\x04\x00\x10\x00" /* format segment: PCM, 2 chan, 44100 Hz, 16 bits */ @@ -391,6 +394,205 @@ static void test_container(void) while (IDirectMusicContainer_Release(dmc)); } +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; + const WCHAR s_unam[] = {'U','N','A','M','\0'}; + const FOURCC alldesc[] = + { + FOURCC_RIFF, DMUS_FOURCC_CONTAINER_FORM, 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 + }; + const FOURCC dupes[] = + { + FOURCC_RIFF, DMUS_FOURCC_CONTAINER_FORM, 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, DMUS_FOURCC_CONTAINER_FORM, 0}; + FOURCC inam[] = + { + FOURCC_RIFF, DMUS_FOURCC_CONTAINER_FORM, FOURCC_LIST, DMUS_FOURCC_UNFO_LIST, + mmioFOURCC('I','N','A','M'), 0, 0 + }; + + hr = CoCreateInstance(&CLSID_DirectMusicContainer, NULL, CLSCTX_INPROC_SERVER, + &IID_IDirectMusicObject, (void **)&dmo); + ok(hr == S_OK, "DirectMusicContainer create failed: %08x, expected S_OK\n", hr); + + /* 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 /* XP */ || + broken(desc.dwValidData == (DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS)), /* Vista and above */ + "Got valid data %#x, expected DMUS_OBJ_OBJECT\n", desc.dwValidData); + ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicContainer), + "Got class guid %s, expected CLSID_DirectMusicContainer\n", + wine_dbgstr_guid(&desc.guidClass)); + + /* Empty RIFF stream */ + stream = gen_riff_stream(empty); + memset(&desc, 0, sizeof(desc)); + hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc); + ok(hr == E_INVALIDARG, "ParseDescriptor failed: %08x, expected E_INVALIDARG\n", hr); + desc.dwSize = 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_DirectMusicContainer), + "Got class guid %s, expected CLSID_DirectMusicContainer\n", + wine_dbgstr_guid(&desc.guidClass)); + IStream_Release(stream); + + /* Wrong form */ + empty[1] = DMUS_FOURCC_SEGMENT_FORM; + stream = gen_riff_stream(empty); + hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc); + todo_wine ok(hr == DMUS_E_DESCEND_CHUNK_FAIL, + "ParseDescriptor failed: %08x, expected DMUS_E_DESCEND_CHUNK_FAIL\n", hr); + + /* All desc chunks */ + stream = gen_riff_stream(alldesc); + memset(&desc, 0, sizeof(desc)); + desc.dwSize = 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_NAME|DMUS_OBJ_CATEGORY|DMUS_OBJ_VERSION; + ok(desc.dwValidData == valid, "Got valid data %#x, expected %#x\n", desc.dwValidData, valid); + ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicContainer), + "Got class guid %s, expected CLSID_DirectMusicContainer\n", + wine_dbgstr_guid(&desc.guidClass)); + ok(IsEqualGUID(&desc.guidObject, &GUID_NULL), "Got object guid %s, expected GUID_NULL\n", + wine_dbgstr_guid(&desc.guidClass)); + ok(!memcmp(desc.wszName, s_unam, sizeof(s_unam)), "Got name '%s', expected 'UNAM'\n", + wine_dbgstr_w(desc.wszName)); + IStream_Release(stream); + + /* UNFO list with INAM */ + inam[3] = DMUS_FOURCC_UNFO_LIST; + stream = gen_riff_stream(inam); + memset(&desc, 0, sizeof(desc)); + desc.dwSize = 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, "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)); + desc.dwSize = 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); + IStream_Release(stream); + + /* Duplicated chunks */ + stream = gen_riff_stream(dupes); + memset(&desc, 0, sizeof(desc)); + desc.dwSize = 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_NAME|DMUS_OBJ_CATEGORY|DMUS_OBJ_VERSION; + ok(desc.dwValidData == valid, "Got valid data %#x, expected %#x\n", desc.dwValidData, valid); + todo_wine ok(!memcmp(desc.wszName, s_unam, sizeof(s_unam)), "Got name '%s', expected 'UNAM'\n", + wine_dbgstr_w(desc.wszName)); + IStream_Release(stream); + + IDirectMusicObject_Release(dmo); +} + START_TEST(loader) { CoInitialize(NULL); @@ -408,5 +610,7 @@ START_TEST(loader) test_COM(); test_COM_container(); test_container(); + test_parsedescriptor(); + CoUninitialize(); }