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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21 
22 #include "dsound_test.h"
23 
24 #include <winnls.h>
25 
26 #ifndef DSBCAPS_CTRLDEFAULT
27 #define DSBCAPS_CTRLDEFAULT \
28         DSBCAPS_CTRLFREQUENCY|DSBCAPS_CTRLPAN|DSBCAPS_CTRLVOLUME
29 #endif
30 
31 #include <initguid.h>
32 
33 DEFINE_GUID(DSPROPSETID_VoiceManager,
34             0x62A69BAE,0xDF9D,0x11D1,0x99,0xA6,0x00,0xC0,0x4F,0xC9,0x9D,0x46);
35 DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties,
36             0x306a6a8,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
37 DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties,
38             0x306a6a7,0xb224,0x11d2,0x99,0xe5,0x0,0x0,0xe8,0xd8,0xc7,0x22);
39 DEFINE_GUID(DSPROPSETID_I3DL2_ListenerProperties,
40             0xDA0F0520,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
41 DEFINE_GUID(DSPROPSETID_I3DL2_BufferProperties,
42             0xDA0F0521,0x300A,0x11D3,0x8A,0x2B,0x00,0x60,0x97,0x0D,0xB0,0x11);
43 DEFINE_GUID(DSPROPSETID_ZOOMFX_BufferProperties,
44             0xCD5368E0,0x3450,0x11D3,0x8B,0x6E,0x00,0x10,0x5A,0x9B,0x7B,0xBC);
45 
46 static HRESULT (WINAPI *pDirectSoundEnumerateA)(LPDSENUMCALLBACKA,LPVOID)=NULL;
47 static HRESULT (WINAPI *pDllGetClassObject)(REFCLSID,REFIID,LPVOID*)=NULL;
48 static HRESULT (WINAPI *pDirectSoundCreate)(LPCGUID,LPDIRECTSOUND*,
49     LPUNKNOWN)=NULL;
50 static HRESULT (WINAPI *pDirectSoundCreate8)(LPCGUID,LPDIRECTSOUND8*,
51     LPUNKNOWN)=NULL;
52 static HRESULT (WINAPI *pDirectSoundCaptureCreate)(LPCGUID,
53     LPDIRECTSOUNDCAPTURE*,LPUNKNOWN)=NULL;
54 static HRESULT (WINAPI *pDirectSoundCaptureCreate8)(LPCGUID,
55     LPDIRECTSOUNDCAPTURE8*,LPUNKNOWN)=NULL;
56 static HRESULT (WINAPI *pDirectSoundFullDuplexCreate)(LPCGUID,LPCGUID,
57     LPCDSCBUFFERDESC,LPCDSBUFFERDESC,HWND,DWORD,LPDIRECTSOUNDFULLDUPLEX*,
58     LPDIRECTSOUNDCAPTUREBUFFER8*,LPDIRECTSOUNDBUFFER8*,LPUNKNOWN)=NULL;
59 
60 static BOOL CALLBACK callback(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA data,
61                        LPVOID context)
62 {
63     trace("  found device:\n");
64     trace("    Type: %s\n",
65           data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
66           data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
67           data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
68     trace("    DataFlow: %s\n",
69           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
70           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
71           "Capture" : "Unknown");
72     trace("    DeviceId: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
73           data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
74           data->DeviceId.Data4[0],data->DeviceId.Data4[1],
75           data->DeviceId.Data4[2],data->DeviceId.Data4[3],
76           data->DeviceId.Data4[4],data->DeviceId.Data4[5],
77           data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
78     trace("    Description: %s\n", data->Description);
79     trace("    Module: %s\n", data->Module);
80     trace("    Interface: %s\n", data->Interface);
81     trace("    WaveDeviceId: %d\n", data->WaveDeviceId);
82 
83     return TRUE;
84 }
85 
86 static BOOL CALLBACK callback1(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data,
87                         LPVOID context)
88 {
89     char descriptionA[0x100];
90     char moduleA[MAX_PATH];
91 
92     trace("  found device:\n");
93     trace("    Type: %s\n",
94           data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
95           data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
96           data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
97     trace("    DataFlow: %s\n",
98           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
99           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
100           "Capture" : "Unknown");
101     trace("    DeviceId: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
102           data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
103           data->DeviceId.Data4[0],data->DeviceId.Data4[1],
104           data->DeviceId.Data4[2],data->DeviceId.Data4[3],
105           data->DeviceId.Data4[4],data->DeviceId.Data4[5],
106           data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
107     trace("    DescriptionA: %s\n", data->DescriptionA);
108     WideCharToMultiByte(CP_ACP, 0, data->DescriptionW, -1, descriptionA, sizeof(descriptionA), NULL, NULL);
109     trace("    DescriptionW: %s\n", descriptionA);
110     trace("    ModuleA: %s\n", data->ModuleA);
111     WideCharToMultiByte(CP_ACP, 0, data->ModuleW, -1, moduleA, sizeof(moduleA), NULL, NULL);
112     trace("    ModuleW: %s\n", moduleA);
113     trace("    WaveDeviceId: %d\n", data->WaveDeviceId);
114 
115     return TRUE;
116 }
117 
118 static BOOL CALLBACK callbackA(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data,
119                         LPVOID context)
120 {
121     trace("  found device:\n");
122     trace("    Type: %s\n",
123           data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
124           data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
125           data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
126     trace("    DataFlow: %s\n",
127           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
128           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
129           "Capture" : "Unknown");
130     trace("    DeviceId: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
131           data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
132           data->DeviceId.Data4[0],data->DeviceId.Data4[1],
133           data->DeviceId.Data4[2],data->DeviceId.Data4[3],
134           data->DeviceId.Data4[4],data->DeviceId.Data4[5],
135           data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
136     trace("    Description: %s\n", data->Description);
137     trace("    Module: %s\n", data->Module);
138     trace("    Interface: %s\n", data->Interface);
139     trace("    WaveDeviceId: %d\n", data->WaveDeviceId);
140 
141     return TRUE;
142 }
143 
144 static BOOL CALLBACK callbackW(PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data,
145                         LPVOID context)
146 {
147     char descriptionA[0x100];
148     char moduleA[MAX_PATH];
149     char interfaceA[MAX_PATH];
150 
151     trace("found device:\n");
152     trace("\tType: %s\n",
153           data->Type == DIRECTSOUNDDEVICE_TYPE_EMULATED ? "Emulated" :
154           data->Type == DIRECTSOUNDDEVICE_TYPE_VXD ? "VxD" :
155           data->Type == DIRECTSOUNDDEVICE_TYPE_WDM ? "WDM" : "Unknown");
156     trace("\tDataFlow: %s\n",
157           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "Render" :
158           data->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ?
159           "Capture" : "Unknown");
160     trace("\tDeviceId: {%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
161           data->DeviceId.Data1,data->DeviceId.Data2,data->DeviceId.Data3,
162           data->DeviceId.Data4[0],data->DeviceId.Data4[1],
163           data->DeviceId.Data4[2],data->DeviceId.Data4[3],
164           data->DeviceId.Data4[4],data->DeviceId.Data4[5],
165           data->DeviceId.Data4[6],data->DeviceId.Data4[7]);
166     WideCharToMultiByte(CP_ACP, 0, data->Description, -1, descriptionA, sizeof(descriptionA), NULL, NULL);
167     WideCharToMultiByte(CP_ACP, 0, data->Module, -1, moduleA, sizeof(moduleA), NULL, NULL);
168     WideCharToMultiByte(CP_ACP, 0, data->Interface, -1, interfaceA, sizeof(interfaceA), NULL, NULL);
169     trace("\tDescription: %s\n", descriptionA);
170     trace("\tModule: %s\n", moduleA);
171     trace("\tInterface: %s\n", interfaceA);
172     trace("\tWaveDeviceId: %d\n", data->WaveDeviceId);
173 
174     return TRUE;
175 }
176 
177 static void propset_private_tests(void)
178 {
179     HRESULT rc;
180     IClassFactory * pcf;
181     IKsPropertySet * pps;
182     ULONG support;
183 
184     /* try direct sound first */
185     /* DSOUND: Error: Invalid interface buffer */
186     rc = (pDllGetClassObject)(&CLSID_DirectSound, &IID_IClassFactory, NULL);
187     ok(rc==DSERR_INVALIDPARAM,"DllGetClassObject(CLSID_DirectSound, "
188        "IID_IClassFactory) should have returned DSERR_INVALIDPARAM, "
189        "returned: %08x\n",rc);
190 
191     rc = (pDllGetClassObject)(&CLSID_DirectSound, &IID_IDirectSound, (void **)(&pcf));
192     ok(rc==E_NOINTERFACE,"DllGetClassObject(CLSID_DirectSound, "
193        "IID_IDirectSound) should have returned E_NOINTERFACE, "
194        "returned: %08x\n",rc);
195 
196     rc = (pDllGetClassObject)(&CLSID_DirectSound, &IID_IUnknown, (void **)(&pcf));
197     ok(rc==DS_OK,"DllGetClassObject(CLSID_DirectSound, "
198        "IID_IUnknown) failed: %08x\n",rc);
199 
200     rc = (pDllGetClassObject)(&CLSID_DirectSound, &IID_IClassFactory, (void **)(&pcf));
201     ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound, IID_IClassFactory) "
202        "failed: %08x\n",rc);
203     if (pcf==0)
204         return;
205 
206     /* direct sound doesn't have an IKsPropertySet */
207     /* DSOUND: Error: Invalid interface buffer */
208     rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
209                                      NULL);
210     ok(rc==DSERR_INVALIDPARAM, "CreateInstance(IID_IKsPropertySet) should have "
211        "returned DSERR_INVALIDPARAM, returned: %08x\n",rc);
212 
213     rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
214                                      (void **)(&pps));
215     ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
216        "returned E_NOINTERFACE, returned: %08x\n",rc);
217 
218     /* and the direct sound 8 version */
219     if (pDirectSoundCreate8) {
220         rc = (pDllGetClassObject)(&CLSID_DirectSound8, &IID_IClassFactory, (void **)(&pcf));
221         ok(pcf!=0, "DllGetClassObject(CLSID_DirectSound8, IID_IClassFactory) "
222            "failed: %08x\n",rc);
223         if (pcf==0)
224             return;
225 
226         /* direct sound 8 doesn't have an IKsPropertySet */
227         rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
228                                          (void **)(&pps));
229         ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
230            "returned E_NOINTERFACE, returned: %08x\n",rc);
231     }
232 
233     /* try direct sound capture next */
234     if (pDirectSoundCaptureCreate) {
235         rc = (pDllGetClassObject)(&CLSID_DirectSoundCapture, &IID_IClassFactory,
236                      (void **)(&pcf));
237         ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture, IID_IClassFactory) "
238            "failed: %08x\n",rc);
239         if (pcf==0)
240             return;
241 
242         /* direct sound capture doesn't have an IKsPropertySet */
243         rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
244                                          (void **)(&pps));
245         ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
246            "returned E_NOINTERFACE,returned: %08x\n",rc);
247     }
248 
249     /* and the direct sound capture 8 version */
250     if (pDirectSoundCaptureCreate8) {
251         rc = (pDllGetClassObject)(&CLSID_DirectSoundCapture8, &IID_IClassFactory,
252                      (void **)(&pcf));
253         ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundCapture8, "
254            "IID_IClassFactory) failed: %08x\n",rc);
255         if (pcf==0)
256             return;
257 
258         /* direct sound capture 8 doesn't have an IKsPropertySet */
259         rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
260                                          (void **)(&pps));
261         ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
262            "returned E_NOINTERFACE, returned: %08x\n",rc);
263     }
264 
265     /* try direct sound full duplex next */
266     if (pDirectSoundFullDuplexCreate) {
267         rc = (pDllGetClassObject)(&CLSID_DirectSoundFullDuplex, &IID_IClassFactory,
268                      (void **)(&pcf));
269         ok(pcf!=0, "DllGetClassObject(CLSID_DirectSoundFullDuplex, "
270            "IID_IClassFactory) failed: %08x\n",rc);
271         if (pcf==0)
272             return;
273 
274         /* direct sound full duplex doesn't have an IKsPropertySet */
275         rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
276                                          (void **)(&pps));
277         ok(rc==E_NOINTERFACE, "CreateInstance(IID_IKsPropertySet) should have "
278            "returned NOINTERFACE, returned: %08x\n",rc);
279     }
280 
281     /* try direct sound private last */
282     rc = (pDllGetClassObject)(&CLSID_DirectSoundPrivate, &IID_IClassFactory,
283                  (void **)(&pcf));
284 
285     /* some early versions of Direct Sound do not have this */
286     if (rc==CLASS_E_CLASSNOTAVAILABLE)
287         return;
288 
289     /* direct sound private does have an IKsPropertySet */
290     rc = IClassFactory_CreateInstance(pcf, NULL, &IID_IKsPropertySet,
291                                      (void **)(&pps));
292     ok(rc==DS_OK, "CreateInstance(IID_IKsPropertySet) failed: %08x\n",
293        rc);
294     if (rc!=DS_OK)
295         return;
296 
297     /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION */
298     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
299                                    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION,
300                                    &support);
301     ok(rc==DS_OK||rc==E_INVALIDARG,
302        "QuerySupport(DSPROPSETID_DirectSoundDevice, "
303        "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION) failed: %08x\n",
304        rc);
305     if (rc!=DS_OK) {
306         if (rc==E_INVALIDARG)
307             trace("  Not Supported\n");
308         return;
309     }
310 
311     ok(support & KSPROPERTY_SUPPORT_GET,
312        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
313        "support = 0x%x\n",support);
314     ok(!(support & KSPROPERTY_SUPPORT_SET),
315        "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION: "
316        "support = 0x%x\n",support);
317 
318     /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 */
319     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
320                                    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1,
321                                    &support);
322     ok(rc==DS_OK||rc==E_INVALIDARG,
323        "QuerySupport(DSPROPSETID_DirectSoundDevice, "
324        "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1) failed: %08x\n",
325        rc);
326     if (rc!=DS_OK) {
327         if (rc==E_INVALIDARG)
328             trace("  Not Supported\n");
329         return;
330     }
331 
332     ok(support & KSPROPERTY_SUPPORT_GET,
333        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: "
334        "support = 0x%x\n",support);
335     ok(!(support & KSPROPERTY_SUPPORT_SET),
336        "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1: "
337        "support = 0x%x\n",support);
338 
339     /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A */
340     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
341                                    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A,
342                                    &support);
343     ok(rc==DS_OK||rc==E_INVALIDARG,
344        "QuerySupport(DSPROPSETID_DirectSoundDevice, "
345        "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A) failed: %08x\n",
346        rc);
347     if (rc!=DS_OK) {
348         if (rc==E_INVALIDARG)
349             trace("  Not Supported\n");
350         return;
351     }
352 
353     ok(support & KSPROPERTY_SUPPORT_GET,
354        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: "
355        "support = 0x%x\n",support);
356     ok(!(support & KSPROPERTY_SUPPORT_SET),
357        "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A: "
358        "support = 0x%x\n",support);
359 
360     /* test DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W */
361     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
362                                    DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W,
363                                    &support);
364     ok(rc==DS_OK||rc==E_INVALIDARG,
365        "QuerySupport(DSPROPSETID_DirectSoundDevice, "
366        "DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W) failed: %08x\n",
367        rc);
368     if (rc!=DS_OK) {
369         if (rc==E_INVALIDARG)
370             trace("  Not Supported\n");
371         return;
372     }
373 
374     ok(support & KSPROPERTY_SUPPORT_GET,
375        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: "
376        "support = 0x%x\n",support);
377     ok(!(support & KSPROPERTY_SUPPORT_SET),
378        "Shouldn't be able to set DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W: "
379        "support = 0x%x\n",support);
380 
381     /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING */
382     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
383         DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING, &support);
384     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
385        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING) failed: %08x\n",
386        rc);
387     if (rc!=DS_OK)
388         return;
389 
390     ok(support & KSPROPERTY_SUPPORT_GET,
391        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: "
392        "support = 0x%x\n",support);
393     ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
394        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING: support = "
395        "0x%x\n",support);
396 
397     /* test DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A */
398     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
399         DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A, &support);
400     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
401        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A) failed: %08x\n",
402        rc);
403     if (rc!=DS_OK)
404         return;
405 
406     ok(support & KSPROPERTY_SUPPORT_GET,
407        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: "
408        "support = 0x%x\n",support);
409     ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
410        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A: support = "
411        "0x%x\n",support);
412 
413     /* test DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W */
414     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
415         DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W, &support);
416     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
417        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W) failed: %08x\n",
418        rc);
419     if (rc!=DS_OK)
420         return;
421 
422     ok(support & KSPROPERTY_SUPPORT_GET,
423        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: "
424        "support = 0x%x\n",support);
425     ok(!(support & KSPROPERTY_SUPPORT_SET), "Shouldn't be able to set "
426        "DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W: support = "
427        "0x%x\n",support);
428 
429     /* test generic DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE */
430     trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE ***\n");
431     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
432                                    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
433                                    &support);
434     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
435        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE) failed: %08x\n",
436        rc);
437     if (rc!=DS_OK)
438         return;
439 
440     ok(support & KSPROPERTY_SUPPORT_GET,
441        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: "
442        "support = 0x%x\n",support);
443     ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
444        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE: support = 0x%x\n",support);
445 
446     if (support & KSPROPERTY_SUPPORT_GET) {
447         DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_DATA data;
448         ULONG bytes;
449 
450         data.Callback = callback;
451         data.Context = 0;
452 
453         rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
454                               DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE,
455                               NULL, 0, &data, sizeof(data), &bytes);
456         ok(rc==DS_OK, "Couldn't enumerate: 0x%x\n",rc);
457     }
458 
459     /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 */
460     trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 ***\n");
461     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
462                                    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1,
463                                    &support);
464     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
465        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1) failed: %08x\n",
466        rc);
467     if (rc!=DS_OK)
468         return;
469 
470     ok(support & KSPROPERTY_SUPPORT_GET,
471        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: "
472        "support = 0x%x\n",support);
473     ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
474        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1: support = 0x%x\n",support);
475 
476     if (support & KSPROPERTY_SUPPORT_GET) {
477         DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA data;
478         ULONG bytes;
479 
480         data.Callback = callback1;
481         data.Context = 0;
482 
483         rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
484                               DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1,
485                               NULL, 0, &data, sizeof(data), &bytes);
486         ok(rc==DS_OK, "Couldn't enumerate: 0x%x\n",rc);
487     }
488 
489     /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A */
490     trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A ***\n");
491     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
492                                    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A,
493                                    &support);
494     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
495        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A) failed: %08x\n",
496        rc);
497     if (rc!=DS_OK)
498         return;
499 
500     ok(support & KSPROPERTY_SUPPORT_GET,
501        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: "
502        "support = 0x%x\n",support);
503     ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
504        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A: support = 0x%x\n",support);
505 
506     if (support & KSPROPERTY_SUPPORT_GET) {
507         DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA data;
508         ULONG bytes;
509 
510         data.Callback = callbackA;
511         data.Context = 0;
512 
513         rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
514                               DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A,
515                               NULL, 0, &data, sizeof(data), &bytes);
516         ok(rc==DS_OK, "Couldn't enumerate: 0x%x\n",rc);
517     }
518 
519     /* test DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W */
520     trace("*** Testing DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W ***\n");
521     rc = IKsPropertySet_QuerySupport(pps, &DSPROPSETID_DirectSoundDevice,
522                                    DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W,
523                                    &support);
524     ok(rc==DS_OK, "QuerySupport(DSPROPSETID_DirectSoundDevice, "
525        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W) failed: %08x\n",
526        rc);
527     if (rc!=DS_OK)
528         return;
529 
530     ok(support & KSPROPERTY_SUPPORT_GET,
531        "Couldn't get DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: "
532        "support = 0x%x\n",support);
533     ok(!(support & KSPROPERTY_SUPPORT_SET),"Shouldn't be able to set "
534        "DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W: support = 0x%x\n",support);
535 
536     if (support & KSPROPERTY_SUPPORT_GET) {
537         DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
538         ULONG bytes;
539 
540         data.Callback = callbackW;
541         data.Context = 0;
542 
543         rc = IKsPropertySet_Get(pps, &DSPROPSETID_DirectSoundDevice,
544                               DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W,
545                               NULL, 0, &data, sizeof(data), &bytes);
546         ok(rc==DS_OK, "Couldn't enumerate: 0x%x\n",rc);
547     }
548     IKsPropertySet_Release(pps);
549 }
550 
551 static unsigned driver_count = 0;
552 
553 static BOOL WINAPI dsenum_callback(LPGUID lpGuid, LPCSTR lpcstrDescription,
554                                    LPCSTR lpcstrModule, LPVOID lpContext)
555 {
556     HRESULT rc;
557     LPDIRECTSOUND dso=NULL;
558     LPDIRECTSOUNDBUFFER primary=NULL,secondary=NULL;
559     DSBUFFERDESC bufdesc;
560     WAVEFORMATEX wfx;
561     int ref;
562 
563     trace("*** Testing %s - %s ***\n",lpcstrDescription,lpcstrModule);
564     driver_count++;
565 
566     rc=pDirectSoundCreate(lpGuid,&dso,NULL);
567     ok(rc==DS_OK||rc==DSERR_NODRIVER||rc==DSERR_ALLOCATED||rc==E_FAIL,
568        "DirectSoundCreate() failed: %08x\n",rc);
569     if (rc!=DS_OK) {
570         if (rc==DSERR_NODRIVER)
571             trace("  No Driver\n");
572         else if (rc == DSERR_ALLOCATED)
573             trace("  Already In Use\n");
574         else if (rc == E_FAIL)
575             trace("  No Device\n");
576         goto EXIT;
577     }
578 
579     /* We must call SetCooperativeLevel before calling CreateSoundBuffer */
580     /* DSOUND: Setting DirectSound cooperative level to DSSCL_PRIORITY */
581     rc=IDirectSound_SetCooperativeLevel(dso,get_hwnd(),DSSCL_PRIORITY);
582     ok(rc==DS_OK,"IDirectSound_SetCooperativeLevel() failed: %08x\n",
583        rc);
584     if (rc!=DS_OK)
585         goto EXIT;
586 
587     /* Testing 3D buffers */
588     primary=NULL;
589     ZeroMemory(&bufdesc, sizeof(bufdesc));
590     bufdesc.dwSize=sizeof(bufdesc);
591     bufdesc.dwFlags=DSBCAPS_PRIMARYBUFFER|DSBCAPS_LOCHARDWARE|DSBCAPS_CTRL3D;
592     rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&primary,NULL);
593     ok((rc==DS_OK&&primary!=NULL)
594        || broken(rc==DSERR_INVALIDPARAM),
595        "IDirectSound_CreateSoundBuffer() failed to "
596        "create a hardware 3D primary buffer: %08x\n",rc);
597     if(rc==DSERR_INVALIDPARAM) {
598        skip("broken driver\n");
599        goto EXIT;
600     }
601     if (rc==DS_OK&&primary!=NULL) {
602         ZeroMemory(&wfx, sizeof(wfx));
603         wfx.wFormatTag=WAVE_FORMAT_PCM;
604         wfx.nChannels=1;
605         wfx.wBitsPerSample=16;
606         wfx.nSamplesPerSec=44100;
607         wfx.nBlockAlign=wfx.nChannels*wfx.wBitsPerSample/8;
608         wfx.nAvgBytesPerSec=wfx.nSamplesPerSec*wfx.nBlockAlign;
609         ZeroMemory(&bufdesc, sizeof(bufdesc));
610         bufdesc.dwSize=sizeof(bufdesc);
611         bufdesc.dwFlags=DSBCAPS_CTRLDEFAULT|DSBCAPS_GETCURRENTPOSITION2;
612         bufdesc.dwBufferBytes=wfx.nAvgBytesPerSec;
613         bufdesc.lpwfxFormat=&wfx;
614         trace("  Testing a secondary buffer at %dx%dx%d\n",
615             wfx.nSamplesPerSec,wfx.wBitsPerSample,wfx.nChannels);
616         rc=IDirectSound_CreateSoundBuffer(dso,&bufdesc,&secondary,NULL);
617         ok((rc==DS_OK && secondary!=NULL) || broken(rc == DSERR_CONTROLUNAVAIL), /* vmware drivers on w2k */
618            "IDirectSound_CreateSoundBuffer() failed to create a secondary buffer: %08x\n",rc);
619         if (rc==DS_OK&&secondary!=NULL) {
620             IKsPropertySet * pPropertySet=NULL;
621             rc=IDirectSoundBuffer_QueryInterface(secondary,
622                                                  &IID_IKsPropertySet,
623                                                  (void **)&pPropertySet);
624             /* it's not an error for this to fail */
625             if(rc==DS_OK) {
626                 ULONG ulTypeSupport;
627                 trace("  Supports property sets\n");
628                 /* it's not an error for these to fail */
629                 rc=IKsPropertySet_QuerySupport(pPropertySet,
630                                                &DSPROPSETID_VoiceManager,
631                                                0,&ulTypeSupport);
632                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
633                                                 KSPROPERTY_SUPPORT_SET)))
634                     trace("    DSPROPSETID_VoiceManager supported\n");
635                 else
636                     trace("    DSPROPSETID_VoiceManager not supported\n");
637                 rc=IKsPropertySet_QuerySupport(pPropertySet,
638                     &DSPROPSETID_EAX20_ListenerProperties,0,&ulTypeSupport);
639                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
640                     KSPROPERTY_SUPPORT_SET)))
641                     trace("    DSPROPSETID_EAX20_ListenerProperties "
642                           "supported\n");
643                 else
644                     trace("    DSPROPSETID_EAX20_ListenerProperties not "
645                           "supported\n");
646                 rc=IKsPropertySet_QuerySupport(pPropertySet,
647                     &DSPROPSETID_EAX20_BufferProperties,0,&ulTypeSupport);
648                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
649                     KSPROPERTY_SUPPORT_SET)))
650                     trace("    DSPROPSETID_EAX20_BufferProperties supported\n");
651                 else
652                     trace("    DSPROPSETID_EAX20_BufferProperties not "
653                           "supported\n");
654                 rc=IKsPropertySet_QuerySupport(pPropertySet,
655                     &DSPROPSETID_I3DL2_ListenerProperties,0,&ulTypeSupport);
656                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
657                     KSPROPERTY_SUPPORT_SET)))
658                     trace("    DSPROPSETID_I3DL2_ListenerProperties "
659                           "supported\n");
660                 else
661                     trace("    DSPROPSETID_I3DL2_ListenerProperties not "
662                           "supported\n");
663                 rc=IKsPropertySet_QuerySupport(pPropertySet,
664                     &DSPROPSETID_I3DL2_BufferProperties,0,&ulTypeSupport);
665                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
666                     KSPROPERTY_SUPPORT_SET)))
667                     trace("    DSPROPSETID_I3DL2_BufferProperties supported\n");
668                 else
669                     trace("    DSPROPSETID_I3DL2_BufferProperties not "
670                           "supported\n");
671                 rc=IKsPropertySet_QuerySupport(pPropertySet,
672                     &DSPROPSETID_ZOOMFX_BufferProperties,0,&ulTypeSupport);
673                 if((rc==DS_OK)&&(ulTypeSupport&(KSPROPERTY_SUPPORT_GET|
674                     KSPROPERTY_SUPPORT_SET)))
675                     trace("    DSPROPSETID_ZOOMFX_BufferProperties "
676                           "supported\n");
677                 else
678                     trace("    DSPROPSETID_ZOOMFX_BufferProperties not "
679                           "supported\n");
680                 ref=IKsPropertySet_Release(pPropertySet);
681                 /* try a few common ones */
682                 ok(ref==0,"IKsPropertySet_Release() secondary has %d "
683                    "references, should have 0\n",ref);
684             } else
685                 trace("  Doesn't support property sets\n");
686 
687             ref=IDirectSoundBuffer_Release(secondary);
688             ok(ref==0,"IDirectSoundBuffer_Release() secondary has %d "
689                "references, should have 0\n",ref);
690         }
691 
692         ref=IDirectSoundBuffer_Release(primary);
693         ok(ref==0,"IDirectSoundBuffer_Release() primary has %d references, "
694            "should have 0\n",ref);
695     }
696 
697 EXIT:
698     if (dso!=NULL) {
699         ref=IDirectSound_Release(dso);
700         ok(ref==0,"IDirectSound_Release() has %d references, should have 0\n",
701            ref);
702     }
703     return 1;
704 }
705 
706 static void propset_buffer_tests(void)
707 {
708     HRESULT rc;
709     rc=pDirectSoundEnumerateA(&dsenum_callback,NULL);
710     ok(rc==DS_OK,"DirectSoundEnumerateA() failed: %08x\n",rc);
711     trace("tested %u DirectSound drivers\n", driver_count);
712 }
713 
714 START_TEST(propset)
715 {
716     HMODULE hDsound;
717 
718     CoInitialize(NULL);
719 
720     hDsound = LoadLibrary("dsound.dll");
721     if (hDsound)
722     {
723 
724         pDirectSoundEnumerateA = (void*)GetProcAddress(hDsound,
725             "DirectSoundEnumerateA");
726         pDllGetClassObject = (void *)GetProcAddress(hDsound,
727             "DllGetClassObject");
728         pDirectSoundCreate = (void*)GetProcAddress(hDsound,
729             "DirectSoundCreate");
730         pDirectSoundCreate8 = (void*)GetProcAddress(hDsound,
731             "DirectSoundCreate8");
732         pDirectSoundCaptureCreate=(void*)GetProcAddress(hDsound,
733             "DirectSoundCaptureCreate");
734         pDirectSoundCaptureCreate8=(void*)GetProcAddress(hDsound,
735             "DirectSoundCaptureCreate8");
736         pDirectSoundFullDuplexCreate=(void*)GetProcAddress(hDsound,
737             "DirectSoundFullDuplexCreate");
738 
739         propset_private_tests();
740         propset_buffer_tests();
741 
742         FreeLibrary(hDsound);
743     }
744     else
745         skip("dsound.dll not found - skipping all tests\n");
746 
747     CoUninitialize();
748 }
749