Authors: Mike McCormack <mike@codeweavers.com>, Aric Stewart <aric@codeweavers.com...
[wine] / dlls / dsound / tests / propset.c
1 /*
2  * Unit tests for CLSID_DirectSoundPrivate property set functions
3  * (used by dxdiag)
4  *
5  * Copyright (c) 2003 Robert Reif
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21
22 #define NONAMELESSSTRUCT
23 #define NONAMELESSUNION
24 #include <windows.h>
25
26 #include "wine/test.h"
27 #include "dsound.h"
28 #include "initguid.h"
29 #include "dsconf.h"
30 #include "dxerr8.h"
31
32 #include "dsound_test.h"
33
34 #ifndef DSBCAPS_CTRLDEFAULT
35 #define DSBCAPS_CTRLDEFAULT \
36         DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME
37 #endif
38
39 DEFINE_GUID(DSPROPSETID_VoiceManager, \
40             0x62A69BAE,0xDF9D,0x11D1,0x99,0xA6,0x00,0xC0,0x4F,0xC9,0x9D,0x46);
41 DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties, \
42             0x306a6a8,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
43 DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties, \
44             0x306a6a7,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
45 DEFINE_GUID(DSPROPSETID_I3DL2_ListenerProperties, \
46             0xDA0F0520,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
47 DEFINE_GUID(DSPROPSETID_I3DL2_BufferProperties, \
48             0xDA0F0521,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
49 DEFINE_GUID(DSPROPSETID_ZOOMFX_BufferProperties, \
50             0xCD5368E0,0x3450,0x11D3,0x8B,0x6E,0x00,0x10,0x5A,0x9B,0x7B,0xBC);
51
52 typedef HRESULT  (CALLBACK * MYPROC)(REFCLSID, REFIID, LPVOID *);
53
54 BOOL CALLBACK callback(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA data,
55                        LPVOID context)
56 {
57     trace("found device:\n");
58     trace("\tType: %s\n",
59           data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
60           data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
61           data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
62     trace("\tDataFlow: %s\n",
63           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
64           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
65           "Capture" : "Unknown");
66     trace("\tDeviceId: {%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
67           data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
68           data->DeviceId.Data4[0],data->DeviceId.Data4[1],
69           data->DeviceId.Data4[2],data->DeviceId.Data4[3],
70           data->DeviceId.Data4[4],data->DeviceId.Data4[5],
71           data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
72     trace("\tDescription: %s\n", data->Description);
73     trace("\tModule: %s\n", data->Module);
74     trace("\tInterface: %s\n", data->Interface);
75     trace("\tWaveDeviceId: %ld\n", data->WaveDeviceId);
76
77     return TRUE;
78 }
79
80 static void propset_private_tests()
81 {
82     HMODULE hDsound;
83     HRESULT rc;
84     IClassFactory * pcf;
85     IKsPropertySet * pps;
86     MYPROC fProc;
87     ULONG support;
88
89     hDsound = LoadLibrary("dsound.dll");
90     ok(hDsound!=0,"LoadLibrary(dsound.dll) failed\n");
91     if (hDsound==0)
92         return;
93
94     fProc = (MYPROC)GetProcAddress(hDsound, "DllGetClassObject");
95
96     /* try direct sound first */
97     rc = (fProc)(&CLSID_DirectSound, &IID_IClassFactory, (void **)0);
98     ok(rc==DSERR_INVALIDPARAM,"DllGetClassObject(CLSID_DirectSound, "
99        "IID_IClassFactory) should have returned DSERR_INVALIDPARAM, "
100        "returned: %s\n",DXGetErrorString8(rc));
101
102     rc = (fProc)(&CLSID_DirectSound, &IID_IClassFactory, (void **)(&pcf));
103     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound, IID_IClassFactory) "
104        "failed: %s\n",DXGetErrorString8(rc));
105     if (pcf==0)
106         goto error;
107
108     /* direct sound doesn't have an IKsPropertySet */
109     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
110                                      (void **)0);
111     ok(rc==DSERR_INVALIDPARAM, "CreateInstance(IID_IKsPropertySet) should have "
112        "returned DSERR_INVALIDPARAM, returned: %s\n",DXGetErrorString8(rc));
113
114     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
115                                      (void **)(&pps));
116     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
117        "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
118
119     /* and the direct sound 8 version */
120     rc = (fProc)(&CLSID_DirectSound8, &IID_IClassFactory, (void **)(&pcf));
121     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
122        "failed: %s\n",DXGetErrorString8(rc));
123     if (pcf==0)
124         goto error;
125
126     /* direct sound 8 doesn't have an IKsPropertySet */
127     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
128                                      (void **)(&pps));
129     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
130        "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
131
132     /* try direct sound capture next */
133     rc = (fProc)(&CLSID_DirectSoundCapture, &IID_IClassFactory,
134                  (void **)(&pcf));
135     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture, IID_IClassFactory) "
136        "failed: %s\n",DXGetErrorString8(rc));
137     if (pcf==0)
138         goto error;
139
140     /* direct sound capture doesn't have an IKsPropertySet */
141     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
142                                      (void **)(&pps));
143     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
144        "returned E_NOINTERFACE,returned: %s\n",DXGetErrorString8(rc));
145
146     /* and the direct sound capture 8 version */
147     rc = (fProc)(&CLSID_DirectSoundCapture8, &IID_IClassFactory,
148                  (void **)(&pcf));
149     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture8, "
150        "IID_IClassFactory) failed: %s\n",DXGetErrorString8(rc));
151     if (pcf==0)
152         goto error;
153
154     /* direct sound capture 8 doesn't have an IKsPropertySet */
155     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
156                                      (void **)(&pps));
157     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
158        "returned E_NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
159
160     /* try direct sound full duplex next */
161     rc = (fProc)(&CLSID_DirectSoundFullDuplex, &IID_IClassFactory,
162                  (void **)(&pcf));
163     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundFullDuplex, "
164        "IID_IClassFactory) failed: %s\n",DXGetErrorString8(rc));
165     if (pcf==0)
166         goto error;
167
168     /* direct sound full duplex doesn't have an IKsPropertySet */
169     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
170                                      (void **)(&pps));
171     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
172        "returned NOINTERFACE, returned: %s\n",DXGetErrorString8(rc));
173
174     /* try direct sound private last */
175     rc = (fProc)(&CLSID_DirectSoundPrivate, &IID_IClassFactory,
176                  (void **)(&pcf));
177     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundPrivate, "
178        "IID_IClassFactory) failed: %s\n",DXGetErrorString8(rc));
179     if (pcf==0)
180         goto error;
181
182     /* direct sound private does have an IKsPropertySet */
183     rc = pcf->lpVtbl->CreateInstance(pcf, NULL, &IID_IKsPropertySet,
184                                      (void **)(&pps));
185     ok(rc==DS_OK, "CreateInstance(IID_IKsPropertySet) failed: %s\n",
186        DXGetErrorString8(rc));
187     if (rc!=DS_OK)
188         goto error;
189
190     rc = pps->lpVtbl->QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
191                                    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
192                                    &support);
193     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
194        "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION) failed: %s\n",
195        DXGetErrorString8(rc));
196     if (rc!=DS_OK)
197         goto error;
198
199     ok(support & KSPROPERTY_SUPPORT_GET,
200        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
201        "support = 0x%lx\n",support);
202     ok(!(support & KSPROPERTY_SUPPORT_SET),
203        "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
204        "support = 0x%lx\n",support);
205
206     rc = pps->lpVtbl->QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
207         DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING, &support);
208     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
209        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING) failed: %s\n",
210        DXGetErrorString8(rc));
211     if (rc!=DS_OK)
212         goto error;
213
214     ok(support & KSPROPERTY_SUPPORT_GET,
215        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: "
216        "support = 0x%lx\n",support);
217     ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
218        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: support = "
219        "0x%lx\n",support);
220
221     rc = pps->lpVtbl->QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
222                                    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
223                                    &support);
224     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
225        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE) failed: %s\n",
226        DXGetErrorString8(rc));
227     if (rc!=DS_OK)
228         goto error;
229
230     ok(support & KSPROPERTY_SUPPORT_GET,
231        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: "
232        "support = 0x%lx\n",support);
233     ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
234        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: support = 0x%lx\n",support);
235
236     if (support & KSPROPERTY_SUPPORT_GET) {
237         DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA data;
238         ULONG bytes;
239
240         data.Callback = callback;
241         data.Context = 0;
242
243         rc = pps->lpVtbl->Get(pps, &DSPROPSETID_DirectSoundDevice,
244                               DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
245                               NULL, 0, &data, sizeof(data), &bytes);
246         ok(rc==DS_OK, "Couldn't enumerate: 0x%lx\n",rc);
247     }
248
249 error:
250     FreeLibrary(hDsound);
251 }
252
253 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
254                                    LPCSTR lpcstrModule, LPVOID lpContext)
255 {
256     HRESULT rc;
257     LPDIRECTSOUND dso=NULL;
258     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
259     DSBUFFERDESC bufdesc;
260     WAVEFORMATEX wfx;
261     int ref;
262
263     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
264
265     rc=DirectSoundCreate(lpGuid,&dso,NULL);
266     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED,
267        "DirectSoundCreate() failed: %s\n",DXGetErrorString8(rc));
268     if (rc!=DS_OK) {
269         if (rc==DSERR_NODRIVER)
270             trace("  No Driver\n");
271         else if (rc == DSERR_ALLOCATED)
272             trace("  Already In Use\n");
273         goto EXIT;
274     }
275
276     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
277     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
278     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
279     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %s\n",
280        DXGetErrorString8(rc));
281     if (rc!=DS_OK)
282         goto EXIT;
283
284     /* Testing 3D buffers */
285     primary=NULL;
286     ZeroMemory(&bufdesc, sizeof(bufdesc));
287     bufdesc.dwSize=sizeof(bufdesc);
288     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_LOCHARDWARE|DSBCAPS_CTRL3D;
289     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
290     ok(rc==DS_OK&&primary!=NULL,"IDirectSound_CreateSoundBuffer() failed to "
291        "create a hardware 3D primary buffer: %s\n",DXGetErrorString8(rc));
292     if (rc==DS_OK&&primary!=NULL) {
293         ZeroMemory(&wfx, sizeof(wfx));
294         wfx.wFormatTag=WAVE_FORMAT_PCM;
295         wfx.nChannels=1;
296         wfx.wBitsPerSample=16;
297         wfx.nSamplesPerSec=44100;
298         wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
299         wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
300         ZeroMemory(&bufdesc, sizeof(bufdesc));
301         bufdesc.dwSize=sizeof(bufdesc);
302         bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
303         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
304         bufdesc.lpwfxFormat=&wfx;
305         trace("  Testing a secondary buffer at %ldx%dx%d\n",
306             wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
307         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
308         ok(rc==DS_OK&&secondary!=NULL,"IDirectSound_CreateSoundBuffer() "
309            "failed to create a secondary buffer: %s\n",DXGetErrorString8(rc));
310         if (rc==DS_OK&&secondary!=NULL) {
311             IKsPropertySet * pPropertySet=NULL;
312             rc=IDirectSoundBuffer_QueryInterface(secondary,
313                                                  &IID_IKsPropertySet,
314                                                  (void **)&pPropertySet);
315             /* it's not an error for this to fail */
316             if(rc==DS_OK) {
317                 ULONG ulTypeSupport;
318                 trace("  Supports property sets\n");
319                 /* it's not an error for these to fail */
320                 rc=IKsPropertySet_QuerySupport(pPropertySet,
321                                                &DSPROPSETID_VoiceManager,
322                                                0,&ulTypeSupport);
323                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
324                                                 KSPROPERTY_SUPPORT_SET)))
325                     trace("    DSPROPSETID_VoiceManager supported\n");
326                 else
327                     trace("    DSPROPSETID_VoiceManager not supported\n");
328                 rc=IKsPropertySet_QuerySupport(pPropertySet,
329                     &DSPROPSETID_EAX20_ListenerProperties,0,&ulTypeSupport);
330                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
331                     KSPROPERTY_SUPPORT_SET)))
332                     trace("    DSPROPSETID_EAX20_ListenerProperties "
333                           "supported\n");
334                 else
335                     trace("    DSPROPSETID_EAX20_ListenerProperties not "
336                           "supported\n");
337                 rc=IKsPropertySet_QuerySupport(pPropertySet,
338                     &DSPROPSETID_EAX20_BufferProperties,0,&ulTypeSupport);
339                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
340                     KSPROPERTY_SUPPORT_SET)))
341                     trace("    DSPROPSETID_EAX20_BufferProperties supported\n");
342                 else
343                     trace("    DSPROPSETID_EAX20_BufferProperties not "
344                           "supported\n");
345                 rc=IKsPropertySet_QuerySupport(pPropertySet,
346                     &DSPROPSETID_I3DL2_ListenerProperties,0,&ulTypeSupport);
347                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
348                     KSPROPERTY_SUPPORT_SET)))
349                     trace("    DSPROPSETID_I3DL2_ListenerProperties "
350                           "supported\n");
351                 else
352                     trace("    DSPROPSETID_I3DL2_ListenerProperties not "
353                           "supported\n");
354                 rc=IKsPropertySet_QuerySupport(pPropertySet,
355                     &DSPROPSETID_I3DL2_BufferProperties,0,&ulTypeSupport);
356                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
357                     KSPROPERTY_SUPPORT_SET)))
358                     trace("    DSPROPSETID_I3DL2_BufferProperties supported\n");
359                 else
360                     trace("    DSPROPSETID_I3DL2_BufferProperties not "
361                           "supported\n");
362                 rc=IKsPropertySet_QuerySupport(pPropertySet,
363                     &DSPROPSETID_ZOOMFX_BufferProperties,0,&ulTypeSupport);
364                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
365                     KSPROPERTY_SUPPORT_SET)))
366                     trace("    DSPROPSETID_ZOOMFX_BufferProperties "
367                           "supported\n");
368                 else
369                     trace("    DSPROPSETID_ZOOMFX_BufferProperties not "
370                           "supported\n");
371                 ref=IKsPropertySet_Release(pPropertySet);
372                 /* try a few common ones */
373                 ok(ref==0,"IKsPropertySet_Release() secondary has %d "
374                    "references, should have 0\n",ref);
375             } else
376                 trace("  Doesn't support property sets\n");
377
378             ref=IDirectSoundBuffer_Release(secondary);
379             ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d "
380                "references, should have 0\n",ref);
381         }
382
383         ref=IDirectSoundBuffer_Release(primary);
384         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
385            "should have 0\n",ref);
386     }
387
388 EXIT:
389     if (dso!=NULL) {
390         ref=IDirectSound_Release(dso);
391         ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
392            ref);
393     }
394     return 1;
395 }
396
397 static void propset_buffer_tests()
398 {
399     HRESULT rc;
400     rc=DirectSoundEnumerateA(&dsenum_callback,NULL);
401     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %s\n",DXGetErrorString8(rc));
402 }
403
404 START_TEST(propset)
405 {
406     CoInitialize(NULL);
407
408     propset_private_tests();
409     propset_buffer_tests();
410
411     CoUninitialize();
412 }