comctl32: toolbar: Fix the return code of TB_ADDBITMAP.
[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 #include <stdarg.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "mmsystem.h"
28 #include "winreg.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 "initguid.h"
38 #include "dsconf.h"
39
40 #ifdef NONAMELESSSTRUCT
41 # define S(x) (x).s
42 #else
43 # define S(x) (x)
44 #endif
45
46 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
47
48
49 /*******************************************************************************
50  *              IKsBufferPropertySet
51  */
52
53 /* IUnknown methods */
54 static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(
55     LPKSPROPERTYSET iface,
56     REFIID riid,
57     LPVOID *ppobj )
58 {
59     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
60     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
61
62     return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
63 }
64
65 static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
66 {
67     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
68     ULONG ref = InterlockedIncrement(&(This->ref));
69     TRACE("(%p) ref was %ld\n", This, ref - 1);
70     return ref;
71 }
72
73 static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
74 {
75     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
76     ULONG ref = InterlockedDecrement(&(This->ref));
77     TRACE("(%p) ref was %ld\n", This, ref + 1);
78
79     if (!ref) {
80         This->dsb->iks = 0;
81         IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
82         HeapFree(GetProcessHeap(), 0, This);
83         TRACE("(%p) released\n", This);
84     }
85     return ref;
86 }
87
88 static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
89     LPKSPROPERTYSET iface,
90     REFGUID guidPropSet,
91     ULONG dwPropID,
92     LPVOID pInstanceData,
93     ULONG cbInstanceData,
94     LPVOID pPropData,
95     ULONG cbPropData,
96     PULONG pcbReturned )
97 {
98     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
99     PIDSDRIVERPROPERTYSET ps;
100     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
101         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
102
103     if (This->dsb->hwbuf) {
104         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
105
106         if (ps) {
107             DSPROPERTY prop;
108             HRESULT hres;
109
110             S(prop).Set = *guidPropSet;
111             S(prop).Id = dwPropID;
112             S(prop).Flags = 0;  /* unused */
113             S(prop).InstanceId = (ULONG)This->dsb->device;
114
115             hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
116
117             IDsDriverPropertySet_Release(ps);
118
119             return hres;
120         }
121     }
122
123     return E_PROP_ID_UNSUPPORTED;
124 }
125
126 static HRESULT WINAPI IKsBufferPropertySetImpl_Set(
127     LPKSPROPERTYSET iface,
128     REFGUID guidPropSet,
129     ULONG dwPropID,
130     LPVOID pInstanceData,
131     ULONG cbInstanceData,
132     LPVOID pPropData,
133     ULONG cbPropData )
134 {
135     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
136     PIDSDRIVERPROPERTYSET ps;
137     TRACE("(%p,%s,%ld,%p,%ld,%p,%ld)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
138
139     if (This->dsb->hwbuf) {
140         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
141
142         if (ps) {
143             DSPROPERTY prop;
144             HRESULT hres;
145
146             S(prop).Set = *guidPropSet;
147             S(prop).Id = dwPropID;
148             S(prop).Flags = 0;  /* unused */
149             S(prop).InstanceId = (ULONG)This->dsb->device;
150             hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);
151
152             IDsDriverPropertySet_Release(ps);
153
154             return hres;
155         }
156     }
157
158     return E_PROP_ID_UNSUPPORTED;
159 }
160
161 static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(
162     LPKSPROPERTYSET iface,
163     REFGUID guidPropSet,
164     ULONG dwPropID,
165     PULONG pTypeSupport )
166 {
167     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
168     PIDSDRIVERPROPERTYSET ps;
169     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
170
171     if (This->dsb->hwbuf) {
172         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
173
174         if (ps) {
175             HRESULT hres;
176
177             hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);
178
179             IDsDriverPropertySet_Release(ps);
180
181             return hres;
182         }
183     }
184
185     return E_PROP_ID_UNSUPPORTED;
186 }
187
188 static const IKsPropertySetVtbl iksbvt = {
189     IKsBufferPropertySetImpl_QueryInterface,
190     IKsBufferPropertySetImpl_AddRef,
191     IKsBufferPropertySetImpl_Release,
192     IKsBufferPropertySetImpl_Get,
193     IKsBufferPropertySetImpl_Set,
194     IKsBufferPropertySetImpl_QuerySupport
195 };
196
197 HRESULT IKsBufferPropertySetImpl_Create(
198     IDirectSoundBufferImpl *dsb,
199     IKsBufferPropertySetImpl **piks)
200 {
201     IKsBufferPropertySetImpl *iks;
202     TRACE("(%p,%p)\n",dsb,piks);
203
204     iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
205     if (iks == 0) {
206         WARN("out of memory\n");
207         *piks = NULL;
208         return DSERR_OUTOFMEMORY;
209     }
210
211     iks->ref = 0;
212     iks->dsb = dsb;
213     dsb->iks = iks;
214     iks->lpVtbl = &iksbvt;
215
216     IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
217
218     *piks = iks;
219     return S_OK;
220 }
221
222 HRESULT IKsBufferPropertySetImpl_Destroy(
223     IKsBufferPropertySetImpl *piks)
224 {
225     TRACE("(%p)\n",piks);
226
227     while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
228
229     return S_OK;
230 }
231
232 /*******************************************************************************
233  *              IKsPrivatePropertySet
234  */
235
236 /* IUnknown methods */
237 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
238     LPKSPROPERTYSET iface,
239     REFIID riid,
240     LPVOID *ppobj )
241 {
242     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
243     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
244
245     *ppobj = NULL;
246     return DSERR_INVALIDPARAM;
247 }
248
249 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
250 {
251     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
252     ULONG ref = InterlockedIncrement(&(This->ref));
253     TRACE("(%p) ref was %ld\n", This, ref - 1);
254     return ref;
255 }
256
257 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
258 {
259     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
260     ULONG ref = InterlockedDecrement(&(This->ref));
261     TRACE("(%p) ref was %ld\n", This, ref + 1);
262
263     if (!ref) {
264         HeapFree(GetProcessHeap(), 0, This);
265         TRACE("(%p) released\n", This);
266     }
267     return ref;
268 }
269
270 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
271     LPVOID pPropData,
272     ULONG cbPropData,
273     PULONG pcbReturned )
274 {
275     HRESULT hr = DSERR_INVALIDPARAM;
276     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
277     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
278           pPropData,cbPropData,pcbReturned);
279
280     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA) pPropData;
281
282     if (!ppd) {
283         WARN("invalid parameter: pPropData\n");
284         return DSERR_INVALIDPARAM;
285     }
286
287     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
288         ULONG wod;
289         unsigned int wodn;
290         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
291         wodn = waveOutGetNumDevs();
292         for (wod = 0; wod < wodn; wod++) {
293             WAVEOUTCAPSA capsA;
294             MMRESULT res;
295             res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA));
296             if (res == MMSYSERR_NOERROR) {
297                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
298                     ppd->DeviceId = DSOUND_renderer_guids[wod];
299                     hr = DS_OK;
300                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
301                           ppd->DeviceName);
302                     break;
303                 }
304             }
305         }
306     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
307         ULONG wid;
308         unsigned int widn;
309         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
310         widn = waveInGetNumDevs();
311         for (wid = 0; wid < widn; wid++) {
312             WAVEINCAPSA capsA;
313             MMRESULT res;
314             res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA));
315             if (res == MMSYSERR_NOERROR) {
316                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
317                     ppd->DeviceId = DSOUND_capture_guids[wid];
318                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
319                           ppd->DeviceName);
320                     hr = DS_OK;
321                     break;
322                 }
323             }
324         }
325     }
326
327     if (pcbReturned)
328         *pcbReturned = cbPropData;
329
330     return hr;
331 }
332
333 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
334     LPVOID pPropData,
335     ULONG cbPropData,
336     PULONG pcbReturned )
337 {
338     HRESULT hr = DSERR_INVALIDPARAM;
339     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
340     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
341           pPropData,cbPropData,pcbReturned);
342
343     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA) pPropData;
344
345     if (!ppd) {
346         WARN("invalid parameter: pPropData\n");
347         return DSERR_INVALIDPARAM;
348     }
349
350     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
351         ULONG wod;
352         unsigned int wodn;
353         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
354         wodn = waveOutGetNumDevs();
355         for (wod = 0; wod < wodn; wod++) {
356             WAVEOUTCAPSW capsW;
357             MMRESULT res;
358             res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
359             if (res == MMSYSERR_NOERROR) {
360                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
361                     ppd->DeviceId = DSOUND_renderer_guids[wod];
362                     hr = DS_OK;
363                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
364                           debugstr_w(ppd->DeviceName));
365                     break;
366                 }
367             }
368         }
369     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
370         ULONG wid;
371         unsigned int widn;
372         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
373         widn = waveInGetNumDevs();
374         for (wid = 0; wid < widn; wid++) {
375             WAVEINCAPSW capsW;
376             MMRESULT res;
377             res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
378             if (res == MMSYSERR_NOERROR) {
379                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
380                     ppd->DeviceId = DSOUND_capture_guids[wid];
381                     hr = DS_OK;
382                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
383                           debugstr_w(ppd->DeviceName));
384                     break;
385                 }
386             }
387         }
388     }
389
390     if (pcbReturned)
391         *pcbReturned = cbPropData;
392
393     return hr;
394 }
395
396 static HRESULT WINAPI DSPROPERTY_Description1(
397     LPVOID pPropData,
398     ULONG cbPropData,
399     PULONG pcbReturned )
400 {
401     HRESULT err;
402     GUID guid, dev_guid;
403     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd;
404     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
405         pPropData,cbPropData,pcbReturned);
406
407     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData;
408
409     if (!ppd) {
410         WARN("invalid parameter: pPropData\n");
411         return DSERR_INVALIDPARAM;
412     }
413
414     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
415     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
416         /* default device of type specified by ppd->DataFlow */
417         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
418             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
419         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
420             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
421         } else {
422             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
423         }
424         FIXME("(pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
425               pPropData,cbPropData,pcbReturned);
426         return E_PROP_ID_UNSUPPORTED;
427     }
428
429     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
430     GetDeviceID(&ppd->DeviceId, &dev_guid);
431
432     if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
433          IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
434         ULONG wod;
435         unsigned int wodn;
436         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
437         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
438         wodn = waveOutGetNumDevs();
439         for (wod = 0; wod < wodn; wod++) {
440             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
441                 DSDRIVERDESC desc;
442                 ppd->WaveDeviceId = wod;
443                 ppd->Devnode = wod;
444                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
445                 if (err == DS_OK) {
446                     PIDSDRIVER drv = NULL;
447                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
448                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
449                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
450                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
451                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
452                     if (err == DS_OK && drv)
453                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
454                     else
455                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
456                     break;
457                 } else {
458                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
459                     return E_PROP_ID_UNSUPPORTED;
460                 }
461             }
462         }
463     } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
464                 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
465         ULONG wid;
466         unsigned int widn;
467         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
468         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
469         widn = waveInGetNumDevs();
470         for (wid = 0; wid < widn; wid++) {
471             if (IsEqualGUID( &dev_guid, &guid) ) {
472                 DSDRIVERDESC desc;
473                 ppd->WaveDeviceId = wid;
474                 ppd->Devnode = wid;
475                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
476                 if (err == DS_OK) {
477                     PIDSCDRIVER drv;
478                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
479                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
480                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
481                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
482                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
483                     if (err == DS_OK && drv)
484                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
485                     else
486                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
487                     break;
488                 } else {
489                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
490                     return E_PROP_ID_UNSUPPORTED;
491                 }
492             }
493         }
494     } else {
495         BOOL found = FALSE;
496         ULONG wod;
497         unsigned int wodn;
498         /* given specific device so try the render devices first */
499         wodn = waveOutGetNumDevs();
500         for (wod = 0; wod < wodn; wod++) {
501             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
502                 DSDRIVERDESC desc;
503                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
504                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
505                 ppd->WaveDeviceId = wod;
506                 ppd->Devnode = wod;
507                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
508                 if (err == DS_OK) {
509                     PIDSDRIVER drv = NULL;
510                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
511                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
512                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
513                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
514                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
515                     if (err == DS_OK && drv)
516                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
517                     else
518                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
519                     found = TRUE;
520                     break;
521                 } else {
522                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
523                     return E_PROP_ID_UNSUPPORTED;
524                 }
525             }
526         }
527
528         if (found == FALSE) {
529             ULONG wid;
530             unsigned int widn;
531             /* given specific device so try the capture devices next */
532             widn = waveInGetNumDevs();
533             for (wid = 0; wid < widn; wid++) {
534                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
535                     DSDRIVERDESC desc;
536                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
537                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
538                     ppd->WaveDeviceId = wid;
539                     ppd->Devnode = wid;
540                     err = mmErr(waveInMessage((HWAVEIN)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
541                     if (err == DS_OK) {
542                         PIDSDRIVER drv = NULL;
543                         lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
544                         lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
545                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
546                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
547                         err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
548                         if (err == DS_OK && drv)
549                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
550                         else
551                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
552                         found = TRUE;
553                         break;
554                     } else {
555                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
556                         return E_PROP_ID_UNSUPPORTED;
557                     }
558                 }
559             }
560
561             if (found == FALSE) {
562                 WARN("device not found\n");
563                 return E_PROP_ID_UNSUPPORTED;
564             }
565         }
566     }
567
568     if (pcbReturned) {
569         *pcbReturned = cbPropData;
570         TRACE("*pcbReturned=%ld\n", *pcbReturned);
571     }
572
573     return S_OK;
574 }
575
576 static HRESULT WINAPI DSPROPERTY_DescriptionA(
577     LPVOID pPropData,
578     ULONG cbPropData,
579     PULONG pcbReturned )
580 {
581     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
582     HRESULT err;
583     GUID dev_guid;
584     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
585           pPropData,cbPropData,pcbReturned);
586
587     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
588     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
589         /* default device of type specified by ppd->DataFlow */
590         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
591             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
592         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
593             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
594         } else {
595             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
596         }
597         FIXME("(pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
598               pPropData,cbPropData,pcbReturned);
599         return E_PROP_ID_UNSUPPORTED;
600     }
601
602     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
603     GetDeviceID(&ppd->DeviceId, &dev_guid);
604
605     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
606          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
607         ULONG wod;
608         unsigned int wodn;
609         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
610             TRACE("DSDEVID_DefaultPlayback\n");
611         else
612             TRACE("DSDEVID_DefaultVoicePlayback\n");
613         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
614         wodn = waveOutGetNumDevs();
615         for (wod = 0; wod < wodn; wod++) {
616             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
617                 DSDRIVERDESC desc;
618                 ppd->WaveDeviceId = wod;
619                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
620                 if (err == DS_OK) {
621                     PIDSDRIVER drv = NULL;
622                     /* FIXME: this is a memory leak */
623                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
624                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
625                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
626
627                     if (szDescription && szModule && szInterface) {
628                         strcpy(szDescription, desc.szDesc);
629                         strcpy(szModule, desc.szDrvname);
630                         strcpy(szInterface, "Interface");
631
632                         ppd->Description = szDescription;
633                         ppd->Module = szModule;
634                         ppd->Interface = szInterface;
635                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
636                         if (err == DS_OK && drv)
637                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
638                         else
639                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
640                         break;
641                     } else {
642                         WARN("no memory\n");
643                         HeapFree(GetProcessHeap(), 0, szDescription);
644                         HeapFree(GetProcessHeap(), 0, szModule);
645                         HeapFree(GetProcessHeap(), 0, szInterface);
646                         return E_OUTOFMEMORY;
647                     }
648                 } else {
649                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
650                     return E_PROP_ID_UNSUPPORTED;
651                 }
652             }
653         }
654     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
655                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
656         ULONG wid;
657         unsigned int widn;
658         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) )
659             TRACE("DSDEVID_DefaultCapture\n");
660         else
661             TRACE("DSDEVID_DefaultVoiceCapture\n");
662         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
663         widn = waveInGetNumDevs();
664         for (wid = 0; wid < widn; wid++) {
665             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
666                 DSDRIVERDESC desc;
667                 ppd->WaveDeviceId = wid;
668                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
669                 if (err == DS_OK) {
670                     PIDSCDRIVER drv;
671                     /* FIXME: this is a memory leak */
672                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
673                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
674                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
675
676                     if (szDescription && szModule && szInterface) {
677                         strcpy(szDescription, desc.szDesc);
678                         strcpy(szModule, desc.szDrvname);
679                         strcpy(szInterface, "Interface");
680
681                         ppd->Description = szDescription;
682                         ppd->Module = szModule;
683                         ppd->Interface = szInterface;
684                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
685                         if (err == DS_OK && drv)
686                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
687                         else
688                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
689                         break;
690                     } else {
691                         WARN("no memory\n");
692                         HeapFree(GetProcessHeap(), 0, szDescription);
693                         HeapFree(GetProcessHeap(), 0, szModule);
694                         HeapFree(GetProcessHeap(), 0, szInterface);
695                         return E_OUTOFMEMORY;
696                     }
697                 } else {
698                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
699                     return E_PROP_ID_UNSUPPORTED;
700                 }
701             }
702         }
703     } else {
704         BOOL found = FALSE;
705         ULONG wod;
706         unsigned int wodn;
707         /* given specific device so try the render devices first */
708         TRACE("Checking renderer devices\n");
709         wodn = waveOutGetNumDevs();
710         for (wod = 0; wod < wodn; wod++) {
711             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
712                 DSDRIVERDESC desc;
713                 TRACE("DSOUND_renderer_guids[%ld]\n", wod);
714                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
715                 ppd->WaveDeviceId = wod;
716                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
717                 if (err == DS_OK) {
718                     PIDSDRIVER drv = NULL;
719                     /* FIXME: this is a memory leak */
720                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
721                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
722                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
723
724                     if (szDescription && szModule && szInterface) {
725                         strcpy(szDescription, desc.szDesc);
726                         strcpy(szModule, desc.szDrvname);
727                         strcpy(szInterface, "Interface");
728
729                         ppd->Description = szDescription;
730                         ppd->Module = szModule;
731                         ppd->Interface = szInterface;
732                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
733                         if (err == DS_OK && drv)
734                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
735                         else
736                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
737                         found = TRUE;
738                         break;
739                     } else {
740                         WARN("no memory\n");
741                         HeapFree(GetProcessHeap(), 0, szDescription);
742                         HeapFree(GetProcessHeap(), 0, szModule);
743                         HeapFree(GetProcessHeap(), 0, szInterface);
744                         return E_OUTOFMEMORY;
745                     }
746                 } else {
747                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
748                     return E_PROP_ID_UNSUPPORTED;
749                 }
750             }
751         }
752
753         if (found == FALSE) {
754             ULONG wid;
755             unsigned int widn;
756             TRACE("Checking capture devices\n");
757             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
758             widn = waveInGetNumDevs();
759             for (wid = 0; wid < widn; wid++) {
760                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
761                     DSDRIVERDESC desc;
762                     TRACE("DSOUND_capture_guids[%ld]\n", wid);
763                     ppd->WaveDeviceId = wid;
764                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
765                     if (err == DS_OK) {
766                         PIDSCDRIVER drv;
767                         /* FIXME: this is a memory leak */
768                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
769                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
770                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
771
772                         if (szDescription && szModule && szInterface) {
773                             strcpy(szDescription, desc.szDesc);
774                             strcpy(szModule, desc.szDrvname);
775                             strcpy(szInterface, "Interface");
776
777                             ppd->Description = szDescription;
778                             ppd->Module = szModule;
779                             ppd->Interface = szInterface;
780                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
781                             if (err == DS_OK && drv)
782                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
783                             else
784                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
785                             found = TRUE;
786                             break;
787                         } else {
788                             WARN("no memory\n");
789                             HeapFree(GetProcessHeap(), 0, szDescription);
790                             HeapFree(GetProcessHeap(), 0, szModule);
791                             HeapFree(GetProcessHeap(), 0, szInterface);
792                             return E_OUTOFMEMORY;
793                         }
794                     } else {
795                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
796                         return E_PROP_ID_UNSUPPORTED;
797                     }
798                 }
799             }
800         }
801
802         if (found == FALSE) {
803             WARN("device not found\n");
804             return E_PROP_ID_UNSUPPORTED;
805         }
806     }
807
808     if (pcbReturned) {
809         *pcbReturned = cbPropData;
810         TRACE("*pcbReturned=%ld\n", *pcbReturned);
811     }
812
813     return S_OK;
814 }
815
816 static HRESULT WINAPI DSPROPERTY_DescriptionW(
817     LPVOID pPropData,
818     ULONG cbPropData,
819     PULONG pcbReturned )
820 {
821     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
822     HRESULT err;
823     GUID dev_guid;
824     TRACE("pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
825           pPropData,cbPropData,pcbReturned);
826
827     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
828     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
829         /* default device of type specified by ppd->DataFlow */
830         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
831             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
832         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
833             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
834         } else {
835             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
836         }
837         FIXME("(pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
838               pPropData,cbPropData,pcbReturned);
839         return E_PROP_ID_UNSUPPORTED;
840     }
841
842     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
843     GetDeviceID(&ppd->DeviceId, &dev_guid);
844
845     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
846          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
847         ULONG wod;
848         unsigned int wodn;
849         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
850             TRACE("DSDEVID_DefaultPlayback\n");
851         else
852             TRACE("DSDEVID_DefaultVoicePlayback\n");
853         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
854         wodn = waveOutGetNumDevs();
855         for (wod = 0; wod < wodn; wod++) {
856             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
857                 DSDRIVERDESC desc;
858                 TRACE("DSOUND_renderer_guids[%ld]\n", wod);
859                 ppd->WaveDeviceId = wod;
860                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
861                 if (err == DS_OK) {
862                     PIDSDRIVER drv = NULL;
863                     /* FIXME: this is a memory leak */
864                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
865                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
866                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
867
868                     if (wDescription && wModule && wInterface) {
869                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
870                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
871                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
872
873                         ppd->Description = wDescription;
874                         ppd->Module = wModule;
875                         ppd->Interface = wInterface;
876                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
877                         if (err == DS_OK && drv)
878                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
879                         else
880                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
881                         break;
882                     } else {
883                         WARN("no memory\n");
884                         HeapFree(GetProcessHeap(), 0, wDescription);
885                         HeapFree(GetProcessHeap(), 0, wModule);
886                         HeapFree(GetProcessHeap(), 0, wInterface);
887                         return E_OUTOFMEMORY;
888                     }
889                 } else {
890                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
891                     return E_PROP_ID_UNSUPPORTED;
892                 }
893             }
894         }
895     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
896                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
897         ULONG wid;
898         unsigned int widn;
899         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture))
900             TRACE("DSDEVID_DefaultCapture\n");
901         else
902             TRACE("DSDEVID_DefaultVoiceCapture\n");
903         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
904         widn = waveInGetNumDevs();
905         for (wid = 0; wid < widn; wid++) {
906             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
907                 DSDRIVERDESC desc;
908                 ppd->WaveDeviceId = wid;
909                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
910                 if (err == DS_OK) {
911                     PIDSCDRIVER drv;
912                     /* FIXME: this is a memory leak */
913                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
914                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
915                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
916
917                     if (wDescription && wModule && wInterface) {
918                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
919                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
920                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
921
922                         ppd->Description = wDescription;
923                         ppd->Module = wModule;
924                         ppd->Interface = wInterface;
925                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
926                         if (err == DS_OK && drv)
927                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
928                         else
929                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
930                         break;
931                     } else {
932                         WARN("no memory\n");
933                         HeapFree(GetProcessHeap(), 0, wDescription);
934                         HeapFree(GetProcessHeap(), 0, wModule);
935                         HeapFree(GetProcessHeap(), 0, wInterface);
936                         return E_OUTOFMEMORY;
937                     }
938                 } else {
939                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
940                     return E_PROP_ID_UNSUPPORTED;
941                 }
942             }
943         }
944     } else {
945         BOOL found = FALSE;
946         ULONG wod;
947         unsigned int wodn;
948         TRACE("Checking renderer devices\n");
949         /* given specific device so try the render devices first */
950         wodn = waveOutGetNumDevs();
951         for (wod = 0; wod < wodn; wod++) {
952             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
953                 DSDRIVERDESC desc;
954                 TRACE("DSOUND_renderer_guids[%ld]\n", wod);
955                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
956                 ppd->WaveDeviceId = wod;
957                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
958                 if (err == DS_OK) {
959                     PIDSDRIVER drv = NULL;
960                     /* FIXME: this is a memory leak */
961                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
962                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
963                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
964
965                     if (wDescription && wModule && wInterface) {
966                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
967                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
968                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
969
970                         ppd->Description = wDescription;
971                         ppd->Module = wModule;
972                         ppd->Interface = wInterface;
973                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
974                         if (err == DS_OK && drv)
975                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
976                         else
977                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
978                         found = TRUE;
979                         break;
980                     } else {
981                         WARN("no memory\n");
982                         HeapFree(GetProcessHeap(), 0, wDescription);
983                         HeapFree(GetProcessHeap(), 0, wModule);
984                         HeapFree(GetProcessHeap(), 0, wInterface);
985                         return E_OUTOFMEMORY;
986                     }
987                 } else {
988                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
989                     return E_PROP_ID_UNSUPPORTED;
990                 }
991             }
992         }
993
994         if (found == FALSE) {
995             ULONG wid;
996             unsigned int widn;
997             TRACE("Checking capture devices\n");
998             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
999             widn = waveInGetNumDevs();
1000             for (wid = 0; wid < widn; wid++) {
1001                 if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
1002                     DSDRIVERDESC desc;
1003                     TRACE("DSOUND_capture_guids[%ld]\n", wid);
1004                     ppd->WaveDeviceId = wid;
1005                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
1006                     if (err == DS_OK) {
1007                         PIDSCDRIVER drv;
1008                         /* FIXME: this is a memory leak */
1009                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1010                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1011                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
1012
1013                         if (wDescription && wModule && wInterface) {
1014                             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
1015                             MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1016                             MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
1017
1018                             ppd->Description = wDescription;
1019                             ppd->Module = wModule;
1020                             ppd->Interface = wInterface;
1021                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
1022                             if (err == DS_OK && drv)
1023                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1024                             else
1025                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1026                             found = TRUE;
1027                             break;
1028                         } else {
1029                             WARN("no memory\n");
1030                             HeapFree(GetProcessHeap(), 0, wDescription);
1031                             HeapFree(GetProcessHeap(), 0, wModule);
1032                             HeapFree(GetProcessHeap(), 0, wInterface);
1033                             return E_OUTOFMEMORY;
1034                         }
1035                     } else {
1036                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
1037                         return E_PROP_ID_UNSUPPORTED;
1038                     }
1039                 }
1040             }
1041         }
1042
1043         if (found == FALSE) {
1044             WARN("device not found\n");
1045             return E_PROP_ID_UNSUPPORTED;
1046         }
1047     }
1048
1049     if (pcbReturned) {
1050         *pcbReturned = cbPropData;
1051         TRACE("*pcbReturned=%ld\n", *pcbReturned);
1052     }
1053
1054     return S_OK;
1055 }
1056
1057 static HRESULT WINAPI DSPROPERTY_Enumerate1(
1058     LPVOID pPropData,
1059     ULONG cbPropData,
1060     PULONG pcbReturned )
1061 {
1062     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData;
1063     HRESULT err;
1064     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1065           pPropData,cbPropData,pcbReturned);
1066
1067     if (ppd) {
1068         if (ppd->Callback) {
1069             unsigned devs, wod, wid;
1070             DSDRIVERDESC desc;
1071             DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data;
1072
1073             devs = waveOutGetNumDevs();
1074             for (wod = 0; wod < devs; ++wod) {
1075                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1076                 if (err == DS_OK) {
1077                     PIDSCDRIVER drv;
1078                     ZeroMemory(&data, sizeof(data));
1079                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1080                     data.WaveDeviceId = wod;
1081                     data.DeviceId = DSOUND_renderer_guids[wod];
1082                     lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
1083                     lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
1084
1085                     MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
1086                     MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
1087
1088                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1089                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1090                     if (err == DS_OK && drv)
1091                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1092                     else
1093                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1094
1095                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1096                     (ppd->Callback)(&data, ppd->Context);
1097                 }
1098             }
1099
1100             devs = waveInGetNumDevs();
1101             for (wid = 0; wid < devs; ++wid) {
1102                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1103                 if (err == DS_OK) {
1104                     PIDSCDRIVER drv;
1105                     ZeroMemory(&data, sizeof(data));
1106                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1107                     data.WaveDeviceId = wid;
1108                     data.DeviceId = DSOUND_capture_guids[wid];
1109                     lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
1110                     lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
1111
1112                     MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
1113                     MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
1114
1115                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1116                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1117                     if (err == DS_OK && drv)
1118                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1119                     else
1120                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1121
1122                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1123                     (ppd->Callback)(&data, ppd->Context);
1124                 }
1125             }
1126
1127             return S_OK;
1128         }
1129     }
1130
1131     if (pcbReturned) {
1132         *pcbReturned = 0;
1133         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1134     }
1135
1136     return E_PROP_ID_UNSUPPORTED;
1137 }
1138
1139 static HRESULT WINAPI DSPROPERTY_EnumerateA(
1140     LPVOID pPropData,
1141     ULONG cbPropData,
1142     PULONG pcbReturned )
1143 {
1144     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
1145     HRESULT err;
1146     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1147           pPropData,cbPropData,pcbReturned);
1148
1149     if (ppd) {
1150         if (ppd->Callback) {
1151             unsigned devs, wod, wid;
1152             DSDRIVERDESC desc;
1153             DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
1154
1155             devs = waveOutGetNumDevs();
1156             for (wod = 0; wod < devs; ++wod) {
1157                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1158                 if (err == DS_OK) {
1159                     DWORD size;
1160                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1161                     if (err == DS_OK) {
1162                         WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1163                         if (nameW) {
1164                             err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1165                             if (err == DS_OK) {
1166                                 CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1167                                 if (szInterface) {
1168                                     PIDSCDRIVER drv;
1169                                     ZeroMemory(&data, sizeof(data));
1170                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1171                                     data.WaveDeviceId = wod;
1172                                     data.DeviceId = DSOUND_renderer_guids[wod];
1173                                     data.Description = desc.szDesc;
1174                                     data.Module = desc.szDrvname;
1175                                     WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1176                                     data.Interface = szInterface;
1177
1178                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1179                                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1180                                     if (err == DS_OK && drv)
1181                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1182                                     else
1183                                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1184
1185                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1186                                     (ppd->Callback)(&data, ppd->Context);
1187                                 }
1188                                 HeapFree(GetProcessHeap(),0,szInterface);
1189                             }
1190                         }
1191                         HeapFree(GetProcessHeap(),0,nameW);
1192                     }
1193                 }
1194             }
1195
1196             devs = waveInGetNumDevs();
1197             for (wid = 0; wid < devs; ++wid) {
1198                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1199                 if (err == DS_OK) {
1200                     DWORD size;
1201                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1202                     if (err == DS_OK) {
1203                         WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1204                         if (nameW) {
1205                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1206                             if (err == DS_OK) {
1207                                 CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1208                                 if (szInterface) {
1209                                     PIDSCDRIVER drv;
1210                                     ZeroMemory(&data, sizeof(data));
1211                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1212                                     data.WaveDeviceId = wid;
1213                                     data.DeviceId = DSOUND_capture_guids[wid];
1214                                     data.Description = desc.szDesc;
1215                                     data.Module = desc.szDrvname;
1216                                     WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1217                                     data.Interface = szInterface;
1218
1219                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1220                                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1221                                     if (err == DS_OK && drv)
1222                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1223                                     else
1224                                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1225
1226                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1227                                     (ppd->Callback)(&data, ppd->Context);
1228                                 }
1229                                 HeapFree(GetProcessHeap(),0,szInterface);
1230                             }
1231                         }
1232                         HeapFree(GetProcessHeap(),0,nameW);
1233                     }
1234                 }
1235             }
1236
1237             return S_OK;
1238         }
1239     }
1240
1241     if (pcbReturned) {
1242         *pcbReturned = 0;
1243         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1244     }
1245
1246     return E_PROP_ID_UNSUPPORTED;
1247 }
1248
1249 static HRESULT WINAPI DSPROPERTY_EnumerateW(
1250     LPVOID pPropData,
1251     ULONG cbPropData,
1252     PULONG pcbReturned )
1253 {
1254     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
1255     HRESULT err;
1256     TRACE("(pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1257           pPropData,cbPropData,pcbReturned);
1258
1259     if (ppd) {
1260         if (ppd->Callback) {
1261             unsigned devs, wod, wid;
1262             DSDRIVERDESC desc;
1263             DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
1264
1265             devs = waveOutGetNumDevs();
1266             for (wod = 0; wod < devs; ++wod) {
1267                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1268                 if (err == DS_OK) {
1269                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1270                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1271                     if (wDescription && wModule) {
1272                         DWORD size;
1273                         err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
1274                         if (err == DS_OK) {
1275                             WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
1276                             if (wInterface) {
1277                                 err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
1278                                 if (err == DS_OK) {
1279                                     PIDSCDRIVER drv;
1280                                     ZeroMemory(&data, sizeof(data));
1281                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1282                                     data.WaveDeviceId = wod;
1283                                     data.DeviceId = DSOUND_renderer_guids[wod];
1284
1285                                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
1286                                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1287
1288                                     data.Description = wDescription;
1289                                     data.Module = wModule;
1290                                     data.Interface = wInterface;
1291
1292                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1293                                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1294                                     if (err == DS_OK && drv)
1295                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1296                                     else
1297                                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1298
1299                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1300                                     (ppd->Callback)(&data, ppd->Context);
1301                                     }
1302                             }
1303                             HeapFree(GetProcessHeap(),0,wInterface);
1304                         }
1305                     }
1306                     HeapFree(GetProcessHeap(),0,wDescription);
1307                     HeapFree(GetProcessHeap(),0,wModule);
1308                 }
1309             }
1310
1311             devs = waveInGetNumDevs();
1312             for (wid = 0; wid < devs; ++wid) {
1313                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1314                 if (err == DS_OK) {
1315                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1316                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1317                     if (wDescription && wModule) {
1318                         DWORD size;
1319                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
1320                         if (err == DS_OK) {
1321                             WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
1322                             if (wInterface) {
1323                                 err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
1324                                 if (err == DS_OK) {
1325                                     PIDSCDRIVER drv;
1326                                     ZeroMemory(&data, sizeof(data));
1327                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1328                                     data.WaveDeviceId = wid;
1329                                     data.DeviceId = DSOUND_capture_guids[wid];
1330
1331                                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
1332                                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1333
1334                                     data.Description = wDescription;
1335                                     data.Module = wModule;
1336                                     data.Interface = wInterface;
1337                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1338                                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1339                                     if (err == DS_OK && drv)
1340                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1341                                     else
1342                                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1343
1344                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1345                                     (ppd->Callback)(&data, ppd->Context);
1346                                 }
1347                             }
1348                             HeapFree(GetProcessHeap(),0,wInterface);
1349                         }
1350                     }
1351                     HeapFree(GetProcessHeap(),0,wDescription);
1352                     HeapFree(GetProcessHeap(),0,wModule);
1353                 }
1354             }
1355
1356             return S_OK;
1357         }
1358     }
1359
1360     if (pcbReturned) {
1361         *pcbReturned = 0;
1362         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1363     }
1364
1365     return E_PROP_ID_UNSUPPORTED;
1366 }
1367
1368 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
1369     LPKSPROPERTYSET iface,
1370     REFGUID guidPropSet,
1371     ULONG dwPropID,
1372     LPVOID pInstanceData,
1373     ULONG cbInstanceData,
1374     LPVOID pPropData,
1375     ULONG cbPropData,
1376     PULONG pcbReturned )
1377 {
1378     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1379     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1380           This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
1381
1382     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1383         switch (dwPropID) {
1384         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1385             return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
1386         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1387             return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
1388         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1389             return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
1390         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1391             return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
1392         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1393             return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
1394         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1395             return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
1396         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1397             return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
1398         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1399             return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
1400         default:
1401             FIXME("unsupported ID: %ld\n",dwPropID);
1402             break;
1403         }
1404     } else {
1405         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1406     }
1407
1408     if (pcbReturned) {
1409         *pcbReturned = 0;
1410         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1411     }
1412
1413     return E_PROP_ID_UNSUPPORTED;
1414 }
1415
1416 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
1417     LPKSPROPERTYSET iface,
1418     REFGUID guidPropSet,
1419     ULONG dwPropID,
1420     LPVOID pInstanceData,
1421     ULONG cbInstanceData,
1422     LPVOID pPropData,
1423     ULONG cbPropData )
1424 {
1425     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1426
1427     FIXME("(%p,%s,%ld,%p,%ld,%p,%ld), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
1428     return E_PROP_ID_UNSUPPORTED;
1429 }
1430
1431 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
1432     LPKSPROPERTYSET iface,
1433     REFGUID guidPropSet,
1434     ULONG dwPropID,
1435     PULONG pTypeSupport )
1436 {
1437     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1438     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
1439
1440     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1441         switch (dwPropID) {
1442         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1443             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1444             return S_OK;
1445         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1446             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1447             return S_OK;
1448         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1449             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1450             return S_OK;
1451         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1452             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1453             return S_OK;
1454         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1455             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1456             return S_OK;
1457         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1458             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1459             return S_OK;
1460         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1461             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1462             return S_OK;
1463         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1464             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1465             return S_OK;
1466         default:
1467             FIXME("unsupported ID: %ld\n",dwPropID);
1468             break;
1469         }
1470     } else {
1471         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1472     }
1473
1474     return E_PROP_ID_UNSUPPORTED;
1475 }
1476
1477 static const IKsPropertySetVtbl ikspvt = {
1478     IKsPrivatePropertySetImpl_QueryInterface,
1479     IKsPrivatePropertySetImpl_AddRef,
1480     IKsPrivatePropertySetImpl_Release,
1481     IKsPrivatePropertySetImpl_Get,
1482     IKsPrivatePropertySetImpl_Set,
1483     IKsPrivatePropertySetImpl_QuerySupport
1484 };
1485
1486 HRESULT IKsPrivatePropertySetImpl_Create(
1487     REFIID riid,
1488     IKsPrivatePropertySetImpl **piks)
1489 {
1490     IKsPrivatePropertySetImpl *iks;
1491     TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
1492
1493     if (!IsEqualIID(riid, &IID_IUnknown) &&
1494         !IsEqualIID(riid, &IID_IKsPropertySet)) {
1495         *piks = 0;
1496         return E_NOINTERFACE;
1497     }
1498
1499     iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
1500     iks->ref = 1;
1501     iks->lpVtbl = &ikspvt;
1502
1503     *piks = iks;
1504     return S_OK;
1505 }