Added missing AW define.
[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 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         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\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)&(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)&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         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
659         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
660         widn = waveInGetNumDevs();
661         for (wid = 0; wid < widn; wid++) {
662             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
663                 DSDRIVERDESC desc;
664                 ppd->WaveDeviceId = wid;
665                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
666                 if (err == DS_OK) {
667                     PIDSCDRIVER drv;
668                     /* FIXME: this is a memory leak */
669                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
670                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
671                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
672
673                     if (szDescription && szModule && szInterface) {
674                         strcpy(szDescription, desc.szDesc);
675                         strcpy(szModule, desc.szDrvname);
676                         strcpy(szInterface, "Interface");
677
678                         ppd->Description = szDescription;
679                         ppd->Module = szModule;
680                         ppd->Interface = szInterface;
681                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
682                         if (err == DS_OK && drv)
683                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
684                         else
685                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
686                         break;
687                     } else {
688                         WARN("no memory\n");
689                         HeapFree(GetProcessHeap(), 0, szDescription);
690                         HeapFree(GetProcessHeap(), 0, szModule);
691                         HeapFree(GetProcessHeap(), 0, szInterface);
692                         return E_OUTOFMEMORY;
693                     }
694                 } else {
695                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
696                     return E_PROP_ID_UNSUPPORTED;
697                 }
698             }
699         }
700     } else {
701         BOOL found = FALSE;
702         ULONG wod;
703         unsigned int wodn;
704         /* given specific device so try the render devices first */
705         wodn = waveOutGetNumDevs();
706         for (wod = 0; wod < wodn; wod++) {
707             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
708                 DSDRIVERDESC desc;
709                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
710                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
711                 ppd->WaveDeviceId = wod;
712                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
713                 if (err == DS_OK) {
714                     PIDSDRIVER drv = NULL;
715                     /* FIXME: this is a memory leak */
716                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
717                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
718                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
719
720                     if (szDescription && szModule && szInterface) {
721                         strcpy(szDescription, desc.szDesc);
722                         strcpy(szModule, desc.szDrvname);
723                         strcpy(szInterface, "Interface");
724
725                         ppd->Description = szDescription;
726                         ppd->Module = szModule;
727                         ppd->Interface = szInterface;
728                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
729                         if (err == DS_OK && drv)
730                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
731                         else
732                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
733                         found = TRUE;
734                         break;
735                     } else {
736                         WARN("no memory\n");
737                         HeapFree(GetProcessHeap(), 0, szDescription);
738                         HeapFree(GetProcessHeap(), 0, szModule);
739                         HeapFree(GetProcessHeap(), 0, szInterface);
740                         return E_OUTOFMEMORY;
741                     }
742                 } else {
743                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
744                     return E_PROP_ID_UNSUPPORTED;
745                 }
746             }
747         }
748
749         if (found == FALSE) {
750             ULONG wid;
751             unsigned int widn;
752             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
753             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
754             widn = waveInGetNumDevs();
755             for (wid = 0; wid < widn; wid++) {
756                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wod] ) ) {
757                     DSDRIVERDESC desc;
758                     ppd->WaveDeviceId = wid;
759                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
760                     if (err == DS_OK) {
761                         PIDSCDRIVER drv;
762                         /* FIXME: this is a memory leak */
763                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
764                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
765                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
766
767                         if (szDescription && szModule && szInterface) {
768                             strcpy(szDescription, desc.szDesc);
769                             strcpy(szModule, desc.szDrvname);
770                             strcpy(szInterface, "Interface");
771
772                             ppd->Description = szDescription;
773                             ppd->Module = szModule;
774                             ppd->Interface = szInterface;
775                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
776                             if (err == DS_OK && drv)
777                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
778                             else
779                                 WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
780                             found = TRUE;
781                             break;
782                         } else {
783                             WARN("no memory\n");
784                             HeapFree(GetProcessHeap(), 0, szDescription);
785                             HeapFree(GetProcessHeap(), 0, szModule);
786                             HeapFree(GetProcessHeap(), 0, szInterface);
787                             return E_OUTOFMEMORY;
788                         }
789                     } else {
790                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
791                         return E_PROP_ID_UNSUPPORTED;
792                     }
793                 }
794             }
795         }
796
797         if (found == FALSE) {
798             WARN("device not found\n");
799             return E_PROP_ID_UNSUPPORTED;
800         }
801     }
802
803     if (pcbReturned) {
804         *pcbReturned = cbPropData;
805         TRACE("*pcbReturned=%ld\n", *pcbReturned);
806     }
807
808     return S_OK;
809 }
810
811 static HRESULT WINAPI DSPROPERTY_DescriptionW(
812     REFGUID guidPropSet,
813     LPVOID pPropData,
814     ULONG cbPropData,
815     PULONG pcbReturned )
816 {
817     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
818     HRESULT err;
819     GUID dev_guid;
820     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
821         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
822
823     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
824     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
825         /* default device of type specified by ppd->DataFlow */
826         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
827             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
828         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
829             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
830         } else {
831             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
832         }
833         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
834             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
835         return E_PROP_ID_UNSUPPORTED;
836     }
837
838     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
839     GetDeviceID(&ppd->DeviceId, &dev_guid);
840
841     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
842          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
843         ULONG wod;
844         unsigned int wodn;
845         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
846         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
847         wodn = waveOutGetNumDevs();
848         for (wod = 0; wod < wodn; wod++) {
849             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
850                 DSDRIVERDESC desc;
851                 ppd->WaveDeviceId = wod;
852                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
853                 if (err == DS_OK) {
854                     PIDSDRIVER drv = NULL;
855                     /* FIXME: this is a memory leak */
856                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
857                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
858                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
859
860                     if (wDescription && wModule && wInterface) {
861                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
862                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
863                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
864
865                         ppd->Description = wDescription;
866                         ppd->Module = wModule;
867                         ppd->Interface = wInterface;
868                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
869                         if (err == DS_OK && drv)
870                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
871                         else
872                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
873                         break;
874                     } else {
875                         WARN("no memory\n");
876                         HeapFree(GetProcessHeap(), 0, wDescription);
877                         HeapFree(GetProcessHeap(), 0, wModule);
878                         HeapFree(GetProcessHeap(), 0, wInterface);
879                         return E_OUTOFMEMORY;
880                     }
881                 } else {
882                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
883                     return E_PROP_ID_UNSUPPORTED;
884                 }
885             }
886         }
887     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
888                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
889         ULONG wid;
890         unsigned int widn;
891         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
892         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
893         widn = waveInGetNumDevs();
894         for (wid = 0; wid < widn; wid++) {
895             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
896                 DSDRIVERDESC desc;
897                 ppd->WaveDeviceId = wid;
898                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
899                 if (err == DS_OK) {
900                     PIDSCDRIVER drv;
901                     /* FIXME: this is a memory leak */
902                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
903                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
904                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
905
906                     if (wDescription && wModule && wInterface) {
907                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
908                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
909                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
910
911                         ppd->Description = wDescription;
912                         ppd->Module = wModule;
913                         ppd->Interface = wInterface;
914                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
915                         if (err == DS_OK && drv)
916                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
917                         else
918                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
919                         break;
920                     } else {
921                         WARN("no memory\n");
922                         HeapFree(GetProcessHeap(), 0, wDescription);
923                         HeapFree(GetProcessHeap(), 0, wModule);
924                         HeapFree(GetProcessHeap(), 0, wInterface);
925                         return E_OUTOFMEMORY;
926                     }
927                 } else {
928                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
929                     return E_PROP_ID_UNSUPPORTED;
930                 }
931             }
932         }
933     } else {
934         BOOL found = FALSE;
935         ULONG wod;
936         unsigned int wodn;
937         /* given specific device so try the render devices first */
938         wodn = waveOutGetNumDevs();
939         for (wod = 0; wod < wodn; wod++) {
940             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
941                 DSDRIVERDESC desc;
942                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
943                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
944                 ppd->WaveDeviceId = wod;
945                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
946                 if (err == DS_OK) {
947                     PIDSDRIVER drv = NULL;
948                     /* FIXME: this is a memory leak */
949                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
950                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
951                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
952
953                     if (wDescription && wModule && wInterface) {
954                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
955                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
956                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
957
958                         ppd->Description = wDescription;
959                         ppd->Module = wModule;
960                         ppd->Interface = wInterface;
961                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
962                         if (err == DS_OK && drv)
963                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
964                         else
965                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
966                         found = TRUE;
967                         break;
968                     } else {
969                         WARN("no memory\n");
970                         HeapFree(GetProcessHeap(), 0, wDescription);
971                         HeapFree(GetProcessHeap(), 0, wModule);
972                         HeapFree(GetProcessHeap(), 0, wInterface);
973                         return E_OUTOFMEMORY;
974                     }
975                 } else {
976                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
977                     return E_PROP_ID_UNSUPPORTED;
978                 }
979             }
980         }
981
982         if (found == FALSE) {
983             ULONG wid;
984             unsigned int widn;
985             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
986             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
987             widn = waveInGetNumDevs();
988             for (wid = 0; wid < widn; wid++) {
989                 if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
990                     DSDRIVERDESC desc;
991                     ppd->WaveDeviceId = wid;
992                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
993                     if (err == DS_OK) {
994                         PIDSCDRIVER drv;
995                         /* FIXME: this is a memory leak */
996                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
997                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
998                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
999
1000                         if (wDescription && wModule && wInterface) {
1001                             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
1002                             MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1003                             MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
1004
1005                             ppd->Description = wDescription;
1006                             ppd->Module = wModule;
1007                             ppd->Interface = wInterface;
1008                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
1009                             if (err == DS_OK && drv)
1010                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1011                             else
1012                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1013                             found = TRUE;
1014                             break;
1015                         } else {
1016                             WARN("no memory\n");
1017                             HeapFree(GetProcessHeap(), 0, wDescription);
1018                             HeapFree(GetProcessHeap(), 0, wModule);
1019                             HeapFree(GetProcessHeap(), 0, wInterface);
1020                             return E_OUTOFMEMORY;
1021                         }
1022                     } else {
1023                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
1024                         return E_PROP_ID_UNSUPPORTED;
1025                     }
1026                 }
1027             }
1028         }
1029
1030         if (found == FALSE) {
1031             WARN("device not found\n");
1032             return E_PROP_ID_UNSUPPORTED;
1033         }
1034     }
1035
1036     if (pcbReturned) {
1037         *pcbReturned = cbPropData;
1038         TRACE("*pcbReturned=%ld\n", *pcbReturned);
1039     }
1040
1041     return S_OK;
1042 }
1043
1044 static HRESULT WINAPI DSPROPERTY_Enumerate1(
1045     REFGUID guidPropSet,
1046     LPVOID pPropData,
1047     ULONG cbPropData,
1048     PULONG pcbReturned )
1049 {
1050     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData;
1051     HRESULT err;
1052     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1053         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
1054
1055     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1056         if (ppd) {
1057             if (ppd->Callback) {
1058                 unsigned devs, wod, wid;
1059                 DSDRIVERDESC desc;
1060                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data;
1061
1062                 devs = waveOutGetNumDevs();
1063                 for (wod = 0; wod < devs; ++wod) {
1064                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1065                     if (err == DS_OK) {
1066                         PIDSCDRIVER drv;
1067                         ZeroMemory(&data, sizeof(data));
1068                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1069                         data.WaveDeviceId = wod;
1070                         data.DeviceId = DSOUND_renderer_guids[wod];
1071                         lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
1072                         lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
1073
1074                         MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW) );
1075                         MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW) );
1076
1077                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1078                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1079                         if (err == DS_OK && drv)
1080                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1081                         else
1082                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1083
1084                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1085                         (ppd->Callback)(&data, ppd->Context);
1086                     }
1087                 }
1088
1089                 devs = waveInGetNumDevs();
1090                 for (wid = 0; wid < devs; ++wid) {
1091                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1092                     if (err == DS_OK) {
1093                         PIDSCDRIVER drv;
1094                         ZeroMemory(&data, sizeof(data));
1095                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1096                         data.WaveDeviceId = wid;
1097                         data.DeviceId = DSOUND_capture_guids[wid];
1098                         lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
1099                         lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
1100
1101                         MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW) );
1102                         MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW) );
1103
1104                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1105                         err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1106                         if (err == DS_OK && drv)
1107                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1108                         else
1109                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1110
1111                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1112                         (ppd->Callback)(&data, ppd->Context);
1113                     }
1114                 }
1115
1116                 return S_OK;
1117             }
1118         }
1119     } else {
1120         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1121     }
1122
1123     if (pcbReturned) {
1124         *pcbReturned = 0;
1125         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1126     }
1127
1128     return E_PROP_ID_UNSUPPORTED;
1129 }
1130
1131 static HRESULT WINAPI DSPROPERTY_EnumerateA(
1132     REFGUID guidPropSet,
1133     LPVOID pPropData,
1134     ULONG cbPropData,
1135     PULONG pcbReturned )
1136 {
1137     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
1138     HRESULT err;
1139     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1140         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
1141
1142     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1143         if (ppd) {
1144             if (ppd->Callback) {
1145                 unsigned devs, wod, wid;
1146                 DSDRIVERDESC desc;
1147                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
1148
1149                 devs = waveOutGetNumDevs();
1150                 for (wod = 0; wod < devs; ++wod) {
1151                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1152                     if (err == DS_OK) {
1153                         DWORD size;
1154                         err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1155                         if (err == DS_OK) {
1156                             WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1157                             if (nameW) {
1158                                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1159                                 if (err == DS_OK) {
1160                                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1161                                     if (szInterface) {
1162                                         PIDSCDRIVER drv;
1163                                         ZeroMemory(&data, sizeof(data));
1164                                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1165                                         data.WaveDeviceId = wod;
1166                                         data.DeviceId = DSOUND_renderer_guids[wod];
1167                                         data.Description = desc.szDesc;
1168                                         data.Module = desc.szDrvname;
1169                                         WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1170                                         data.Interface = szInterface;
1171
1172                                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1173                                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1174                                         if (err == DS_OK && drv)
1175                                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1176                                         else
1177                                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1178
1179                                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1180                                         (ppd->Callback)(&data, ppd->Context);
1181                                     }
1182                                     HeapFree(GetProcessHeap(),0,szInterface);
1183                                 }
1184                             }
1185                             HeapFree(GetProcessHeap(),0,nameW);
1186                         }
1187                     }
1188                 }
1189
1190                 devs = waveInGetNumDevs();
1191                 for (wid = 0; wid < devs; ++wid) {
1192                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1193                     if (err == DS_OK) {
1194                         DWORD size;
1195                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1196                         if (err == DS_OK) {
1197                             WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1198                             if (nameW) {
1199                                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1200                                 if (err == DS_OK) {
1201                                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1202                                     if (szInterface) {
1203                                         PIDSCDRIVER drv;
1204                                         ZeroMemory(&data, sizeof(data));
1205                                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1206                                         data.WaveDeviceId = wid;
1207                                         data.DeviceId = DSOUND_capture_guids[wid];
1208                                         data.Description = desc.szDesc;
1209                                         data.Module = desc.szDrvname;
1210                                         WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1211                                         data.Interface = szInterface;
1212
1213                                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1214                                         err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1215                                         if (err == DS_OK && drv)
1216                                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1217                                         else
1218                                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1219
1220                                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1221                                         (ppd->Callback)(&data, ppd->Context);
1222                                     }
1223                                     HeapFree(GetProcessHeap(),0,szInterface);
1224                                 }
1225                             }
1226                             HeapFree(GetProcessHeap(),0,nameW);
1227                         }
1228                     }
1229                 }
1230
1231                 return S_OK;
1232             }
1233         }
1234     } else {
1235         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1236     }
1237
1238     if (pcbReturned) {
1239         *pcbReturned = 0;
1240         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1241     }
1242
1243     return E_PROP_ID_UNSUPPORTED;
1244 }
1245
1246 static HRESULT WINAPI DSPROPERTY_EnumerateW(
1247     REFGUID guidPropSet,
1248     LPVOID pPropData,
1249     ULONG cbPropData,
1250     PULONG pcbReturned )
1251 {
1252     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
1253     HRESULT err;
1254     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1255         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
1256
1257     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1258         if (ppd) {
1259             if (ppd->Callback) {
1260                 unsigned devs, wod, wid;
1261                 DSDRIVERDESC desc;
1262                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
1263
1264                 devs = waveOutGetNumDevs();
1265                 for (wod = 0; wod < devs; ++wod) {
1266                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1267                     if (err == DS_OK) {
1268                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1269                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1270                         if (wDescription && wModule) {
1271                             DWORD size;
1272                             err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
1273                             if (err == DS_OK) {
1274                                 WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
1275                                 if (wInterface) {
1276                                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
1277                                     if (err == DS_OK) {
1278                                         PIDSCDRIVER drv;
1279                                         ZeroMemory(&data, sizeof(data));
1280                                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1281                                         data.WaveDeviceId = wod;
1282                                         data.DeviceId = DSOUND_renderer_guids[wod];
1283
1284                                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
1285                                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1286
1287                                         data.Description = wDescription;
1288                                         data.Module = wModule;
1289                                         data.Interface = wInterface;
1290
1291                                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1292                                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1293                                         if (err == DS_OK && drv)
1294                                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1295                                         else
1296                                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1297
1298                                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1299                                         (ppd->Callback)(&data, ppd->Context);
1300                                     }
1301                                 }
1302                                 HeapFree(GetProcessHeap(),0,wInterface);
1303                             }
1304                         }
1305                         HeapFree(GetProcessHeap(),0,wDescription);
1306                         HeapFree(GetProcessHeap(),0,wModule);
1307                     }
1308                 }
1309
1310                 devs = waveInGetNumDevs();
1311                 for (wid = 0; wid < devs; ++wid) {
1312                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
1313                     if (err == DS_OK) {
1314                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1315                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1316                         if (wDescription && wModule) {
1317                             DWORD size;
1318                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
1319                             if (err == DS_OK) {
1320                                 WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
1321                                 if (wInterface) {
1322                                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
1323                                     if (err == DS_OK) {
1324                                         PIDSCDRIVER drv;
1325                                         ZeroMemory(&data, sizeof(data));
1326                                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1327                                         data.WaveDeviceId = wid;
1328                                         data.DeviceId = DSOUND_capture_guids[wid];
1329
1330                                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
1331                                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1332
1333                                         data.Description = wDescription;
1334                                         data.Module = wModule;
1335                                         data.Interface = wInterface;
1336                                         data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1337                                         err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
1338                                         if (err == DS_OK && drv)
1339                                             data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1340                                         else
1341                                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1342
1343                                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1344                                         (ppd->Callback)(&data, ppd->Context);
1345                                     }
1346                                 }
1347                                 HeapFree(GetProcessHeap(),0,wInterface);
1348                             }
1349                         }
1350                         HeapFree(GetProcessHeap(),0,wDescription);
1351                         HeapFree(GetProcessHeap(),0,wModule);
1352                     }
1353                 }
1354
1355                 return S_OK;
1356             }
1357         }
1358     } else {
1359         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1360     }
1361
1362     if (pcbReturned) {
1363         *pcbReturned = 0;
1364         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1365     }
1366
1367     return E_PROP_ID_UNSUPPORTED;
1368 }
1369
1370 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
1371     LPKSPROPERTYSET iface,
1372     REFGUID guidPropSet,
1373     ULONG dwPropID,
1374     LPVOID pInstanceData,
1375     ULONG cbInstanceData,
1376     LPVOID pPropData,
1377     ULONG cbPropData,
1378     PULONG pcbReturned )
1379 {
1380     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1381     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
1382         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
1383
1384     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1385         switch (dwPropID) {
1386         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1387             return DSPROPERTY_WaveDeviceMappingA(guidPropSet,pPropData,cbPropData,pcbReturned);
1388         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1389             return DSPROPERTY_Description1(guidPropSet,pPropData,cbPropData,pcbReturned);
1390         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1391             return DSPROPERTY_Enumerate1(guidPropSet,pPropData,cbPropData,pcbReturned);
1392         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1393             return DSPROPERTY_WaveDeviceMappingW(guidPropSet,pPropData,cbPropData,pcbReturned);
1394         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1395             return DSPROPERTY_DescriptionA(guidPropSet,pPropData,cbPropData,pcbReturned);
1396         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1397             return DSPROPERTY_DescriptionW(guidPropSet,pPropData,cbPropData,pcbReturned);
1398         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1399             return DSPROPERTY_EnumerateA(guidPropSet,pPropData,cbPropData,pcbReturned);
1400         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1401             return DSPROPERTY_EnumerateW(guidPropSet,pPropData,cbPropData,pcbReturned);
1402         default:
1403             FIXME("unsupported ID: %ld\n",dwPropID);
1404             break;
1405         }
1406     } else {
1407         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1408     }
1409
1410     if (pcbReturned) {
1411         *pcbReturned = 0;
1412         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1413     }
1414
1415     return E_PROP_ID_UNSUPPORTED;
1416 }
1417
1418 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
1419     LPKSPROPERTYSET iface,
1420     REFGUID guidPropSet,
1421     ULONG dwPropID,
1422     LPVOID pInstanceData,
1423     ULONG cbInstanceData,
1424     LPVOID pPropData,
1425     ULONG cbPropData )
1426 {
1427     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1428
1429     FIXME("(%p,%s,%ld,%p,%ld,%p,%ld), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
1430     return E_PROP_ID_UNSUPPORTED;
1431 }
1432
1433 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
1434     LPKSPROPERTYSET iface,
1435     REFGUID guidPropSet,
1436     ULONG dwPropID,
1437     PULONG pTypeSupport )
1438 {
1439     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1440     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
1441
1442     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1443         switch (dwPropID) {
1444         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1445             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1446             return S_OK;
1447         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1448             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1449             return S_OK;
1450         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1451             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1452             return S_OK;
1453         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1454             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1455             return S_OK;
1456         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1457             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1458             return S_OK;
1459         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1460             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1461             return S_OK;
1462         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1463             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1464             return S_OK;
1465         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1466             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1467             return S_OK;
1468         default:
1469             FIXME("unsupported ID: %ld\n",dwPropID);
1470             break;
1471         }
1472     } else {
1473         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1474     }
1475
1476     return E_PROP_ID_UNSUPPORTED;
1477 }
1478
1479 static IKsPropertySetVtbl ikspvt = {
1480     IKsPrivatePropertySetImpl_QueryInterface,
1481     IKsPrivatePropertySetImpl_AddRef,
1482     IKsPrivatePropertySetImpl_Release,
1483     IKsPrivatePropertySetImpl_Get,
1484     IKsPrivatePropertySetImpl_Set,
1485     IKsPrivatePropertySetImpl_QuerySupport
1486 };
1487
1488 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
1489     IKsPrivatePropertySetImpl **piks)
1490 {
1491     IKsPrivatePropertySetImpl *iks;
1492
1493     iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
1494     iks->ref = 0;
1495     iks->lpVtbl = &ikspvt;
1496
1497     *piks = iks;
1498     return S_OK;
1499 }