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