2 * Copyright 2014 Michael Stefaniuc
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include <wine/test.h>
29 DEFINE_GUID(GUID_NULL
,0,0,0,0,0,0,0,0,0,0,0);
31 static BOOL
missing_dmstyle(void)
33 IDirectMusicStyle
*dms
;
34 HRESULT hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, NULL
, CLSCTX_INPROC_SERVER
,
35 &IID_IDirectMusicStyle
, (void**)&dms
);
37 if (hr
== S_OK
&& dms
)
39 IDirectMusicStyle_Release(dms
);
45 static void test_COM(void)
47 IDirectMusicStyle8
*dms8
= (IDirectMusicStyle8
*)0xdeadbeef;
48 IDirectMusicObject
*dmo
;
55 hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
,
56 &IID_IUnknown
, (void**)&dms8
);
57 ok(hr
== CLASS_E_NOAGGREGATION
,
58 "DirectMusicStyle8 create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
59 ok(!dms8
, "dms8 = %p\n", dms8
);
62 hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IClassFactory
,
64 ok(hr
== E_NOINTERFACE
, "DirectMusicStyle8 create failed: %08x, expected E_NOINTERFACE\n", hr
);
66 /* Same refcount for all DirectMusicStyle8 interfaces */
67 hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, NULL
, CLSCTX_INPROC_SERVER
,
68 &IID_IDirectMusicStyle8
, (void**)&dms8
);
69 if (hr
== E_NOINTERFACE
) {
70 win_skip("Old version without IDirectMusicStyle8\n");
73 ok(hr
== S_OK
, "DirectMusicStyle8 create failed: %08x, expected S_OK\n", hr
);
74 refcount
= IDirectMusicStyle8_AddRef(dms8
);
75 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
77 hr
= IDirectMusicStyle8_QueryInterface(dms8
, &IID_IDirectMusicObject
, (void**)&dmo
);
78 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicObject failed: %08x\n", hr
);
79 refcount
= IDirectMusicObject_AddRef(dmo
);
80 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
81 refcount
= IDirectMusicObject_Release(dmo
);
83 hr
= IDirectMusicStyle8_QueryInterface(dms8
, &IID_IPersistStream
, (void**)&ps
);
84 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
85 refcount
= IPersistStream_AddRef(ps
);
86 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
87 refcount
= IPersistStream_Release(ps
);
89 hr
= IDirectMusicStyle8_QueryInterface(dms8
, &IID_IUnknown
, (void**)&unk
);
90 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
91 refcount
= IUnknown_AddRef(unk
);
92 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
93 refcount
= IUnknown_Release(unk
);
95 while (IDirectMusicStyle8_Release(dms8
));
98 static void test_COM_section(void)
100 IDirectMusicObject
*dmo
= (IDirectMusicObject
*)0xdeadbeef;
106 /* COM aggregation */
107 hr
= CoCreateInstance(&CLSID_DirectMusicSection
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
,
108 &IID_IUnknown
, (void**)&dmo
);
109 ok(hr
== CLASS_E_NOAGGREGATION
,
110 "DirectMusicSection create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
111 ok(!dmo
, "dmo = %p\n", dmo
);
114 hr
= CoCreateInstance(&CLSID_DirectMusicSection
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IClassFactory
,
116 todo_wine
ok(hr
== E_NOINTERFACE
,
117 "DirectMusicSection create failed: %08x, expected E_NOINTERFACE\n", hr
);
119 /* Same refcount for all DirectMusicObject interfaces */
120 hr
= CoCreateInstance(&CLSID_DirectMusicSection
, NULL
, CLSCTX_INPROC_SERVER
,
121 &IID_IDirectMusicObject
, (void**)&dmo
);
122 todo_wine
ok(hr
== S_OK
, "DirectMusicSection create failed: %08x, expected S_OK\n", hr
);
124 skip("DirectMusicSection not implemented\n");
127 refcount
= IDirectMusicObject_AddRef(dmo
);
128 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
130 hr
= IDirectMusicObject_QueryInterface(dmo
, &IID_IPersistStream
, (void**)&ps
);
131 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
132 refcount
= IPersistStream_AddRef(ps
);
133 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
134 IPersistStream_Release(ps
);
136 hr
= IDirectMusicObject_QueryInterface(dmo
, &IID_IUnknown
, (void**)&unk
);
137 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
138 refcount
= IUnknown_AddRef(unk
);
139 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
140 refcount
= IUnknown_Release(unk
);
142 while (IDirectMusicObject_Release(dmo
));
145 static void test_COM_track(void)
147 IDirectMusicTrack8
*dmt8
;
152 #define X(class) &CLSID_ ## class, #class
157 { X(DirectMusicAuditionTrack
) },
158 { X(DirectMusicChordTrack
) },
159 { X(DirectMusicCommandTrack
) },
160 { X(DirectMusicMotifTrack
) },
161 { X(DirectMusicMuteTrack
) },
162 { X(DirectMusicStyleTrack
) },
167 for (i
= 0; i
< ARRAY_SIZE(class); i
++) {
168 /* COM aggregation */
169 dmt8
= (IDirectMusicTrack8
*)0xdeadbeef;
170 hr
= CoCreateInstance(class[i
].clsid
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
172 if (hr
== REGDB_E_CLASSNOTREG
) {
173 win_skip("%s not registered\n", class[i
].name
);
176 ok(hr
== CLASS_E_NOAGGREGATION
,
177 "%s create failed: %08x, expected CLASS_E_NOAGGREGATION\n", class[i
].name
, hr
);
178 ok(!dmt8
, "dmt8 = %p\n", dmt8
);
181 hr
= CoCreateInstance(class[i
].clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicObject
,
183 ok(hr
== E_NOINTERFACE
, "%s create failed: %08x, expected E_NOINTERFACE\n",
186 /* Same refcount for all DirectMusicTrack interfaces */
187 hr
= CoCreateInstance(class[i
].clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicTrack8
,
189 ok(hr
== S_OK
, "%s create failed: %08x, expected S_OK\n", class[i
].name
, hr
);
190 refcount
= IDirectMusicTrack8_AddRef(dmt8
);
191 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
193 hr
= IDirectMusicTrack8_QueryInterface(dmt8
, &IID_IPersistStream
, (void**)&ps
);
194 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
195 refcount
= IPersistStream_AddRef(ps
);
196 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
197 IPersistStream_Release(ps
);
199 hr
= IDirectMusicTrack8_QueryInterface(dmt8
, &IID_IUnknown
, (void**)&unk
);
200 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
201 refcount
= IUnknown_AddRef(unk
);
202 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
203 refcount
= IUnknown_Release(unk
);
205 while (IDirectMusicTrack8_Release(dmt8
));
209 static void test_dmstyle(void)
211 IDirectMusicStyle
*dms
;
217 hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, NULL
, CLSCTX_INPROC_SERVER
,
218 &IID_IDirectMusicStyle
, (void**)&dms
);
219 ok(hr
== S_OK
, "DirectMusicStyle create failed: %08x, expected S_OK\n", hr
);
222 hr
= IDirectMusicStyle_QueryInterface(dms
, &IID_IPersistStream
, (void**)&ps
);
223 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
224 hr
= IPersistStream_GetClassID(ps
, &class);
225 ok(hr
== S_OK
, "IPersistStream_GetClassID failed: %08x\n", hr
);
226 ok(IsEqualGUID(&class, &CLSID_DirectMusicStyle
),
227 "Expected class CLSID_DirectMusicStyle got %s\n", wine_dbgstr_guid(&class));
229 /* Unimplemented IPersistStream methods*/
230 hr
= IPersistStream_IsDirty(ps
);
231 ok(hr
== S_FALSE
, "IPersistStream_IsDirty failed: %08x\n", hr
);
232 hr
= IPersistStream_GetSizeMax(ps
, &size
);
233 ok(hr
== E_NOTIMPL
, "IPersistStream_GetSizeMax failed: %08x\n", hr
);
234 hr
= IPersistStream_Save(ps
, NULL
, TRUE
);
235 ok(hr
== E_NOTIMPL
, "IPersistStream_Save failed: %08x\n", hr
);
237 while (IDirectMusicStyle_Release(dms
));
240 static void expect_getparam(IDirectMusicTrack8
*track
, REFGUID type
, const char *name
,
244 char buf
[64] = { 0 };
246 hr
= IDirectMusicTrack8_GetParam(track
, type
, 0, NULL
, buf
);
247 ok(hr
== expect
, "GetParam(%s) failed: %08x, expected %08x\n", name
, hr
, expect
);
250 static void expect_setparam(IDirectMusicTrack8
*track
, REFGUID type
, const char *name
,
255 hr
= IDirectMusicTrack8_SetParam(track
, type
, 0, track
);
256 ok(hr
== expect
, "SetParam(%s) failed: %08x, expected %08x\n", name
, hr
, expect
);
259 static void test_track(void)
261 IDirectMusicTrack8
*dmt8
;
266 #define X(guid) &guid, #guid
271 { X(GUID_BandParam
) },
272 { X(GUID_ChordParam
) },
273 { X(GUID_Clear_All_Bands
) },
274 { X(GUID_CommandParam
) },
275 { X(GUID_CommandParam2
) },
276 { X(GUID_CommandParamNext
) },
277 { X(GUID_ConnectToDLSCollection
) },
278 { X(GUID_Disable_Auto_Download
) },
279 { X(GUID_DisableTempo
) },
280 { X(GUID_DisableTimeSig
) },
281 { X(GUID_Download
) },
282 { X(GUID_DownloadToAudioPath
) },
283 { X(GUID_Enable_Auto_Download
) },
284 { X(GUID_EnableTempo
) },
285 { X(GUID_EnableTimeSig
) },
286 { X(GUID_IDirectMusicBand
) },
287 { X(GUID_IDirectMusicChordMap
) },
288 { X(GUID_IDirectMusicStyle
) },
289 { X(GUID_MuteParam
) },
290 { X(GUID_Play_Marker
) },
291 { X(GUID_RhythmParam
) },
292 { X(GUID_SeedVariations
) },
293 { X(GUID_StandardMIDIFile
) },
294 { X(GUID_TempoParam
) },
295 { X(GUID_TimeSignature
) },
297 { X(GUID_UnloadFromAudioPath
) },
298 { X(GUID_Valid_Start_Time
) },
299 { X(GUID_Variations
) }
302 #define X(class) &CLSID_ ## class, #class
308 /* bitfield with supported param types */
309 unsigned int has_params
;
311 { X(DirectMusicAuditionTrack
), TRUE
, FALSE
, 0x18204200 },
312 { X(DirectMusicChordTrack
), TRUE
, TRUE
, 0x100002 },
313 { X(DirectMusicCommandTrack
), TRUE
, TRUE
, 0x38 },
314 { X(DirectMusicMotifTrack
), FALSE
, FALSE
, 0x8204200 },
315 { X(DirectMusicMuteTrack
), TRUE
, FALSE
, 0x40000 },
316 { X(DirectMusicStyleTrack
), FALSE
, TRUE
, 0x1224200 },
321 for (i
= 0; i
< ARRAY_SIZE(class); i
++) {
322 trace("Testing %s\n", class[i
].name
);
323 hr
= CoCreateInstance(class[i
].clsid
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicTrack8
,
325 ok(hr
== S_OK
, "%s create failed: %08x, expected S_OK\n", class[i
].name
, hr
);
327 /* IDirectMusicTrack8 */
328 hr
= IDirectMusicTrack8_Init(dmt8
, NULL
);
329 todo_wine
ok(hr
== E_POINTER
, "IDirectMusicTrack8_Init failed: %08x\n", hr
);
330 if (class[i
].clsid
!= &CLSID_DirectMusicChordTrack
&&
331 class[i
].clsid
!= &CLSID_DirectMusicCommandTrack
) {
332 /* Crashes on native */
333 hr
= IDirectMusicTrack8_InitPlay(dmt8
, NULL
, NULL
, NULL
, 0, 0);
334 if (class[i
].clsid
== &CLSID_DirectMusicMuteTrack
)
335 ok(hr
== S_OK
, "IDirectMusicTrack8_InitPlay failed: %08x\n", hr
);
337 todo_wine
ok(hr
== E_POINTER
, "IDirectMusicTrack8_InitPlay failed: %08x\n", hr
);
340 hr
= IDirectMusicTrack8_GetParam(dmt8
, NULL
, 0, NULL
, NULL
);
341 ok(hr
== E_POINTER
, "IDirectMusicTrack8_GetParam failed: %08x\n", hr
);
342 hr
= IDirectMusicTrack8_SetParam(dmt8
, NULL
, 0, NULL
);
343 ok(hr
== E_POINTER
, "IDirectMusicTrack8_SetParam failed: %08x\n", hr
);
345 hr
= IDirectMusicTrack8_IsParamSupported(dmt8
, NULL
);
346 ok(hr
== E_POINTER
, "IDirectMusicTrack8_IsParamSupported failed: %08x\n", hr
);
347 for (j
= 0; j
< ARRAY_SIZE(param_types
); j
++) {
348 hr
= IDirectMusicTrack8_IsParamSupported(dmt8
, param_types
[j
].type
);
349 if (class[i
].has_params
& (1 << j
))
350 ok(hr
== S_OK
, "IsParamSupported(%s) failed: %08x, expected S_OK\n",
351 param_types
[j
].name
, hr
);
353 ok(hr
== DMUS_E_TYPE_UNSUPPORTED
,
354 "IsParamSupported(%s) failed: %08x, expected DMUS_E_TYPE_UNSUPPORTED\n",
355 param_types
[j
].name
, hr
);
356 if (class[i
].clsid
== &CLSID_DirectMusicChordTrack
) {
357 expect_setparam(dmt8
, param_types
[j
].type
, param_types
[j
].name
,
358 DMUS_E_SET_UNSUPPORTED
);
359 } else if (class[i
].clsid
== &CLSID_DirectMusicMuteTrack
) {
360 expect_getparam(dmt8
, param_types
[j
].type
, param_types
[j
].name
,
361 DMUS_E_TYPE_UNSUPPORTED
);
362 expect_setparam(dmt8
, param_types
[j
].type
, param_types
[j
].name
,
363 DMUS_E_TYPE_UNSUPPORTED
);
365 expect_getparam(dmt8
, param_types
[j
].type
, param_types
[j
].name
,
366 DMUS_E_GET_UNSUPPORTED
);
367 expect_setparam(dmt8
, param_types
[j
].type
, param_types
[j
].name
,
368 DMUS_E_SET_UNSUPPORTED
);
373 /* GetParam / SetParam for IsParamSupported supported types */
374 if (class[i
].clsid
== &CLSID_DirectMusicAuditionTrack
) {
375 expect_getparam(dmt8
, &GUID_DisableTimeSig
, "GUID_DisableTimeSig",
376 DMUS_E_GET_UNSUPPORTED
);
377 expect_getparam(dmt8
, &GUID_EnableTimeSig
, "GUID_EnableTimeSig",
378 DMUS_E_GET_UNSUPPORTED
);
379 expect_getparam(dmt8
, &GUID_SeedVariations
, "GUID_SeedVariations",
380 DMUS_E_GET_UNSUPPORTED
);
381 expect_setparam(dmt8
, &GUID_Valid_Start_Time
, "GUID_Valid_Start_Time",
382 DMUS_E_SET_UNSUPPORTED
);
383 expect_setparam(dmt8
, &GUID_Variations
, "GUID_Variations",
384 DMUS_E_SET_UNSUPPORTED
);
385 } else if (class[i
].clsid
== &CLSID_DirectMusicChordTrack
) {
386 expect_setparam(dmt8
, &GUID_RhythmParam
, "GUID_RhythmParam",
387 DMUS_E_SET_UNSUPPORTED
);
388 } else if (class[i
].clsid
== &CLSID_DirectMusicCommandTrack
) {
389 expect_setparam(dmt8
, &GUID_CommandParam2
, "GUID_CommandParam2",
390 DMUS_E_SET_UNSUPPORTED
);
391 } else if (class[i
].clsid
== &CLSID_DirectMusicMotifTrack
) {
392 expect_getparam(dmt8
, &GUID_DisableTimeSig
, "GUID_DisableTimeSig",
393 DMUS_E_GET_UNSUPPORTED
);
394 expect_getparam(dmt8
, &GUID_EnableTimeSig
, "GUID_EnableTimeSig",
395 DMUS_E_GET_UNSUPPORTED
);
396 expect_getparam(dmt8
, &GUID_SeedVariations
, "GUID_SeedVariations",
397 DMUS_E_GET_UNSUPPORTED
);
398 expect_setparam(dmt8
, &GUID_Valid_Start_Time
, "GUID_Valid_Start_Time",
399 DMUS_E_SET_UNSUPPORTED
);
400 } else if (class[i
].clsid
== &CLSID_DirectMusicStyleTrack
) {
401 expect_getparam(dmt8
, &GUID_DisableTimeSig
, "GUID_DisableTimeSig",
402 DMUS_E_GET_UNSUPPORTED
);
403 expect_getparam(dmt8
, &GUID_EnableTimeSig
, "GUID_EnableTimeSig",
404 DMUS_E_GET_UNSUPPORTED
);
405 expect_getparam(dmt8
, &GUID_SeedVariations
, "GUID_SeedVariations",
406 DMUS_E_GET_UNSUPPORTED
);
407 expect_setparam(dmt8
, &GUID_TimeSignature
, "GUID_TimeSignature",
408 DMUS_E_SET_UNSUPPORTED
);
411 if (class[i
].clsid
== &CLSID_DirectMusicMuteTrack
) {
412 hr
= IDirectMusicTrack8_AddNotificationType(dmt8
, NULL
);
413 ok(hr
== E_NOTIMPL
, "IDirectMusicTrack8_AddNotificationType failed: %08x\n", hr
);
414 hr
= IDirectMusicTrack8_RemoveNotificationType(dmt8
, NULL
);
415 ok(hr
== E_NOTIMPL
, "IDirectMusicTrack8_RemoveNotificationType failed: %08x\n", hr
);
417 hr
= IDirectMusicTrack8_AddNotificationType(dmt8
, NULL
);
418 ok(hr
== E_POINTER
, "IDirectMusicTrack8_AddNotificationType failed: %08x\n", hr
);
419 hr
= IDirectMusicTrack8_RemoveNotificationType(dmt8
, NULL
);
420 ok(hr
== E_POINTER
, "IDirectMusicTrack8_RemoveNotificationType failed: %08x\n", hr
);
423 hr
= IDirectMusicTrack8_Clone(dmt8
, 0, 0, NULL
);
424 ok(hr
== E_POINTER
, "IDirectMusicTrack8_Clone failed: %08x\n", hr
);
425 hr
= IDirectMusicTrack8_PlayEx(dmt8
, NULL
, 0, 0, 0, 0, NULL
, NULL
, 0);
426 ok(hr
== E_POINTER
, "IDirectMusicTrack8_PlayEx failed: %08x\n", hr
);
427 hr
= IDirectMusicTrack8_GetParamEx(dmt8
, NULL
, 0, NULL
, NULL
, NULL
, 0);
428 ok(hr
== E_POINTER
, "IDirectMusicTrack8_GetParamEx failed: %08x\n", hr
);
429 hr
= IDirectMusicTrack8_SetParamEx(dmt8
, NULL
, 0, NULL
, NULL
, 0);
430 ok(hr
== E_POINTER
, "IDirectMusicTrack8_SetParamEx failed: %08x\n", hr
);
432 hr
= IDirectMusicTrack8_Compose(dmt8
, NULL
, 0, NULL
);
433 ok(hr
== E_NOTIMPL
, "IDirectMusicTrack8_Compose failed: %08x\n", hr
);
434 if (class[i
].has_join
) {
435 hr
= IDirectMusicTrack8_Join(dmt8
, NULL
, 0, NULL
, 0, NULL
);
436 todo_wine
ok(hr
== E_POINTER
, "IDirectMusicTrack8_Join failed: %08x\n", hr
);
438 hr
= IDirectMusicTrack8_Join(dmt8
, NULL
, 0, NULL
, 0, NULL
);
439 ok(hr
== E_NOTIMPL
, "IDirectMusicTrack8_Join failed: %08x\n", hr
);
443 hr
= IDirectMusicTrack8_QueryInterface(dmt8
, &IID_IPersistStream
, (void**)&ps
);
444 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
445 hr
= IPersistStream_GetClassID(ps
, &classid
);
446 ok(hr
== S_OK
, "IPersistStream_GetClassID failed: %08x\n", hr
);
447 ok(IsEqualGUID(&classid
, class[i
].clsid
),
448 "Expected class %s got %s\n", class[i
].name
, wine_dbgstr_guid(&classid
));
449 hr
= IPersistStream_IsDirty(ps
);
450 ok(hr
== S_FALSE
, "IPersistStream_IsDirty failed: %08x\n", hr
);
452 hr
= IPersistStream_GetSizeMax(ps
, &size
);
453 ok(hr
== E_NOTIMPL
, "IPersistStream_GetSizeMax failed: %08x\n", hr
);
455 hr
= IPersistStream_Save(ps
, NULL
, TRUE
);
456 if (class[i
].has_save
)
457 ok(hr
== E_POINTER
, "IPersistStream_Save failed: %08x\n", hr
);
459 ok(hr
== E_NOTIMPL
, "IPersistStream_Save failed: %08x\n", hr
);
461 while (IDirectMusicTrack8_Release(dmt8
));
471 #define CHUNK_HDR_SIZE (sizeof(FOURCC) + sizeof(DWORD))
473 /* Generate a RIFF file format stream from an array of FOURCC ids.
474 RIFF and LIST need to be followed by the form type respectively list type,
475 followed by the chunks of the list and terminated with 0. */
476 static IStream
*gen_riff_stream(const FOURCC
*ids
)
478 static const LARGE_INTEGER zero
;
480 DWORD
*sizes
[4]; /* Stack for the sizes of RIFF and LIST chunks */
487 ck
= (struct chunk
*)p
;
491 *sizes
[level
] = p
- (char *)sizes
[level
] - sizeof(DWORD
);
497 sizes
[level
] = &ck
->size
;
501 case DMUS_FOURCC_GUID_CHUNK
:
502 ck
->size
= sizeof(GUID_NULL
);
504 memcpy(p
, &GUID_NULL
, sizeof(GUID_NULL
));
507 case DMUS_FOURCC_VERSION_CHUNK
:
509 DMUS_VERSION ver
= {5, 8};
511 ck
->size
= sizeof(ver
);
513 memcpy(p
, &ver
, sizeof(ver
));
519 /* Just convert the FOURCC id to a WCHAR string */
522 ck
->size
= 5 * sizeof(WCHAR
);
525 s
[0] = (char)(ck
->id
);
526 s
[1] = (char)(ck
->id
>> 8);
527 s
[2] = (char)(ck
->id
>> 16);
528 s
[3] = (char)(ck
->id
>> 24);
533 } while (level
>= 0);
535 ck
= (struct chunk
*)riff
;
536 CreateStreamOnHGlobal(NULL
, TRUE
, &stream
);
537 IStream_Write(stream
, riff
, ck
->size
+ CHUNK_HDR_SIZE
, NULL
);
538 IStream_Seek(stream
, zero
, STREAM_SEEK_SET
, NULL
);
543 static void test_parsedescriptor(void)
545 IDirectMusicObject
*dmo
;
547 DMUS_OBJECTDESC desc
= {0};
550 const FOURCC alldesc
[] =
552 FOURCC_RIFF
, DMUS_FOURCC_STYLE_FORM
, DMUS_FOURCC_CATEGORY_CHUNK
, FOURCC_LIST
,
553 DMUS_FOURCC_UNFO_LIST
, DMUS_FOURCC_UNAM_CHUNK
, DMUS_FOURCC_UCOP_CHUNK
,
554 DMUS_FOURCC_UCMT_CHUNK
, DMUS_FOURCC_USBJ_CHUNK
, 0, DMUS_FOURCC_VERSION_CHUNK
,
555 DMUS_FOURCC_GUID_CHUNK
, 0
557 const FOURCC dupes
[] =
559 FOURCC_RIFF
, DMUS_FOURCC_STYLE_FORM
, DMUS_FOURCC_CATEGORY_CHUNK
, DMUS_FOURCC_CATEGORY_CHUNK
,
560 DMUS_FOURCC_VERSION_CHUNK
, DMUS_FOURCC_VERSION_CHUNK
, DMUS_FOURCC_GUID_CHUNK
,
561 DMUS_FOURCC_GUID_CHUNK
, FOURCC_LIST
, DMUS_FOURCC_UNFO_LIST
, DMUS_FOURCC_UNAM_CHUNK
, 0,
562 FOURCC_LIST
, DMUS_FOURCC_UNFO_LIST
, mmioFOURCC('I','N','A','M'), 0, 0
564 FOURCC empty
[] = {FOURCC_RIFF
, DMUS_FOURCC_STYLE_FORM
, 0};
567 FOURCC_RIFF
, DMUS_FOURCC_STYLE_FORM
, FOURCC_LIST
, DMUS_FOURCC_UNFO_LIST
,
568 mmioFOURCC('I','N','A','M'), 0, 0
571 hr
= CoCreateInstance(&CLSID_DirectMusicStyle
, NULL
, CLSCTX_INPROC_SERVER
,
572 &IID_IDirectMusicObject
, (void **)&dmo
);
573 ok(hr
== S_OK
, "DirectMusicStyle create failed: %08x, expected S_OK\n", hr
);
576 hr
= IDirectMusicObject_GetDescriptor(dmo
, &desc
);
577 ok(hr
== S_OK
, "GetDescriptor failed: %08x, expected S_OK\n", hr
);
578 ok(desc
.dwValidData
& DMUS_OBJ_CLASS
, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
580 ok(IsEqualGUID(&desc
.guidClass
, &CLSID_DirectMusicStyle
),
581 "Got class guid %s, expected CLSID_DirectMusicStyle\n",
582 wine_dbgstr_guid(&desc
.guidClass
));
584 /* Empty RIFF stream */
585 stream
= gen_riff_stream(empty
);
586 memset(&desc
, 0, sizeof(desc
));
587 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
588 ok(hr
== S_OK
, "ParseDescriptor failed: %08x, expected S_OK\n", hr
);
589 ok(desc
.dwValidData
== DMUS_OBJ_CLASS
, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
591 ok(IsEqualGUID(&desc
.guidClass
, &CLSID_DirectMusicStyle
),
592 "Got class guid %s, expected CLSID_DirectMusicStyle\n",
593 wine_dbgstr_guid(&desc
.guidClass
));
594 IStream_Release(stream
);
597 memset(&desc
, 0, sizeof(desc
));
598 hr
= IDirectMusicObject_ParseDescriptor(dmo
, NULL
, &desc
);
599 ok(hr
== E_POINTER
, "ParseDescriptor failed: %08x, expected E_POINTER\n", hr
);
600 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, NULL
);
601 ok(hr
== E_POINTER
, "ParseDescriptor failed: %08x, expected E_POINTER\n", hr
);
604 empty
[1] = DMUS_FOURCC_CONTAINER_FORM
;
605 stream
= gen_riff_stream(empty
);
606 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
607 ok(hr
== DMUS_E_CHUNKNOTFOUND
,
608 "ParseDescriptor failed: %08x, expected DMUS_E_CHUNKNOTFOUND\n", hr
);
609 IStream_Release(stream
);
611 /* All desc chunks, DMUS_OBJ_CATEGORY not supported */
612 stream
= gen_riff_stream(alldesc
);
613 memset(&desc
, 0, sizeof(desc
));
614 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
615 ok(hr
== S_OK
, "ParseDescriptor failed: %08x, expected S_OK\n", hr
);
616 valid
= DMUS_OBJ_OBJECT
|DMUS_OBJ_CLASS
|DMUS_OBJ_NAME
|DMUS_OBJ_VERSION
;
617 ok(desc
.dwValidData
== valid
, "Got valid data %#x, expected %#x\n", desc
.dwValidData
, valid
);
618 ok(IsEqualGUID(&desc
.guidClass
, &CLSID_DirectMusicStyle
),
619 "Got class guid %s, expected CLSID_DirectMusicStyle\n",
620 wine_dbgstr_guid(&desc
.guidClass
));
621 ok(IsEqualGUID(&desc
.guidObject
, &GUID_NULL
), "Got object guid %s, expected GUID_NULL\n",
622 wine_dbgstr_guid(&desc
.guidClass
));
623 ok(!lstrcmpW(desc
.wszName
, L
"UNAM"), "Got name '%s', expected 'UNAM'\n",
624 wine_dbgstr_w(desc
.wszName
));
625 IStream_Release(stream
);
627 /* UNFO list with INAM */
628 inam
[3] = DMUS_FOURCC_UNFO_LIST
;
629 stream
= gen_riff_stream(inam
);
630 memset(&desc
, 0, sizeof(desc
));
631 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
632 ok(hr
== S_OK
, "ParseDescriptor failed: %08x, expected S_OK\n", hr
);
633 ok(desc
.dwValidData
== (DMUS_OBJ_CLASS
| DMUS_OBJ_NAME
),
634 "Got valid data %#x, expected DMUS_OBJ_CLASS | DMUS_OBJ_NAME\n", desc
.dwValidData
);
635 ok(!lstrcmpW(desc
.wszName
, L
"INAM"), "Got name '%s', expected 'INAM'\n",
636 wine_dbgstr_w(desc
.wszName
));
637 IStream_Release(stream
);
639 /* INFO list with INAM */
640 inam
[3] = DMUS_FOURCC_INFO_LIST
;
641 stream
= gen_riff_stream(inam
);
642 memset(&desc
, 0, sizeof(desc
));
643 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
644 ok(hr
== S_OK
, "ParseDescriptor failed: %08x, expected S_OK\n", hr
);
645 ok(desc
.dwValidData
== DMUS_OBJ_CLASS
, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
647 IStream_Release(stream
);
649 /* Duplicated chunks */
650 stream
= gen_riff_stream(dupes
);
651 memset(&desc
, 0, sizeof(desc
));
652 hr
= IDirectMusicObject_ParseDescriptor(dmo
, stream
, &desc
);
653 ok(hr
== S_OK
, "ParseDescriptor failed: %08x, expected S_OK\n", hr
);
654 valid
= DMUS_OBJ_OBJECT
|DMUS_OBJ_CLASS
|DMUS_OBJ_NAME
|DMUS_OBJ_VERSION
;
655 ok(desc
.dwValidData
== valid
, "Got valid data %#x, expected %#x\n", desc
.dwValidData
, valid
);
656 ok(!lstrcmpW(desc
.wszName
, L
"INAM"), "Got name '%s', expected 'INAM'\n",
657 wine_dbgstr_w(desc
.wszName
));
658 IStream_Release(stream
);
660 IDirectMusicObject_Release(dmo
);
667 if (missing_dmstyle())
669 skip("dmstyle not available\n");
678 test_parsedescriptor();