mf/session: Forward more events to the application.
[wine/zf.git] / dlls / dmcompos / tests / dmcompos.c
blobd4dbd2206c44b429747dc9d63c4513be5069c24e
1 /*
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
19 #define COBJMACROS
21 #include <stdarg.h>
22 #include <windef.h>
23 #include <initguid.h>
24 #include <wine/test.h>
25 #include <ole2.h>
26 #include <dmusici.h>
27 #include <dmusicf.h>
29 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
31 static BOOL missing_dmcompos(void)
33 IDirectMusicComposer *dmc;
34 HRESULT hr = CoCreateInstance(&CLSID_DirectMusicComposer, NULL, CLSCTX_INPROC_SERVER,
35 &IID_IDirectMusicComposer, (void**)&dmc);
37 if (hr == S_OK && dmc)
39 IDirectMusicComposer_Release(dmc);
40 return FALSE;
42 return TRUE;
45 static void test_COM(void)
47 IDirectMusicComposer *dmc = (IDirectMusicComposer*)0xdeadbeef;
48 IUnknown *unk;
49 ULONG refcount;
50 HRESULT hr;
52 /* COM aggregation */
53 hr = CoCreateInstance(&CLSID_DirectMusicComposer, (IUnknown *)0xdeadbeef, CLSCTX_INPROC_SERVER,
54 &IID_IUnknown, (void**)&dmc);
55 ok(hr == CLASS_E_NOAGGREGATION,
56 "DirectMusicComposer create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr);
57 ok(!dmc, "dmc = %p\n", dmc);
59 /* Invalid RIID */
60 hr = CoCreateInstance(&CLSID_DirectMusicComposer, NULL, CLSCTX_INPROC_SERVER,
61 &IID_IDirectMusicObject, (void**)&dmc);
62 ok(hr == E_NOINTERFACE,
63 "DirectMusicComposer create failed: %08x, expected E_NOINTERFACE\n", hr);
65 /* Same refcount for all DirectMusicComposer interfaces */
66 hr = CoCreateInstance(&CLSID_DirectMusicComposer, NULL, CLSCTX_INPROC_SERVER,
67 &IID_IDirectMusicComposer, (void**)&dmc);
68 ok(hr == S_OK, "DirectMusicComposer create failed: %08x, expected S_OK\n", hr);
69 refcount = IDirectMusicComposer_AddRef(dmc);
70 ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
72 hr = IDirectMusicComposer_QueryInterface(dmc, &IID_IUnknown, (void**)&unk);
73 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
74 refcount = IUnknown_AddRef(unk);
75 ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
76 refcount = IUnknown_Release(unk);
78 while (IDirectMusicComposer_Release(dmc));
81 static void test_COM_chordmap(void)
83 IDirectMusicChordMap *dmcm = (IDirectMusicChordMap*)0xdeadbeef;
84 IDirectMusicObject *dmo;
85 IPersistStream *ps;
86 IUnknown *unk;
87 ULONG refcount;
88 HRESULT hr;
90 /* COM aggregation */
91 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, (IUnknown *)0xdeadbeef, CLSCTX_INPROC_SERVER,
92 &IID_IUnknown, (void**)&dmcm);
93 ok(hr == CLASS_E_NOAGGREGATION,
94 "DirectMusicChordMap create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr);
95 ok(!dmcm, "dmcm = %p\n", dmcm);
97 /* Invalid RIID */
98 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, NULL, CLSCTX_INPROC_SERVER,
99 &IID_IClassFactory, (void**)&dmcm);
100 ok(hr == E_NOINTERFACE,
101 "DirectMusicChordMap create failed: %08x, expected E_NOINTERFACE\n", hr);
103 /* Same refcount for all DirectMusicChordMap interfaces */
104 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, NULL, CLSCTX_INPROC_SERVER,
105 &IID_IDirectMusicChordMap, (void**)&dmcm);
106 ok(hr == S_OK, "DirectMusicChordMap create failed: %08x, expected S_OK\n", hr);
107 refcount = IDirectMusicChordMap_AddRef(dmcm);
108 ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
110 hr = IDirectMusicChordMap_QueryInterface(dmcm, &IID_IDirectMusicObject, (void**)&dmo);
111 ok(hr == S_OK, "QueryInterface for IID_IDirectMusicObject failed: %08x\n", hr);
112 refcount = IDirectMusicObject_AddRef(dmo);
113 ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
114 refcount = IDirectMusicObject_Release(dmo);
116 hr = IDirectMusicChordMap_QueryInterface(dmcm, &IID_IPersistStream, (void**)&ps);
117 ok(hr == S_OK, "QueryInterface for IID_IPersistStream failed: %08x\n", hr);
118 refcount = IPersistStream_AddRef(ps);
119 ok(refcount == 5, "refcount == %u, expected 5\n", refcount);
120 refcount = IPersistStream_Release(ps);
122 hr = IDirectMusicChordMap_QueryInterface(dmcm, &IID_IUnknown, (void**)&unk);
123 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
124 refcount = IUnknown_AddRef(unk);
125 ok(refcount == 6, "refcount == %u, expected 6\n", refcount);
126 refcount = IUnknown_Release(unk);
128 while (IDirectMusicChordMap_Release(dmcm));
131 static void test_COM_template(void)
133 IPersistStream *ps = (IPersistStream*)0xdeadbeef;
134 IUnknown *unk;
135 ULONG refcount;
136 HRESULT hr;
138 /* COM aggregation */
139 hr = CoCreateInstance(&CLSID_DirectMusicTemplate, (IUnknown *)0xdeadbeef, CLSCTX_INPROC_SERVER,
140 &IID_IUnknown, (void**)&ps);
141 ok(hr == CLASS_E_NOAGGREGATION,
142 "DirectMusicTemplate create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr);
143 ok(!ps, "ps = %p\n", ps);
145 /* Invalid RIID */
146 hr = CoCreateInstance(&CLSID_DirectMusicTemplate, NULL, CLSCTX_INPROC_SERVER,
147 &IID_IDirectMusicObject, (void**)&ps);
148 todo_wine ok(hr == E_NOINTERFACE,
149 "DirectMusicTemplate create failed: %08x, expected E_NOINTERFACE\n", hr);
151 /* Same refcount for all DirectMusicTemplate interfaces */
152 hr = CoCreateInstance(&CLSID_DirectMusicTemplate, NULL, CLSCTX_INPROC_SERVER,
153 &IID_IPersistStream, (void**)&ps);
154 todo_wine ok(hr == S_OK, "DirectMusicTemplate create failed: %08x, expected S_OK\n", hr);
155 if (hr != S_OK) {
156 skip("DirectMusicTemplate not implemented\n");
157 return;
159 refcount = IPersistStream_AddRef(ps);
160 ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
162 hr = IPersistStream_QueryInterface(ps, &IID_IUnknown, (void**)&unk);
163 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
164 refcount = IUnknown_AddRef(unk);
165 ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
166 refcount = IUnknown_Release(unk);
168 while (IPersistStream_Release(ps));
171 static void test_COM_track(void)
173 IDirectMusicTrack8 *dmt8;
174 IPersistStream *ps;
175 IUnknown *unk;
176 ULONG refcount;
177 HRESULT hr;
178 #define X(class) &CLSID_ ## class, #class
179 const struct {
180 REFCLSID clsid;
181 const char *name;
182 } class[] = {
183 { X(DirectMusicChordMapTrack) },
184 { X(DirectMusicSignPostTrack) },
186 #undef X
187 unsigned int i;
189 for (i = 0; i < ARRAY_SIZE(class); i++) {
190 /* COM aggregation */
191 dmt8 = (IDirectMusicTrack8*)0xdeadbeef;
192 hr = CoCreateInstance(class[i].clsid, (IUnknown *)0xdeadbeef, CLSCTX_INPROC_SERVER, &IID_IUnknown,
193 (void**)&dmt8);
194 if (hr == REGDB_E_CLASSNOTREG) {
195 win_skip("%s not registered\n", class[i].name);
196 continue;
198 ok(hr == CLASS_E_NOAGGREGATION,
199 "%s create failed: %08x, expected CLASS_E_NOAGGREGATION\n", class[i].name, hr);
200 ok(!dmt8, "dmt8 = %p\n", dmt8);
202 /* Invalid RIID */
203 hr = CoCreateInstance(class[i].clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicObject,
204 (void**)&dmt8);
205 ok(hr == E_NOINTERFACE, "%s create failed: %08x, expected E_NOINTERFACE\n",
206 class[i].name, hr);
208 /* Same refcount for all DirectMusicTrack interfaces */
209 hr = CoCreateInstance(class[i].clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicTrack8,
210 (void**)&dmt8);
211 if (hr == E_NOINTERFACE && !dmt8) {
212 skip("%s not created with CoCreateInstance()\n", class[i].name);
213 continue;
215 ok(hr == S_OK, "%s create failed: %08x, expected S_OK\n", class[i].name, hr);
216 refcount = IDirectMusicTrack8_AddRef(dmt8);
217 ok(refcount == 2, "refcount == %u, expected 2\n", refcount);
219 hr = IDirectMusicTrack8_QueryInterface(dmt8, &IID_IPersistStream, (void**)&ps);
220 ok(hr == S_OK, "QueryInterface for IID_IPersistStream failed: %08x\n", hr);
221 refcount = IPersistStream_AddRef(ps);
222 ok(refcount == 4, "refcount == %u, expected 4\n", refcount);
223 IPersistStream_Release(ps);
225 hr = IDirectMusicTrack8_QueryInterface(dmt8, &IID_IUnknown, (void**)&unk);
226 ok(hr == S_OK, "QueryInterface for IID_IUnknown failed: %08x\n", hr);
227 refcount = IUnknown_AddRef(unk);
228 ok(refcount == 5, "refcount == %u, expected 5\n", refcount);
229 refcount = IUnknown_Release(unk);
231 while (IDirectMusicTrack8_Release(dmt8));
235 static void test_chordmap(void)
237 IDirectMusicChordMap *dmcm;
238 IPersistStream *ps;
239 CLSID class = { 0 };
240 ULARGE_INTEGER size;
241 HRESULT hr;
243 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, NULL, CLSCTX_INPROC_SERVER,
244 &IID_IDirectMusicChordMap, (void**)&dmcm);
245 ok(hr == S_OK, "DirectMusicChordMap create failed: %08x, expected S_OK\n", hr);
247 /* IPersistStream */
248 hr = IDirectMusicChordMap_QueryInterface(dmcm, &IID_IPersistStream, (void**)&ps);
249 ok(hr == S_OK, "QueryInterface for IID_IPersistStream failed: %08x\n", hr);
250 hr = IPersistStream_GetClassID(ps, &class);
251 ok(hr == S_OK, "IPersistStream_GetClassID failed: %08x\n", hr);
252 ok(IsEqualGUID(&class, &CLSID_DirectMusicChordMap),
253 "Expected class CLSID_DirectMusicChordMap got %s\n", wine_dbgstr_guid(&class));
255 /* Unimplemented IPersistStream methods */
256 hr = IPersistStream_IsDirty(ps);
257 ok(hr == S_FALSE || broken(hr == S_OK), "IPersistStream_IsDirty failed: %08x\n", hr);
258 hr = IPersistStream_GetSizeMax(ps, &size);
259 ok(hr == E_NOTIMPL, "IPersistStream_GetSizeMax failed: %08x\n", hr);
260 hr = IPersistStream_Save(ps, NULL, TRUE);
261 ok(hr == E_NOTIMPL, "IPersistStream_Save failed: %08x\n", hr);
263 while (IDirectMusicChordMap_Release(dmcm));
266 static void test_chordmaptrack(void)
268 IDirectMusicTrack8 *dmt8;
269 IPersistStream *ps;
270 IDirectMusicChordMap *chordmap;
271 CLSID class;
272 ULARGE_INTEGER size;
273 HRESULT hr;
274 #define X(guid) &guid, #guid
275 const struct {
276 REFGUID type;
277 const char *name;
278 } unsupported[] = {
279 { X(GUID_BandParam) },
280 { X(GUID_ChordParam) },
281 { X(GUID_Clear_All_Bands) },
282 { X(GUID_CommandParam) },
283 { X(GUID_CommandParam2) },
284 { X(GUID_CommandParamNext) },
285 { X(GUID_ConnectToDLSCollection) },
286 { X(GUID_Disable_Auto_Download) },
287 { X(GUID_DisableTempo) },
288 { X(GUID_DisableTimeSig) },
289 { X(GUID_Download) },
290 { X(GUID_DownloadToAudioPath) },
291 { X(GUID_Enable_Auto_Download) },
292 { X(GUID_EnableTempo) },
293 { X(GUID_EnableTimeSig) },
294 { X(GUID_IDirectMusicBand) },
295 { X(GUID_IDirectMusicStyle) },
296 { X(GUID_MuteParam) },
297 { X(GUID_Play_Marker) },
298 { X(GUID_RhythmParam) },
299 { X(GUID_SeedVariations) },
300 { X(GUID_StandardMIDIFile) },
301 { X(GUID_TempoParam) },
302 { X(GUID_TimeSignature) },
303 { X(GUID_Unload) },
304 { X(GUID_UnloadFromAudioPath) },
305 { X(GUID_Valid_Start_Time) },
306 { X(GUID_Variations) },
308 #undef X
309 unsigned int i;
311 hr = CoCreateInstance(&CLSID_DirectMusicChordMapTrack, NULL, CLSCTX_INPROC_SERVER,
312 &IID_IDirectMusicTrack8, (void**)&dmt8);
313 ok(hr == S_OK, "DirectMusicChordMapTrack create failed: %08x, expected S_OK\n", hr);
315 /* IDirectMusicTrack8 */
316 hr = IDirectMusicTrack8_Init(dmt8, NULL);
317 ok(hr == S_OK, "IDirectMusicTrack8_Init failed: %08x\n", hr);
318 hr = IDirectMusicTrack8_InitPlay(dmt8, NULL, NULL, NULL, 0, 0);
319 ok(hr == S_OK, "IDirectMusicTrack8_InitPlay failed: %08x\n", hr);
320 hr = IDirectMusicTrack8_EndPlay(dmt8, NULL);
321 ok(hr == S_OK, "IDirectMusicTrack8_EndPlay failed: %08x\n", hr);
322 hr = IDirectMusicTrack8_Play(dmt8, NULL, 0, 0, 0, 0, NULL, NULL, 0);
323 ok(hr == S_OK, "IDirectMusicTrack8_Play failed: %08x\n", hr);
324 hr = IDirectMusicTrack8_GetParam(dmt8, NULL, 0, NULL, NULL);
325 ok(hr == E_POINTER, "IDirectMusicTrack8_GetParam failed: %08x\n", hr);
326 hr = IDirectMusicTrack8_SetParam(dmt8, NULL, 0, NULL);
327 ok(hr == E_POINTER, "IDirectMusicTrack8_SetParam failed: %08x\n", hr);
329 hr = IDirectMusicTrack8_IsParamSupported(dmt8, NULL);
330 ok(hr == E_POINTER, "IDirectMusicTrack8_IsParamSupported failed: %08x\n", hr);
331 hr = IDirectMusicTrack8_IsParamSupported(dmt8, &GUID_IDirectMusicChordMap);
332 ok(hr == S_OK, "IsParamSupported(GUID_IDirectMusicChordMap) failed: %08x, expected S_OK\n", hr);
333 hr = IDirectMusicTrack8_GetParam(dmt8, &GUID_IDirectMusicChordMap, 0, NULL, &chordmap);
334 todo_wine ok(hr == DMUS_E_NOT_FOUND,
335 "GetParam(GUID_IDirectMusicChordMap) failed: %08x, expected DMUS_E_NOT_FOUND\n", hr);
336 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, NULL, CLSCTX_INPROC_SERVER,
337 &IID_IDirectMusicChordMap, (void **)&chordmap);
338 ok(hr == S_OK, "DirectMusicChordMap create failed: %08x, expected S_OK\n", hr);
339 hr = IDirectMusicTrack8_SetParam(dmt8, &GUID_IDirectMusicChordMap, 0, chordmap);
340 ok(hr == S_OK, "SetParam(GUID_IDirectMusicChordMap) failed: %08x, expected S_OK\n", hr);
341 IDirectMusicChordMap_Release(chordmap);
343 for (i = 0; i < ARRAY_SIZE(unsupported); i++) {
344 hr = IDirectMusicTrack8_IsParamSupported(dmt8, unsupported[i].type);
345 ok(hr == DMUS_E_TYPE_UNSUPPORTED,
346 "IsParamSupported(%s) failed: %08x, expected DMUS_E_TYPE_UNSUPPORTED\n",
347 unsupported[i].name, hr);
348 hr = IDirectMusicTrack8_GetParam(dmt8, unsupported[i].type, 0, NULL, &chordmap);
349 ok(hr == DMUS_E_GET_UNSUPPORTED,
350 "GetParam(%s) failed: %08x, expected DMUS_E_GET_UNSUPPORTED\n",
351 unsupported[i].name, hr);
352 hr = IDirectMusicTrack8_SetParam(dmt8, unsupported[i].type, 0, chordmap);
353 ok(hr == DMUS_E_SET_UNSUPPORTED,
354 "SetParam(%s) failed: %08x, expected DMUS_E_SET_UNSUPPORTED\n",
355 unsupported[i].name, hr);
358 hr = IDirectMusicTrack8_AddNotificationType(dmt8, NULL);
359 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_AddNotificationType failed: %08x\n", hr);
360 hr = IDirectMusicTrack8_RemoveNotificationType(dmt8, NULL);
361 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_RemoveNotificationType failed: %08x\n", hr);
362 todo_wine {
363 hr = IDirectMusicTrack8_Clone(dmt8, 0, 0, NULL);
364 ok(hr == E_POINTER, "IDirectMusicTrack8_Clone failed: %08x\n", hr);
365 hr = IDirectMusicTrack8_PlayEx(dmt8, NULL, 0, 0, 0, 0, NULL, NULL, 0);
366 ok(hr == E_POINTER, "IDirectMusicTrack8_PlayEx failed: %08x\n", hr);
367 hr = IDirectMusicTrack8_GetParamEx(dmt8, NULL, 0, NULL, NULL, NULL, 0);
368 ok(hr == E_POINTER, "IDirectMusicTrack8_GetParamEx failed: %08x\n", hr);
369 hr = IDirectMusicTrack8_SetParamEx(dmt8, NULL, 0, NULL, NULL, 0);
370 ok(hr == E_POINTER, "IDirectMusicTrack8_SetParamEx failed: %08x\n", hr);
372 hr = IDirectMusicTrack8_Compose(dmt8, NULL, 0, NULL);
373 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_Compose failed: %08x\n", hr);
374 hr = IDirectMusicTrack8_Join(dmt8, NULL, 0, NULL, 0, NULL);
375 todo_wine ok(hr == E_POINTER, "IDirectMusicTrack8_Join failed: %08x\n", hr);
377 /* IPersistStream */
378 hr = IDirectMusicTrack8_QueryInterface(dmt8, &IID_IPersistStream, (void**)&ps);
379 ok(hr == S_OK, "QueryInterface for IID_IPersistStream failed: %08x\n", hr);
380 hr = IPersistStream_GetClassID(ps, &class);
381 ok(hr == S_OK, "IPersistStream_GetClassID failed: %08x\n", hr);
382 ok(IsEqualGUID(&class, &CLSID_DirectMusicChordMapTrack),
383 "Expected class CLSID_DirectMusicChordMapTrack got %s\n", wine_dbgstr_guid(&class));
385 /* Unimplemented IPersistStream methods */
386 hr = IPersistStream_IsDirty(ps);
387 ok(hr == S_FALSE, "IPersistStream_IsDirty failed: %08x\n", hr);
388 hr = IPersistStream_GetSizeMax(ps, &size);
389 ok(hr == E_NOTIMPL, "IPersistStream_GetSizeMax failed: %08x\n", hr);
390 hr = IPersistStream_Save(ps, NULL, TRUE);
391 ok(hr == E_NOTIMPL, "IPersistStream_Save failed: %08x\n", hr);
393 while (IDirectMusicTrack8_Release(dmt8));
396 static void test_signposttrack(void)
398 IDirectMusicTrack8 *dmt8;
399 IPersistStream *ps;
400 CLSID class;
401 ULARGE_INTEGER size;
402 HRESULT hr;
404 hr = CoCreateInstance(&CLSID_DirectMusicSignPostTrack, NULL, CLSCTX_INPROC_SERVER,
405 &IID_IDirectMusicTrack8, (void**)&dmt8);
406 ok(hr == S_OK, "DirectMusicSignPostTrack create failed: %08x, expected S_OK\n", hr);
408 /* IDirectMusicTrack8 */
409 hr = IDirectMusicTrack8_Init(dmt8, NULL);
410 ok(hr == S_OK, "IDirectMusicTrack8_Init failed: %08x\n", hr);
411 if (0) {
412 /* Crashes on Windows */
413 hr = IDirectMusicTrack8_InitPlay(dmt8, NULL, NULL, NULL, 0, 0);
414 ok(hr == E_POINTER, "IDirectMusicTrack8_InitPlay failed: %08x\n", hr);
416 hr = IDirectMusicTrack8_EndPlay(dmt8, NULL);
417 ok(hr == S_OK, "IDirectMusicTrack8_EndPlay failed: %08x\n", hr);
418 hr = IDirectMusicTrack8_Play(dmt8, NULL, 0, 0, 0, 0, NULL, NULL, 0);
419 ok(hr == S_OK, "IDirectMusicTrack8_Play failed: %08x\n", hr);
420 hr = IDirectMusicTrack8_GetParam(dmt8, NULL, 0, NULL, NULL);
421 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_GetParam failed: %08x\n", hr);
422 hr = IDirectMusicTrack8_SetParam(dmt8, NULL, 0, NULL);
423 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_SetParam failed: %08x\n", hr);
424 hr = IDirectMusicTrack8_IsParamSupported(dmt8, NULL);
425 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_IsParamSupported failed: %08x\n", hr);
426 todo_wine {
427 hr = IDirectMusicTrack8_AddNotificationType(dmt8, NULL);
428 ok(hr == E_POINTER, "IDirectMusicTrack8_AddNotificationType failed: %08x\n", hr);
429 hr = IDirectMusicTrack8_RemoveNotificationType(dmt8, NULL);
430 ok(hr == E_POINTER, "IDirectMusicTrack8_RemoveNotificationType failed: %08x\n", hr);
431 hr = IDirectMusicTrack8_Clone(dmt8, 0, 0, NULL);
432 ok(hr == E_POINTER, "IDirectMusicTrack8_Clone failed: %08x\n", hr);
433 hr = IDirectMusicTrack8_PlayEx(dmt8, NULL, 0, 0, 0, 0, NULL, NULL, 0);
434 ok(hr == E_POINTER, "IDirectMusicTrack8_PlayEx failed: %08x\n", hr);
436 hr = IDirectMusicTrack8_GetParamEx(dmt8, NULL, 0, NULL, NULL, NULL, 0);
437 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_GetParamEx failed: %08x\n", hr);
438 hr = IDirectMusicTrack8_SetParamEx(dmt8, NULL, 0, NULL, NULL, 0);
439 ok(hr == E_NOTIMPL, "IDirectMusicTrack8_SetParamEx failed: %08x\n", hr);
440 todo_wine {
441 hr = IDirectMusicTrack8_Compose(dmt8, NULL, 0, NULL);
442 ok(hr == E_POINTER, "IDirectMusicTrack8_Compose failed: %08x\n", hr);
443 hr = IDirectMusicTrack8_Join(dmt8, NULL, 0, NULL, 0, NULL);
444 ok(hr == E_POINTER, "IDirectMusicTrack8_Join failed: %08x\n", hr);
447 /* IPersistStream */
448 hr = IDirectMusicTrack8_QueryInterface(dmt8, &IID_IPersistStream, (void**)&ps);
449 ok(hr == S_OK, "QueryInterface for IID_IPersistStream failed: %08x\n", hr);
450 hr = IPersistStream_GetClassID(ps, &class);
451 ok(hr == S_OK, "IPersistStream_GetClassID failed: %08x\n", hr);
452 ok(IsEqualGUID(&class, &CLSID_DirectMusicSignPostTrack),
453 "Expected class CLSID_DirectMusicSignPostTrack got %s\n", wine_dbgstr_guid(&class));
454 hr = IPersistStream_Save(ps, NULL, TRUE);
455 ok(hr == E_POINTER, "IPersistStream_Save failed: %08x\n", hr);
457 /* Unimplemented IPersistStream methods */
458 hr = IPersistStream_IsDirty(ps);
459 ok(hr == S_FALSE, "IPersistStream_IsDirty failed: %08x\n", hr);
460 hr = IPersistStream_GetSizeMax(ps, &size);
461 ok(hr == E_NOTIMPL, "IPersistStream_GetSizeMax failed: %08x\n", hr);
463 while (IDirectMusicTrack8_Release(dmt8));
466 struct chunk {
467 FOURCC id;
468 DWORD size;
469 FOURCC type;
472 #define CHUNK_HDR_SIZE (sizeof(FOURCC) + sizeof(DWORD))
474 /* Generate a RIFF file format stream from an array of FOURCC ids.
475 RIFF and LIST need to be followed by the form type respectively list type,
476 followed by the chunks of the list and terminated with 0. */
477 static IStream *gen_riff_stream(const FOURCC *ids)
479 static const LARGE_INTEGER zero;
480 int level = -1;
481 DWORD *sizes[4]; /* Stack for the sizes of RIFF and LIST chunks */
482 char riff[1024];
483 char *p = riff;
484 struct chunk *ck;
485 IStream *stream;
487 do {
488 ck = (struct chunk *)p;
489 ck->id = *ids++;
490 switch (ck->id) {
491 case 0:
492 *sizes[level] = p - (char *)sizes[level] - sizeof(DWORD);
493 level--;
494 break;
495 case FOURCC_LIST:
496 case FOURCC_RIFF:
497 level++;
498 sizes[level] = &ck->size;
499 ck->type = *ids++;
500 p += sizeof(*ck);
501 break;
502 case DMUS_FOURCC_GUID_CHUNK:
503 ck->size = sizeof(GUID_NULL);
504 p += CHUNK_HDR_SIZE;
505 memcpy(p, &GUID_NULL, sizeof(GUID_NULL));
506 p += ck->size;
507 break;
508 case DMUS_FOURCC_VERSION_CHUNK:
510 DMUS_VERSION ver = {5, 8};
512 ck->size = sizeof(ver);
513 p += CHUNK_HDR_SIZE;
514 memcpy(p, &ver, sizeof(ver));
515 p += ck->size;
516 break;
518 default:
520 /* Just convert the FOURCC id to a WCHAR string */
521 WCHAR *s;
523 ck->size = 5 * sizeof(WCHAR);
524 p += CHUNK_HDR_SIZE;
525 s = (WCHAR *)p;
526 s[0] = (char)(ck->id);
527 s[1] = (char)(ck->id >> 8);
528 s[2] = (char)(ck->id >> 16);
529 s[3] = (char)(ck->id >> 24);
530 s[4] = 0;
531 p += ck->size;
534 } while (level >= 0);
536 ck = (struct chunk *)riff;
537 CreateStreamOnHGlobal(NULL, TRUE, &stream);
538 IStream_Write(stream, riff, ck->size + CHUNK_HDR_SIZE, NULL);
539 IStream_Seek(stream, zero, STREAM_SEEK_SET, NULL);
541 return stream;
544 static void test_parsedescriptor(void)
546 IDirectMusicObject *dmo;
547 IStream *stream;
548 DMUS_OBJECTDESC desc = {0};
549 HRESULT hr;
550 const FOURCC alldesc[] =
552 FOURCC_RIFF, DMUS_FOURCC_CHORDMAP_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_CHORDMAP_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_CHORDMAP_FORM, 0};
565 FOURCC inam[] =
567 FOURCC_RIFF, DMUS_FOURCC_CHORDMAP_FORM, FOURCC_LIST, DMUS_FOURCC_UNFO_LIST,
568 mmioFOURCC('I','N','A','M'), 0, 0
571 hr = CoCreateInstance(&CLSID_DirectMusicChordMap, NULL, CLSCTX_INPROC_SERVER,
572 &IID_IDirectMusicObject, (void **)&dmo);
573 ok(hr == S_OK, "DirectMusicChordMap create failed: %08x, expected S_OK\n", hr);
575 /* Nothing loaded */
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_OBJECT\n",
579 desc.dwValidData);
580 ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicChordMap),
581 "Got class guid %s, expected CLSID_DirectMusicChordMap\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",
590 desc.dwValidData);
591 ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicChordMap),
592 "Got class guid %s, expected CLSID_DirectMusicChordMap\n",
593 wine_dbgstr_guid(&desc.guidClass));
594 IStream_Release(stream);
596 /* NULL pointers */
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);
603 /* Wrong form */
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, only DMUS_OBJ_OBJECT and DMUS_OBJ_CLASS 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 ok(desc.dwValidData == (DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS),
617 "Got valid data %#x, expected DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS\n", desc.dwValidData);
618 ok(IsEqualGUID(&desc.guidClass, &CLSID_DirectMusicChordMap),
619 "Got class guid %s, expected CLSID_DirectMusicChordMap\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 IStream_Release(stream);
625 /* UNFO list with INAM */
626 inam[3] = DMUS_FOURCC_UNFO_LIST;
627 stream = gen_riff_stream(inam);
628 memset(&desc, 0, sizeof(desc));
629 hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
630 ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
631 ok(desc.dwValidData == DMUS_OBJ_CLASS, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
632 desc.dwValidData);
633 IStream_Release(stream);
635 /* INFO list with INAM */
636 inam[3] = DMUS_FOURCC_INFO_LIST;
637 stream = gen_riff_stream(inam);
638 memset(&desc, 0, sizeof(desc));
639 hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
640 ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
641 ok(desc.dwValidData == DMUS_OBJ_CLASS, "Got valid data %#x, expected DMUS_OBJ_CLASS\n",
642 desc.dwValidData);
643 IStream_Release(stream);
645 /* Duplicated chunks */
646 stream = gen_riff_stream(dupes);
647 memset(&desc, 0, sizeof(desc));
648 hr = IDirectMusicObject_ParseDescriptor(dmo, stream, &desc);
649 ok(hr == S_OK, "ParseDescriptor failed: %08x, expected S_OK\n", hr);
650 ok(desc.dwValidData == (DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS),
651 "Got valid data %#x, expected DMUS_OBJ_OBJECT | DMUS_OBJ_CLASS\n", desc.dwValidData);
652 IStream_Release(stream);
654 IDirectMusicObject_Release(dmo);
657 START_TEST(dmcompos)
659 CoInitialize(NULL);
661 if (missing_dmcompos())
663 skip("dmcompos not available\n");
664 CoUninitialize();
665 return;
667 test_COM();
668 test_COM_chordmap();
669 test_COM_template();
670 test_COM_track();
671 test_chordmap();
672 test_chordmaptrack();
673 test_signposttrack();
674 test_parsedescriptor();
676 CoUninitialize();