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