mshtml: Rename call_event to fire_event.
[wine] / dlls / dsound / propset.c
1 /*                      DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2002 TransGaming Technologies, Inc.
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 #define COBJMACROS
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "mmsystem.h"
29 #include "winternl.h"
30 #include "winnls.h"
31 #include "vfwmsgs.h"
32 #include "mmddk.h"
33 #include "wine/debug.h"
34 #include "dsound.h"
35 #include "dsdriver.h"
36 #include "dsound_private.h"
37 #include "dsconf.h"
38
39 #ifdef NONAMELESSSTRUCT
40 # define S(x) (x).s
41 #else
42 # define S(x) (x)
43 #endif
44
45 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
46
47 typedef struct IKsPrivatePropertySetImpl
48 {
49     IKsPropertySet IKsPropertySet_iface;
50     LONG ref;
51 } IKsPrivatePropertySetImpl;
52
53 static IKsPrivatePropertySetImpl *impl_from_IKsPropertySet(IKsPropertySet *iface)
54 {
55     return CONTAINING_RECORD(iface, IKsPrivatePropertySetImpl, IKsPropertySet_iface);
56 }
57
58 /*******************************************************************************
59  *              IKsPrivatePropertySet
60  */
61
62 /* IUnknown methods */
63 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
64     LPKSPROPERTYSET iface,
65     REFIID riid,
66     LPVOID *ppobj )
67 {
68     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
69     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
70
71     if (IsEqualIID(riid, &IID_IUnknown) ||
72         IsEqualIID(riid, &IID_IKsPropertySet)) {
73         *ppobj = iface;
74         IUnknown_AddRef(iface);
75         return S_OK;
76     }
77     *ppobj = NULL;
78     return E_NOINTERFACE;
79 }
80
81 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
82 {
83     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
84     ULONG ref = InterlockedIncrement(&(This->ref));
85     TRACE("(%p) ref was %d\n", This, ref - 1);
86     return ref;
87 }
88
89 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
90 {
91     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
92     ULONG ref = InterlockedDecrement(&(This->ref));
93     TRACE("(%p) ref was %d\n", This, ref + 1);
94
95     if (!ref) {
96         HeapFree(GetProcessHeap(), 0, This);
97         TRACE("(%p) released\n", This);
98     }
99     return ref;
100 }
101
102 static HRESULT DSPROPERTY_WaveDeviceMappingW(
103     LPVOID pPropData,
104     ULONG cbPropData,
105     PULONG pcbReturned )
106 {
107     HRESULT hr = DSERR_INVALIDPARAM;
108     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
109     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
110           pPropData,cbPropData,pcbReturned);
111
112     ppd = pPropData;
113
114     if (!ppd) {
115         WARN("invalid parameter: pPropData\n");
116         return DSERR_INVALIDPARAM;
117     }
118
119     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
120         ULONG wod;
121         unsigned int wodn;
122         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
123         wodn = waveOutGetNumDevs();
124         for (wod = 0; wod < wodn; wod++) {
125             WAVEOUTCAPSW capsW;
126             MMRESULT res;
127             res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
128             if (res == MMSYSERR_NOERROR) {
129                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
130                     ppd->DeviceId = DSOUND_renderer_guids[wod];
131                     hr = DS_OK;
132                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
133                           debugstr_w(ppd->DeviceName));
134                     break;
135                 }
136             }
137         }
138     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
139         ULONG wid;
140         unsigned int widn;
141         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
142         widn = waveInGetNumDevs();
143         for (wid = 0; wid < widn; wid++) {
144             WAVEINCAPSW capsW;
145             MMRESULT res;
146             res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
147             if (res == MMSYSERR_NOERROR) {
148                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
149                     ppd->DeviceId = DSOUND_capture_guids[wid];
150                     hr = DS_OK;
151                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
152                           debugstr_w(ppd->DeviceName));
153                     break;
154                 }
155             }
156         }
157     }
158
159     if (pcbReturned)
160         *pcbReturned = cbPropData;
161
162     return hr;
163 }
164
165 static HRESULT DSPROPERTY_WaveDeviceMappingA(
166     LPVOID pPropData,
167     ULONG cbPropData,
168     PULONG pcbReturned )
169 {
170     DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
171     DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
172     DWORD len;
173     HRESULT hr;
174
175     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
176       pPropData,cbPropData,pcbReturned);
177
178     if (!ppd || !ppd->DeviceName) {
179         WARN("invalid parameter: ppd=%p\n", ppd);
180         return DSERR_INVALIDPARAM;
181     }
182
183     data.DataFlow = ppd->DataFlow;
184     len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0);
185     data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
186     if (!data.DeviceName)
187         return E_OUTOFMEMORY;
188     MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len);
189
190     hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
191     HeapFree(GetProcessHeap(), 0, data.DeviceName);
192     ppd->DeviceId = data.DeviceId;
193
194     if (pcbReturned)
195         *pcbReturned = cbPropData;
196
197     return hr;
198 }
199
200 static HRESULT DSPROPERTY_DescriptionW(
201     LPVOID pPropData,
202     ULONG cbPropData,
203     PULONG pcbReturned )
204 {
205     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
206     HRESULT err;
207     GUID dev_guid;
208     ULONG wod, wid, wodn, widn;
209     DSDRIVERDESC desc;
210
211     TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
212           pPropData,cbPropData,pcbReturned);
213
214     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
215     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
216         /* default device of type specified by ppd->DataFlow */
217         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
218             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
219             ppd->DeviceId = DSDEVID_DefaultCapture;
220         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
221             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
222             ppd->DeviceId = DSDEVID_DefaultPlayback;
223         } else {
224             WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
225             return E_PROP_ID_UNSUPPORTED;
226         }
227     }
228
229     setup_dsound_options();
230
231     GetDeviceID(&ppd->DeviceId, &dev_guid);
232
233     wodn = waveOutGetNumDevs();
234     widn = waveInGetNumDevs();
235     wid = wod = dev_guid.Data4[7];
236     if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1)
237         && wod < wodn)
238     {
239         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
240         ppd->WaveDeviceId = wod;
241     }
242     else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1)
243              && wid < widn)
244     {
245         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
246         ppd->WaveDeviceId = wid;
247     }
248     else
249     {
250         WARN("Device not found\n");
251         return E_PROP_ID_UNSUPPORTED;
252     }
253
254     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
255         err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
256     else
257         err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,ds_hw_accel);
258
259     if (err != MMSYSERR_NOERROR)
260     {
261         WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
262         return E_PROP_ID_UNSUPPORTED;
263     }
264     else
265     {
266         /* FIXME: Still a memory leak.. */
267         int desclen, modlen;
268         static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
269
270         modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 );
271         desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 );
272         ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
273         ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
274         ppd->Interface = wInterface;
275         if (!ppd->Description || !ppd->Module)
276         {
277             WARN("Out of memory\n");
278             HeapFree(GetProcessHeap(), 0, ppd->Description);
279             HeapFree(GetProcessHeap(), 0, ppd->Module);
280             ppd->Description = ppd->Module = NULL;
281             return E_OUTOFMEMORY;
282         }
283
284         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
285         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
286     }
287
288     ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
289
290     if (pcbReturned) {
291         *pcbReturned = sizeof(*ppd);
292         TRACE("*pcbReturned=%d\n", *pcbReturned);
293     }
294
295     return S_OK;
296 }
297
298 static HRESULT DSPROPERTY_EnumerateW(
299     LPVOID pPropData,
300     ULONG cbPropData,
301     PULONG pcbReturned )
302 {
303     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
304     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
305     BOOL ret;
306     int widn, wodn, i;
307     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
308           pPropData,cbPropData,pcbReturned);
309
310     if (pcbReturned)
311         *pcbReturned = 0;
312
313     if (!ppd || !ppd->Callback)
314     {
315         WARN("Invalid ppd %p\n", ppd);
316         return E_PROP_ID_UNSUPPORTED;
317     }
318
319     wodn = waveOutGetNumDevs();
320     widn = waveInGetNumDevs();
321
322     data.DeviceId = DSOUND_renderer_guids[0];
323     for (i = 0; i < wodn; ++i)
324     {
325         HRESULT hr;
326         data.DeviceId.Data4[7] = i;
327         hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
328         if (FAILED(hr))
329         {
330             ERR("DescriptionW failed!\n");
331             return S_OK;
332         }
333         ret = ppd->Callback(&data, ppd->Context);
334         HeapFree(GetProcessHeap(), 0, data.Module);
335         HeapFree(GetProcessHeap(), 0, data.Description);
336         if (!ret)
337             return S_OK;
338     }
339
340     data.DeviceId = DSOUND_capture_guids[0];
341     for (i = 0; i < widn; ++i)
342     {
343         HRESULT hr;
344         data.DeviceId.Data4[7] = i;
345         hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
346         if (FAILED(hr))
347         {
348             ERR("DescriptionW failed!\n");
349             return S_OK;
350         }
351         ret = ppd->Callback(&data, ppd->Context);
352         HeapFree(GetProcessHeap(), 0, data.Module);
353         HeapFree(GetProcessHeap(), 0, data.Description);
354         if (!ret)
355             return S_OK;
356     }
357     return S_OK;
358 }
359
360 static BOOL DSPROPERTY_descWtoA(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
361                                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
362 {
363     DWORD modlen, desclen;
364     static char Interface[] = "Interface";
365
366     modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL);
367     desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL);
368     dataA->Type = dataW->Type;
369     dataA->DataFlow = dataW->DataFlow;
370     dataA->DeviceId = dataW->DeviceId;
371     dataA->WaveDeviceId = dataW->WaveDeviceId;
372     dataA->Interface = Interface;
373     dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
374     dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
375     if (!dataA->Module || !dataA->Description)
376     {
377         HeapFree(GetProcessHeap(), 0, dataA->Module);
378         HeapFree(GetProcessHeap(), 0, dataA->Description);
379         dataA->Module = dataA->Description = NULL;
380         return FALSE;
381     }
382
383     WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
384     WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
385     return TRUE;
386 }
387
388 static void DSPROPERTY_descWto1(const DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
389                                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
390 {
391     data1->DeviceId = dataW->DeviceId;
392     lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
393     lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
394     WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL);
395     WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL);
396     data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0;
397     data1->ModuleA[sizeof(data1->ModuleA)-1] = 0;
398     data1->Type = dataW->Type;
399     data1->DataFlow = dataW->DataFlow;
400     data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
401 }
402
403 static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
404 {
405     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
406     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
407     BOOL ret;
408
409     ret = DSPROPERTY_descWtoA(descW, &descA);
410     if (!ret)
411         return FALSE;
412     ret = ppd->Callback(&descA, ppd->Context);
413     HeapFree(GetProcessHeap(), 0, descA.Module);
414     HeapFree(GetProcessHeap(), 0, descA.Description);
415     return ret;
416 }
417
418 static HRESULT DSPROPERTY_EnumerateA(
419     LPVOID pPropData,
420     ULONG cbPropData,
421     PULONG pcbReturned)
422 {
423     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
424     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
425
426     if (!ppd || !ppd->Callback)
427     {
428         WARN("Invalid ppd %p\n", ppd);
429         return E_PROP_ID_UNSUPPORTED;
430     }
431
432     data.Callback = DSPROPERTY_enumWtoA;
433     data.Context = ppd;
434
435     return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
436 }
437
438 static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
439 {
440     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
441     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
442     BOOL ret;
443
444     DSPROPERTY_descWto1(descW, &desc1);
445     ret = ppd->Callback(&desc1, ppd->Context);
446     return ret;
447 }
448
449 static HRESULT DSPROPERTY_Enumerate1(
450     LPVOID pPropData,
451     ULONG cbPropData,
452     PULONG pcbReturned)
453 {
454     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
455     DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
456
457     if (!ppd || !ppd->Callback)
458     {
459         WARN("Invalid ppd %p\n", ppd);
460         return E_PROP_ID_UNSUPPORTED;
461     }
462
463     data.Callback = DSPROPERTY_enumWto1;
464     data.Context = ppd;
465
466     return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
467 }
468
469 static HRESULT DSPROPERTY_DescriptionA(
470     LPVOID pPropData,
471     ULONG cbPropData,
472     PULONG pcbReturned)
473 {
474     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
475     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
476     HRESULT hr;
477
478     if (pcbReturned)
479         *pcbReturned = sizeof(*ppd);
480     if (!pPropData)
481         return S_OK;
482
483     data.DeviceId = ppd->DeviceId;
484     data.DataFlow = ppd->DataFlow;
485     hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
486     if (FAILED(hr))
487         return hr;
488     if (!DSPROPERTY_descWtoA(&data, ppd))
489         hr = E_OUTOFMEMORY;
490     HeapFree(GetProcessHeap(), 0, data.Module);
491     HeapFree(GetProcessHeap(), 0, data.Interface);
492     return hr;
493 }
494
495 static HRESULT DSPROPERTY_Description1(
496     LPVOID pPropData,
497     ULONG cbPropData,
498     PULONG pcbReturned)
499 {
500     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
501     DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
502     HRESULT hr;
503
504     if (pcbReturned)
505         *pcbReturned = sizeof(*ppd);
506     if (!pPropData)
507         return S_OK;
508
509     data.DeviceId = ppd->DeviceId;
510     data.DataFlow = ppd->DataFlow;
511     hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
512     if (FAILED(hr))
513         return hr;
514     DSPROPERTY_descWto1(&data, ppd);
515     HeapFree(GetProcessHeap(), 0, data.Module);
516     HeapFree(GetProcessHeap(), 0, data.Interface);
517     return hr;
518 }
519
520 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
521     LPKSPROPERTYSET iface,
522     REFGUID guidPropSet,
523     ULONG dwPropID,
524     LPVOID pInstanceData,
525     ULONG cbInstanceData,
526     LPVOID pPropData,
527     ULONG cbPropData,
528     PULONG pcbReturned )
529 {
530     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
531     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
532           This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
533
534     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
535         switch (dwPropID) {
536         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
537             return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
538         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
539             return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
540         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
541             return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
542         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
543             return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
544         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
545             return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
546         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
547             return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
548         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
549             return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
550         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
551             return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
552         default:
553             FIXME("unsupported ID: %d\n",dwPropID);
554             break;
555         }
556     } else {
557         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
558     }
559
560     if (pcbReturned) {
561         *pcbReturned = 0;
562         FIXME("*pcbReturned=%d\n", *pcbReturned);
563     }
564
565     return E_PROP_ID_UNSUPPORTED;
566 }
567
568 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
569     LPKSPROPERTYSET iface,
570     REFGUID guidPropSet,
571     ULONG dwPropID,
572     LPVOID pInstanceData,
573     ULONG cbInstanceData,
574     LPVOID pPropData,
575     ULONG cbPropData )
576 {
577     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
578
579     FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
580     return E_PROP_ID_UNSUPPORTED;
581 }
582
583 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
584     LPKSPROPERTYSET iface,
585     REFGUID guidPropSet,
586     ULONG dwPropID,
587     PULONG pTypeSupport )
588 {
589     IKsPrivatePropertySetImpl *This = impl_from_IKsPropertySet(iface);
590     TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
591
592     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
593         switch (dwPropID) {
594         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
595             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
596             return S_OK;
597         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
598             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
599             return S_OK;
600         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
601             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
602             return S_OK;
603         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
604             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
605             return S_OK;
606         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
607             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
608             return S_OK;
609         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
610             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
611             return S_OK;
612         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
613             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
614             return S_OK;
615         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
616             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
617             return S_OK;
618         default:
619             FIXME("unsupported ID: %d\n",dwPropID);
620             break;
621         }
622     } else {
623         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
624     }
625
626     return E_PROP_ID_UNSUPPORTED;
627 }
628
629 static const IKsPropertySetVtbl ikspvt = {
630     IKsPrivatePropertySetImpl_QueryInterface,
631     IKsPrivatePropertySetImpl_AddRef,
632     IKsPrivatePropertySetImpl_Release,
633     IKsPrivatePropertySetImpl_Get,
634     IKsPrivatePropertySetImpl_Set,
635     IKsPrivatePropertySetImpl_QuerySupport
636 };
637
638 HRESULT IKsPrivatePropertySetImpl_Create(
639     REFIID riid,
640     IKsPropertySet **piks)
641 {
642     IKsPrivatePropertySetImpl *iks;
643     TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
644
645     if (!IsEqualIID(riid, &IID_IUnknown) &&
646         !IsEqualIID(riid, &IID_IKsPropertySet)) {
647         *piks = 0;
648         return E_NOINTERFACE;
649     }
650
651     iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
652     iks->ref = 1;
653     iks->IKsPropertySet_iface.lpVtbl = &ikspvt;
654
655     *piks = &iks->IKsPropertySet_iface;
656     return S_OK;
657 }