2 * Unit tests for dmusic functions
4 * Copyright (C) 2012 Christian Costa
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 #include "wine/test.h"
32 static inline const char* debugstr_longlong(ULONGLONG ll
)
34 static char string
[17];
35 if (sizeof(ll
) > sizeof(unsigned long) && ll
>> 32)
36 sprintf(string
, "%lx%08lx", (unsigned long)(ll
>> 32), (unsigned long)ll
);
38 sprintf(string
, "%lx", (unsigned long)ll
);
42 static void test_dmusic(void)
44 IDirectMusic
*dmusic
= NULL
;
47 DMUS_PORTCAPS port_caps
;
48 DMUS_PORTPARAMS port_params
;
49 IDirectMusicPort
*port
= NULL
;
50 DMUS_CLOCKINFO clock_info
;
52 IReferenceClock
*clock
= NULL
;
54 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic
, (LPVOID
*)&dmusic
);
55 ok(hr
== S_OK
, "Cannot create DirectMusic object (%x)\n", hr
);
57 hr
= IDirectMusic_GetMasterClock(dmusic
, &guid_clock
, &clock
);
58 ok(hr
== S_OK
, "IDirectMusic_GetMasterClock returned: %x\n", hr
);
59 ok(clock
!= NULL
, "No clock returned\n");
60 trace(" guidPort = %s\n", wine_dbgstr_guid(&guid_clock
));
62 IReferenceClock_Release(clock
);
64 port_params
.dwSize
= sizeof(port_params
);
65 port_params
.dwValidParams
= DMUS_PORTPARAMS_CHANNELGROUPS
| DMUS_PORTPARAMS_AUDIOCHANNELS
;
66 port_params
.dwChannelGroups
= 1;
67 port_params
.dwAudioChannels
= 2;
69 /* No port can be created before SetDirectSound is called */
70 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, &port_params
, &port
, NULL
);
71 ok(hr
== DMUS_E_DSOUND_NOT_SET
, "IDirectMusic_CreatePort returned: %x\n", hr
);
73 hr
= IDirectMusic_SetDirectSound(dmusic
, NULL
, NULL
);
74 ok(hr
== S_OK
, "IDirectMusic_SetDirectSound returned: %x\n", hr
);
76 /* Check wrong params */
77 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, &port_params
, &port
, (IUnknown
*)dmusic
);
78 ok(hr
== CLASS_E_NOAGGREGATION
, "IDirectMusic_CreatePort returned: %x\n", hr
);
79 hr
= IDirectMusic_CreatePort(dmusic
, NULL
, &port_params
, &port
, NULL
);
80 ok(hr
== E_POINTER
, "IDirectMusic_CreatePort returned: %x\n", hr
);
81 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, NULL
, &port
, NULL
);
82 ok(hr
== E_INVALIDARG
, "IDirectMusic_CreatePort returned: %x\n", hr
);
83 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, &port_params
, NULL
, NULL
);
84 ok(hr
== E_POINTER
, "IDirectMusic_CreatePort returned: %x\n", hr
);
86 /* Test creation of default port with GUID_NULL */
87 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, &port_params
, &port
, NULL
);
88 ok(hr
== S_OK
, "IDirectMusic_CreatePort returned: %x\n", hr
);
90 port_caps
.dwSize
= sizeof(port_caps
);
91 while (IDirectMusic_EnumPort(dmusic
, index
, &port_caps
) == S_OK
)
93 ok(port_caps
.dwSize
== sizeof(port_caps
), "DMUS_PORTCAPS dwSize member is wrong (%u)\n", port_caps
.dwSize
);
94 trace("Port %u:\n", index
);
95 trace(" dwFlags = %x\n", port_caps
.dwFlags
);
96 trace(" guidPort = %s\n", wine_dbgstr_guid(&port_caps
.guidPort
));
97 trace(" dwClass = %u\n", port_caps
.dwClass
);
98 trace(" dwType = %u\n", port_caps
.dwType
);
99 trace(" dwMemorySize = %u\n", port_caps
.dwMemorySize
);
100 trace(" dwMaxChannelGroups = %u\n", port_caps
.dwMaxChannelGroups
);
101 trace(" dwMaxVoices = %u\n", port_caps
.dwMaxVoices
);
102 trace(" dwMaxAudioChannels = %u\n", port_caps
.dwMaxAudioChannels
);
103 trace(" dwEffectFlags = %x\n", port_caps
.dwEffectFlags
);
104 trace(" wszDescription = %s\n", wine_dbgstr_w(port_caps
.wszDescription
));
109 clock_info
.dwSize
= sizeof(clock_info
);
110 while (IDirectMusic_EnumMasterClock(dmusic
, index
, &clock_info
) == S_OK
)
112 ok(clock_info
.dwSize
== sizeof(clock_info
), "DMUS_CLOCKINFO dwSize member is wrong (%u)\n", clock_info
.dwSize
);
113 trace("Clock %u:\n", index
);
114 trace(" ctType = %u\n", clock_info
.ctType
);
115 trace(" guidClock = %s\n", wine_dbgstr_guid(&clock_info
.guidClock
));
116 trace(" wszDescription = %s\n", wine_dbgstr_w(clock_info
.wszDescription
));
121 IDirectMusicPort_Release(port
);
122 IDirectMusic_Release(dmusic
);
125 static ULONG
get_refcount(IDirectSound
*iface
)
127 IDirectSound_AddRef(iface
);
128 return IDirectSound_Release(iface
);
131 static void test_setdsound(void)
133 IDirectMusic
*dmusic
;
134 IDirectSound
*dsound
, *dsound2
;
135 DMUS_PORTPARAMS params
;
136 IDirectMusicPort
*port
= NULL
;
140 params
.dwSize
= sizeof(params
);
141 params
.dwValidParams
= DMUS_PORTPARAMS_CHANNELGROUPS
| DMUS_PORTPARAMS_AUDIOCHANNELS
;
142 params
.dwChannelGroups
= 1;
143 params
.dwAudioChannels
= 2;
145 /* Old dsound without SetCooperativeLevel() */
146 hr
= DirectSoundCreate(NULL
, &dsound
, NULL
);
147 if (hr
== DSERR_NODRIVER
) {
151 ok(hr
== S_OK
, "DirectSoundCreate failed: %08x\n", hr
);
152 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic8
,
154 ok(hr
== S_OK
, "DirectMusic create failed: %08x\n", hr
);
155 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
156 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
157 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, ¶ms
, &port
, NULL
);
158 ok(hr
== S_OK
, "CreatePort returned: %x\n", hr
);
159 IDirectMusicPort_Release(port
);
160 IDirectMusic_Release(dmusic
);
161 IDirectSound_Release(dsound
);
163 /* dsound ref counting */
164 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic8
,
166 ok(hr
== S_OK
, "DirectMusic create failed: %08x\n", hr
);
167 hr
= DirectSoundCreate8(NULL
, (IDirectSound8
**)&dsound
, NULL
);
168 ok(hr
== S_OK
, "DirectSoundCreate failed: %08x\n", hr
);
169 hr
= IDirectSound_SetCooperativeLevel(dsound
, GetForegroundWindow(), DSSCL_PRIORITY
);
170 ok(hr
== S_OK
, "SetCooperativeLevel failed: %08x\n", hr
);
171 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
172 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
173 ref
= get_refcount(dsound
);
174 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
175 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, ¶ms
, &port
, NULL
);
176 ok(hr
== S_OK
, "CreatePort returned: %x\n", hr
);
177 ref
= get_refcount(dsound
);
178 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
179 IDirectMusicPort_AddRef(port
);
180 ref
= IDirectMusicPort_Release(port
);
181 ok(ref
== 1, "port ref count got %d expected 1\n", ref
);
182 hr
= IDirectMusicPort_Activate(port
, TRUE
);
183 ok(hr
== S_OK
, "Port Activate returned: %x\n", hr
);
184 ref
= get_refcount(dsound
);
185 ok(ref
== 4, "dsound ref count got %d expected 4\n", ref
);
186 IDirectMusicPort_AddRef(port
);
187 ref
= IDirectMusicPort_Release(port
);
188 ok(ref
== 1, "port ref count got %d expected 1\n", ref
);
190 /* Releasing dsound from dmusic */
191 hr
= IDirectMusic_SetDirectSound(dmusic
, NULL
, NULL
);
192 ok(hr
== DMUS_E_DSOUND_ALREADY_SET
, "SetDirectSound failed: %08x\n", hr
);
193 hr
= IDirectMusicPort_Activate(port
, FALSE
);
194 ok(hr
== S_OK
, "Port Activate returned: %x\n", hr
);
195 ref
= get_refcount(dsound
);
196 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
197 hr
= IDirectMusic_SetDirectSound(dmusic
, NULL
, NULL
);
198 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
199 ref
= get_refcount(dsound
);
200 ok(ref
== 1, "dsound ref count got %d expected 1\n", ref
);
202 /* Setting the same dsound twice */
203 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
204 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
205 ref
= get_refcount(dsound
);
206 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
207 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound
, NULL
);
208 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
209 ref
= get_refcount(dsound
);
210 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
212 /* Replacing one dsound with another */
213 hr
= DirectSoundCreate8(NULL
, (IDirectSound8
**)&dsound2
, NULL
);
214 ok(hr
== S_OK
, "DirectSoundCreate failed: %08x\n", hr
);
215 hr
= IDirectMusic_SetDirectSound(dmusic
, dsound2
, NULL
);
216 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
217 ref
= get_refcount(dsound
);
218 ok(ref
== 1, "dsound ref count got %d expected 1\n", ref
);
219 ref
= get_refcount(dsound2
);
220 ok(ref
== 2, "dsound2 ref count got %d expected 2\n", ref
);
222 /* Replacing the dsound in the port */
223 hr
= IDirectMusicPort_SetDirectSound(port
, dsound
, NULL
);
224 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
225 ref
= get_refcount(dsound
);
226 ok(ref
== 2, "dsound ref count got %d expected 2\n", ref
);
227 ref
= get_refcount(dsound2
);
228 ok(ref
== 2, "dsound2 ref count got %d expected 2\n", ref
);
229 /* Setting the dsound again on the port will mess with the parent dmusic */
230 hr
= IDirectMusicPort_SetDirectSound(port
, dsound
, NULL
);
231 ok(hr
== S_OK
, "SetDirectSound failed: %08x\n", hr
);
232 ref
= get_refcount(dsound
);
233 ok(ref
== 3, "dsound ref count got %d expected 3\n", ref
);
234 ref
= get_refcount(dsound2
);
235 ok(ref
== 1, "dsound2 ref count got %d expected 1\n", ref
);
236 IDirectSound_AddRef(dsound2
); /* Crash prevention */
237 hr
= IDirectMusicPort_Activate(port
, TRUE
);
238 ok(hr
== S_OK
, "Activate returned: %x\n", hr
);
239 ref
= get_refcount(dsound
);
240 ok(ref
== 4, "dsound ref count got %d expected 4\n", ref
);
241 ref
= get_refcount(dsound2
);
242 ok(ref
== 2, "dsound2 ref count got %d expected 2\n", ref
);
243 hr
= IDirectMusicPort_Activate(port
, TRUE
);
244 ok(hr
== S_FALSE
, "Activate returned: %x\n", hr
);
245 ref
= get_refcount(dsound
);
246 ok(ref
== 4, "dsound ref count got %d expected 4\n", ref
);
247 ref
= get_refcount(dsound2
);
248 ok(ref
== 2, "dsound2 ref count got %d expected 2\n", ref
);
250 /* Deactivating the port messes with the dsound refcount in the parent dmusic */
251 hr
= IDirectMusicPort_Activate(port
, FALSE
);
252 ok(hr
== S_OK
, "Port Activate returned: %x\n", hr
);
253 ref
= get_refcount(dsound
);
254 ok(ref
== 3, "dsound ref count got %d expected 3\n", ref
);
255 ref
= get_refcount(dsound2
);
256 ok(ref
== 1, "dsound2 ref count got %d expected 1\n", ref
);
257 hr
= IDirectMusicPort_Activate(port
, FALSE
);
258 ok(hr
== S_FALSE
, "Port Activate returned: %x\n", hr
);
259 ref
= get_refcount(dsound
);
260 ok(ref
== 3, "dsound ref count got %d expected 3\n", ref
);
261 ref
= get_refcount(dsound2
);
262 ok(ref
== 1, "dsound2 ref count got %d expected 1\n", ref
);
264 IDirectMusicPort_Release(port
);
265 IDirectMusic_Release(dmusic
);
266 while (IDirectSound_Release(dsound
));
269 static void test_dmbuffer(void)
271 IDirectMusic
*dmusic
;
272 IDirectMusicBuffer
*dmbuffer
= NULL
;
274 DMUS_BUFFERDESC desc
;
281 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic
, (LPVOID
*)&dmusic
);
282 ok(hr
== S_OK
, "Cannot create DirectMusic object (%x)\n", hr
);
284 desc
.dwSize
= sizeof(DMUS_BUFFERDESC
);
286 desc
.cbBuffer
= 1023;
287 memcpy(&desc
.guidBufferFormat
, &GUID_NULL
, sizeof(GUID
));
289 hr
= IDirectMusic_CreateMusicBuffer(dmusic
, &desc
, &dmbuffer
, NULL
);
290 ok(hr
== S_OK
, "IDirectMusic_CreateMusicBuffer return %x\n", hr
);
292 hr
= IDirectMusicBuffer_GetBufferFormat(dmbuffer
, &format
);
293 ok(hr
== S_OK
, "IDirectMusicBuffer_GetBufferFormat returned %x\n", hr
);
294 ok(IsEqualGUID(&format
, &KSDATAFORMAT_SUBTYPE_MIDI
), "Wrong format returned %s\n", wine_dbgstr_guid(&format
));
295 hr
= IDirectMusicBuffer_GetMaxBytes(dmbuffer
, &size
);
296 ok(hr
== S_OK
, "IDirectMusicBuffer_GetMaxBytes returned %x\n", hr
);
297 ok(size
== 1024, "Buffer size is %u instead of 1024\n", size
);
299 hr
= IDirectMusicBuffer_GetStartTime(dmbuffer
, &time
);
300 ok(hr
== DMUS_E_BUFFER_EMPTY
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
301 hr
= IDirectMusicBuffer_SetStartTime(dmbuffer
, 10);
302 ok(hr
== S_OK
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
303 hr
= IDirectMusicBuffer_GetStartTime(dmbuffer
, &time
);
304 ok(hr
== DMUS_E_BUFFER_EMPTY
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
306 hr
= IDirectMusicBuffer_PackStructured(dmbuffer
, 20, 0, 0);
307 ok(hr
== DMUS_E_INVALID_EVENT
, "IDirectMusicBuffer_PackStructured returned %x\n", hr
);
308 hr
= IDirectMusicBuffer_PackStructured(dmbuffer
, 20, 0, 0x000090); /* note on : chan 0, note 0 & vel 0 */
309 ok(hr
== S_OK
, "IDirectMusicBuffer_PackStructured returned %x\n", hr
);
310 hr
= IDirectMusicBuffer_PackStructured(dmbuffer
, 30, 0, 0x000080); /* note off : chan 0, note 0 & vel 0 */
311 ok(hr
== S_OK
, "IDirectMusicBuffer_PackStructured returned %x\n", hr
);
312 hr
= IDirectMusicBuffer_GetUsedBytes(dmbuffer
, &bytes
);
313 ok(hr
== S_OK
, "IDirectMusicBuffer_GetUsedBytes returned %x\n", hr
);
314 ok(bytes
== 48, "Buffer size is %u instead of 48\n", bytes
);
316 hr
= IDirectMusicBuffer_GetStartTime(dmbuffer
, &time
);
317 ok(hr
== S_OK
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
318 ok(time
== 20, "Buffer start time is wrong\n");
319 hr
= IDirectMusicBuffer_SetStartTime(dmbuffer
, 40);
320 ok(hr
== S_OK
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
321 hr
= IDirectMusicBuffer_GetStartTime(dmbuffer
, &time
);
322 ok(hr
== S_OK
, "IDirectMusicBuffer_GetStartTime returned %x\n", hr
);
323 ok(time
== 40, "Buffer start time is wrong\n");
325 hr
= IDirectMusicBuffer_GetRawBufferPtr(dmbuffer
, &data
);
326 ok(hr
== S_OK
, "IDirectMusicBuffer_GetRawBufferPtr returned %x\n", hr
);
329 DMUS_EVENTHEADER
* header
;
332 /* Check message 1 */
333 header
= (DMUS_EVENTHEADER
*)data
;
334 data
+= sizeof(DMUS_EVENTHEADER
);
335 ok(header
->cbEvent
== 3, "cbEvent is %u instead of 3\n", header
->cbEvent
);
336 ok(header
->dwChannelGroup
== 0, "dwChannelGroup is %u instead of 0\n", header
->dwChannelGroup
);
337 ok(header
->rtDelta
== 0, "rtDelta is %s instead of 0\n", debugstr_longlong(header
->rtDelta
));
338 ok(header
->dwFlags
== DMUS_EVENT_STRUCTURED
, "dwFlags is %x instead of %x\n", header
->dwFlags
, DMUS_EVENT_STRUCTURED
);
339 message
= *(DWORD
*)data
& 0xffffff; /* Only 3 bytes are relevant */
340 data
+= sizeof(DWORD
);
341 ok(message
== 0x000090, "Message is %0x instead of 0x000090\n", message
);
343 /* Check message 2 */
344 header
= (DMUS_EVENTHEADER
*)data
;
345 data
+= sizeof(DMUS_EVENTHEADER
);
346 ok(header
->cbEvent
== 3, "cbEvent is %u instead of 3\n", header
->cbEvent
);
347 ok(header
->dwChannelGroup
== 0, "dwChannelGroup is %u instead of 0\n", header
->dwChannelGroup
);
348 ok(header
->rtDelta
== 10, "rtDelta is %s instead of 0\n", debugstr_longlong(header
->rtDelta
));
349 ok(header
->dwFlags
== DMUS_EVENT_STRUCTURED
, "dwFlags is %x instead of %x\n", header
->dwFlags
, DMUS_EVENT_STRUCTURED
);
350 message
= *(DWORD
*)data
& 0xffffff; /* Only 3 bytes are relevant */
351 ok(message
== 0x000080, "Message 2 is %0x instead of 0x000080\n", message
);
355 IDirectMusicBuffer_Release(dmbuffer
);
356 IDirectMusic_Release(dmusic
);
359 static void test_COM(void)
361 IDirectMusic8
*dm8
= (IDirectMusic8
*)0xdeadbeef;
367 /* COM aggregation */
368 hr
= CoCreateInstance(&CLSID_DirectMusic
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
, &IID_IUnknown
,
370 ok(hr
== CLASS_E_NOAGGREGATION
,
371 "DirectMusic8 create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
372 ok(!dm8
, "dm8 = %p\n", dm8
);
375 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusicObject
,
377 ok(hr
== E_NOINTERFACE
, "DirectMusic8 create failed: %08x, expected E_NOINTERFACE\n", hr
);
379 /* Same refcount for DirectMusic and DirectMusic8 */
380 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic8
,
382 if (hr
== E_NOINTERFACE
)
384 win_skip("DirectMusic too old (no IDirectMusic8)\n");
387 ok(hr
== S_OK
, "DirectMusic8 create failed: %08x, expected S_OK\n", hr
);
388 refcount
= IDirectMusic8_AddRef(dm8
);
389 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
391 hr
= IDirectMusic8_QueryInterface(dm8
, &IID_IDirectMusic
, (void**)&dm
);
392 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusic failed: %08x\n", hr
);
393 refcount
= IDirectMusic_AddRef(dm
);
394 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
395 IDirectMusic_Release(dm
);
397 hr
= IDirectMusic8_QueryInterface(dm8
, &IID_IUnknown
, (void**)&unk
);
398 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
399 refcount
= IUnknown_AddRef(unk
);
400 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
401 refcount
= IUnknown_Release(unk
);
403 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
404 while (IDirectMusic8_Release(dm8
));
407 static void test_COM_dmcoll(void)
409 IDirectMusicCollection
*dmc
= (IDirectMusicCollection
*)0xdeadbeef;
410 IDirectMusicObject
*dmo
;
416 /* COM aggregation */
417 hr
= CoCreateInstance(&CLSID_DirectMusicCollection
, (IUnknown
*)0xdeadbeef, CLSCTX_INPROC_SERVER
,
418 &IID_IUnknown
, (void**)&dmc
);
419 ok(hr
== CLASS_E_NOAGGREGATION
,
420 "DirectMusicCollection create failed: %08x, expected CLASS_E_NOAGGREGATION\n", hr
);
421 ok(!dmc
, "dmc = %p\n", dmc
);
424 hr
= CoCreateInstance(&CLSID_DirectMusicCollection
, NULL
, CLSCTX_INPROC_SERVER
,
425 &IID_IClassFactory
, (void**)&dmc
);
426 ok(hr
== E_NOINTERFACE
, "DirectMusicCollection create failed: %08x, expected E_NOINTERFACE\n", hr
);
428 /* Same refcount for all DirectMusicCollection interfaces */
429 hr
= CoCreateInstance(&CLSID_DirectMusicCollection
, NULL
, CLSCTX_INPROC_SERVER
,
430 &IID_IDirectMusicCollection
, (void**)&dmc
);
431 ok(hr
== S_OK
, "DirectMusicCollection create failed: %08x, expected S_OK\n", hr
);
432 refcount
= IDirectMusicCollection_AddRef(dmc
);
433 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
435 hr
= IDirectMusicCollection_QueryInterface(dmc
, &IID_IDirectMusicObject
, (void**)&dmo
);
436 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicObject failed: %08x\n", hr
);
437 refcount
= IDirectMusicObject_AddRef(dmo
);
438 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
439 refcount
= IDirectMusicObject_Release(dmo
);
441 hr
= IDirectMusicCollection_QueryInterface(dmc
, &IID_IPersistStream
, (void**)&ps
);
442 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
443 refcount
= IPersistStream_AddRef(ps
);
444 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
445 refcount
= IPersistStream_Release(ps
);
447 hr
= IDirectMusicCollection_QueryInterface(dmc
, &IID_IUnknown
, (void**)&unk
);
448 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
449 refcount
= IUnknown_AddRef(unk
);
450 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
451 refcount
= IUnknown_Release(unk
);
453 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
454 while (IDirectMusicCollection_Release(dmc
));
457 static void test_dmcoll(void)
459 IDirectMusicCollection
*dmc
;
460 IDirectMusicObject
*dmo
;
462 DMUS_OBJECTDESC desc
;
467 hr
= CoCreateInstance(&CLSID_DirectMusicCollection
, NULL
, CLSCTX_INPROC_SERVER
,
468 &IID_IDirectMusicCollection
, (void**)&dmc
);
469 ok(hr
== S_OK
, "DirectMusicCollection create failed: %08x, expected S_OK\n", hr
);
471 /* IDirectMusicObject */
472 hr
= IDirectMusicCollection_QueryInterface(dmc
, &IID_IDirectMusicObject
, (void**)&dmo
);
473 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicObject failed: %08x\n", hr
);
474 hr
= IDirectMusicObject_GetDescriptor(dmo
, NULL
);
475 ok(hr
== E_POINTER
, "IDirectMusicObject_GetDescriptor: expected E_POINTER, got %08x\n", hr
);
476 hr
= IDirectMusicObject_SetDescriptor(dmo
, NULL
);
477 ok(hr
== E_POINTER
, "IDirectMusicObject_SetDescriptor: expected E_POINTER, got %08x\n", hr
);
478 ZeroMemory(&desc
, sizeof(desc
));
479 hr
= IDirectMusicObject_GetDescriptor(dmo
, &desc
);
480 ok(hr
== S_OK
, "IDirectMusicObject_GetDescriptor failed: %08x\n", hr
);
481 ok(desc
.dwValidData
== DMUS_OBJ_CLASS
,
482 "Fresh object has more valid data (%08x) than DMUS_OBJ_CLASS\n", desc
.dwValidData
);
483 /* DMUS_OBJ_CLASS is immutable */
484 desc
.dwValidData
= DMUS_OBJ_CLASS
;
485 hr
= IDirectMusicObject_SetDescriptor(dmo
, &desc
);
486 ok(hr
== S_FALSE
, "IDirectMusicObject_SetDescriptor failed: %08x\n", hr
);
487 ok(!desc
.dwValidData
, "dwValidData wasn't cleared: %08x\n", desc
.dwValidData
);
488 desc
.dwValidData
= DMUS_OBJ_CLASS
;
489 desc
.guidClass
= CLSID_DirectMusicSegment
;
490 hr
= IDirectMusicObject_SetDescriptor(dmo
, &desc
);
491 ok(hr
== S_FALSE
&& !desc
.dwValidData
, "IDirectMusicObject_SetDescriptor failed: %08x\n", hr
);
492 hr
= IDirectMusicObject_GetDescriptor(dmo
, &desc
);
493 ok(hr
== S_OK
, "IDirectMusicObject_GetDescriptor failed: %08x\n", hr
);
494 ok(IsEqualGUID(&desc
.guidClass
, &CLSID_DirectMusicCollection
),
495 "guidClass changed, should be CLSID_DirectMusicCollection\n");
497 /* Unimplemented IPersistStream methods*/
498 hr
= IDirectMusicCollection_QueryInterface(dmc
, &IID_IPersistStream
, (void**)&ps
);
499 ok(hr
== S_OK
, "QueryInterface for IID_IPersistStream failed: %08x\n", hr
);
500 hr
= IPersistStream_GetClassID(ps
, &class);
501 ok(hr
== E_NOTIMPL
, "IPersistStream_GetClassID failed: %08x\n", hr
);
502 hr
= IPersistStream_IsDirty(ps
);
503 ok(hr
== S_FALSE
, "IPersistStream_IsDirty failed: %08x\n", hr
);
504 hr
= IPersistStream_GetSizeMax(ps
, &size
);
505 ok(hr
== E_NOTIMPL
, "IPersistStream_GetSizeMax failed: %08x\n", hr
);
506 hr
= IPersistStream_Save(ps
, NULL
, TRUE
);
507 ok(hr
== E_NOTIMPL
, "IPersistStream_Save failed: %08x\n", hr
);
509 while (IDirectMusicCollection_Release(dmc
));
512 static BOOL
missing_dmusic(void)
515 HRESULT hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic
,
518 if (hr
== S_OK
&& dm
)
520 IDirectMusic_Release(dm
);
526 static void test_COM_synthport(void)
528 IDirectMusic
*dmusic
= NULL
;
529 IDirectMusicPort
*port
= NULL
;
530 IDirectMusicPortDownload
*dmpd
;
531 IDirectMusicThru
*dmt
;
533 IReferenceClock
*clock
;
535 DMUS_PORTPARAMS port_params
;
539 /* Create a IDirectMusicPort */
540 hr
= CoCreateInstance(&CLSID_DirectMusic
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IDirectMusic
,
542 ok(hr
== S_OK
, "Cannot create DirectMusic object (%x)\n", hr
);
543 port_params
.dwSize
= sizeof(port_params
);
544 port_params
.dwValidParams
= DMUS_PORTPARAMS_CHANNELGROUPS
| DMUS_PORTPARAMS_AUDIOCHANNELS
;
545 port_params
.dwChannelGroups
= 1;
546 port_params
.dwAudioChannels
= 2;
547 hr
= IDirectMusic_SetDirectSound(dmusic
, NULL
, NULL
);
548 ok(hr
== S_OK
, "IDirectMusic_SetDirectSound returned: %x\n", hr
);
549 hr
= IDirectMusic_CreatePort(dmusic
, &GUID_NULL
, &port_params
, &port
, NULL
);
550 ok(hr
== S_OK
, "IDirectMusic_CreatePort returned: %x\n", hr
);
552 /* Same refcount for all DirectMusicPort interfaces */
553 refcount
= IDirectMusicPort_AddRef(port
);
554 ok(refcount
== 2, "refcount == %u, expected 2\n", refcount
);
556 hr
= IDirectMusicPort_QueryInterface(port
, &IID_IDirectMusicPortDownload
, (void**)&dmpd
);
557 ok(hr
== S_OK
, "QueryInterface for IID_IDirectMusicPortDownload failed: %08x\n", hr
);
558 refcount
= IDirectMusicPortDownload_AddRef(dmpd
);
559 ok(refcount
== 4, "refcount == %u, expected 4\n", refcount
);
560 IDirectMusicPortDownload_Release(dmpd
);
562 hr
= IDirectMusicPort_QueryInterface(port
, &IID_IKsControl
, (void**)&iksc
);
563 ok(hr
== S_OK
, "QueryInterface for IID_IKsControl failed: %08x\n", hr
);
564 refcount
= IKsControl_AddRef(iksc
);
565 ok(refcount
== 5, "refcount == %u, expected 5\n", refcount
);
566 IKsControl_Release(iksc
);
568 hr
= IDirectMusicPort_QueryInterface(port
, &IID_IUnknown
, (void**)&unk
);
569 ok(hr
== S_OK
, "QueryInterface for IID_IUnknown failed: %08x\n", hr
);
570 refcount
= IUnknown_AddRef(unk
);
571 ok(refcount
== 6, "refcount == %u, expected 6\n", refcount
);
572 IUnknown_Release(unk
);
574 /* Unsupported interface */
575 hr
= IDirectMusicPort_QueryInterface(port
, &IID_IDirectMusicThru
, (void**)&dmt
);
576 todo_wine
ok(hr
== E_NOINTERFACE
, "QueryInterface for IID_IDirectMusicThru failed: %08x\n", hr
);
577 hr
= IDirectMusicPort_QueryInterface(port
, &IID_IReferenceClock
, (void**)&clock
);
578 ok(hr
== E_NOINTERFACE
, "QueryInterface for IID_IReferenceClock failed: %08x\n", hr
);
580 while (IDirectMusicPort_Release(port
));
585 CoInitializeEx(NULL
, COINIT_MULTITHREADED
);
587 if (missing_dmusic())
589 skip("DirectMusic not available\n");
595 test_COM_synthport();