rpcrt4: Try a lot harder to resuse existing connections by comparing inside the RpcQu...
[wine] / dlls / dsound / propset.c
1 /*                      DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2002 TransGaming Technologies, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20  */
21
22 #define COBJMACROS
23 #include <stdarg.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "mmsystem.h"
29 #include "winternl.h"
30 #include "winnls.h"
31 #include "vfwmsgs.h"
32 #include "mmddk.h"
33 #include "wine/debug.h"
34 #include "dsound.h"
35 #include "dsdriver.h"
36 #include "dsound_private.h"
37 #include "dsconf.h"
38
39 #ifdef NONAMELESSSTRUCT
40 # define S(x) (x).s
41 #else
42 # define S(x) (x)
43 #endif
44
45 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
46
47
48 /*******************************************************************************
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 %d\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 %d\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=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,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->device;
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,%d,%p,%d,%p,%d)\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->device;
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,%d,%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 IKsBufferPropertySetImpl_Create(
197     IDirectSoundBufferImpl *dsb,
198     IKsBufferPropertySetImpl **piks)
199 {
200     PIDSDRIVERPROPERTYSET ps = NULL;
201     IKsBufferPropertySetImpl *iks;
202     TRACE("(%p,%p)\n",dsb,piks);
203     *piks = NULL;
204
205     if (!dsb->hwbuf)
206         return DSERR_INVALIDPARAM;
207
208     IDsDriver_QueryInterface(dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
209     if (!ps)
210         return DSERR_INVALIDPARAM;
211
212     IUnknown_Release(ps);
213
214     iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
215     if (iks == 0) {
216         WARN("out of memory\n");
217         *piks = NULL;
218         return DSERR_OUTOFMEMORY;
219     }
220
221     iks->ref = 0;
222     iks->dsb = dsb;
223     dsb->iks = iks;
224     iks->lpVtbl = &iksbvt;
225
226     IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
227
228     *piks = iks;
229     return S_OK;
230 }
231
232 HRESULT IKsBufferPropertySetImpl_Destroy(
233     IKsBufferPropertySetImpl *piks)
234 {
235     TRACE("(%p)\n",piks);
236
237     while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
238
239     return S_OK;
240 }
241
242 /*******************************************************************************
243  *              IKsPrivatePropertySet
244  */
245
246 /* IUnknown methods */
247 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
248     LPKSPROPERTYSET iface,
249     REFIID riid,
250     LPVOID *ppobj )
251 {
252     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
253     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
254
255     if (IsEqualIID(riid, &IID_IUnknown) ||
256         IsEqualIID(riid, &IID_IKsPropertySet)) {
257         *ppobj = iface;
258         IUnknown_AddRef(iface);
259         return S_OK;
260     }
261     *ppobj = NULL;
262     return E_NOINTERFACE;
263 }
264
265 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
266 {
267     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
268     ULONG ref = InterlockedIncrement(&(This->ref));
269     TRACE("(%p) ref was %d\n", This, ref - 1);
270     return ref;
271 }
272
273 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
274 {
275     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
276     ULONG ref = InterlockedDecrement(&(This->ref));
277     TRACE("(%p) ref was %d\n", This, ref + 1);
278
279     if (!ref) {
280         HeapFree(GetProcessHeap(), 0, This);
281         TRACE("(%p) released\n", This);
282     }
283     return ref;
284 }
285
286 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
287     LPVOID pPropData,
288     ULONG cbPropData,
289     PULONG pcbReturned )
290 {
291     HRESULT hr = DSERR_INVALIDPARAM;
292     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
293     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
294           pPropData,cbPropData,pcbReturned);
295
296     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA) pPropData;
297
298     if (!ppd) {
299         WARN("invalid parameter: pPropData\n");
300         return DSERR_INVALIDPARAM;
301     }
302
303     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
304         ULONG wod;
305         unsigned int wodn;
306         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
307         wodn = waveOutGetNumDevs();
308         for (wod = 0; wod < wodn; wod++) {
309             WAVEOUTCAPSA capsA;
310             MMRESULT res;
311             res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA));
312             if (res == MMSYSERR_NOERROR) {
313                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
314                     ppd->DeviceId = DSOUND_renderer_guids[wod];
315                     hr = DS_OK;
316                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
317                           ppd->DeviceName);
318                     break;
319                 }
320             }
321         }
322     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
323         ULONG wid;
324         unsigned int widn;
325         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
326         widn = waveInGetNumDevs();
327         for (wid = 0; wid < widn; wid++) {
328             WAVEINCAPSA capsA;
329             MMRESULT res;
330             res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA));
331             if (res == MMSYSERR_NOERROR) {
332                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
333                     ppd->DeviceId = DSOUND_capture_guids[wid];
334                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
335                           ppd->DeviceName);
336                     hr = DS_OK;
337                     break;
338                 }
339             }
340         }
341     }
342
343     if (pcbReturned)
344         *pcbReturned = cbPropData;
345
346     return hr;
347 }
348
349 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
350     LPVOID pPropData,
351     ULONG cbPropData,
352     PULONG pcbReturned )
353 {
354     HRESULT hr = DSERR_INVALIDPARAM;
355     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
356     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
357           pPropData,cbPropData,pcbReturned);
358
359     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA) pPropData;
360
361     if (!ppd) {
362         WARN("invalid parameter: pPropData\n");
363         return DSERR_INVALIDPARAM;
364     }
365
366     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
367         ULONG wod;
368         unsigned int wodn;
369         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
370         wodn = waveOutGetNumDevs();
371         for (wod = 0; wod < wodn; wod++) {
372             WAVEOUTCAPSW capsW;
373             MMRESULT res;
374             res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
375             if (res == MMSYSERR_NOERROR) {
376                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
377                     ppd->DeviceId = DSOUND_renderer_guids[wod];
378                     hr = DS_OK;
379                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
380                           debugstr_w(ppd->DeviceName));
381                     break;
382                 }
383             }
384         }
385     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
386         ULONG wid;
387         unsigned int widn;
388         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
389         widn = waveInGetNumDevs();
390         for (wid = 0; wid < widn; wid++) {
391             WAVEINCAPSW capsW;
392             MMRESULT res;
393             res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
394             if (res == MMSYSERR_NOERROR) {
395                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
396                     ppd->DeviceId = DSOUND_capture_guids[wid];
397                     hr = DS_OK;
398                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
399                           debugstr_w(ppd->DeviceName));
400                     break;
401                 }
402             }
403         }
404     }
405
406     if (pcbReturned)
407         *pcbReturned = cbPropData;
408
409     return hr;
410 }
411
412 static HRESULT WINAPI DSPROPERTY_Description1(
413     LPVOID pPropData,
414     ULONG cbPropData,
415     PULONG pcbReturned )
416 {
417     HRESULT err;
418     GUID guid, dev_guid;
419     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd;
420     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
421         pPropData,cbPropData,pcbReturned);
422
423     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData;
424
425     if (!ppd) {
426         WARN("invalid parameter: pPropData\n");
427         return DSERR_INVALIDPARAM;
428     }
429
430     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
431     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
432         /* default device of type specified by ppd->DataFlow */
433         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
434             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
435         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
436             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
437         } else {
438             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
439         }
440         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
441               pPropData,cbPropData,pcbReturned);
442         return E_PROP_ID_UNSUPPORTED;
443     }
444
445     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
446     GetDeviceID(&ppd->DeviceId, &dev_guid);
447
448     if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
449          IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
450         ULONG wod;
451         unsigned int wodn;
452         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
453         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
454         wodn = waveOutGetNumDevs();
455         for (wod = 0; wod < wodn; wod++) {
456             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
457                 DSDRIVERDESC desc;
458                 ppd->WaveDeviceId = wod;
459                 ppd->Devnode = wod;
460                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
461                 if (err == DS_OK) {
462                     PIDSDRIVER drv = NULL;
463                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
464                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
465                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
466                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
467                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
468                     if (err == DS_OK && drv)
469                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
470                     else
471                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
472                     break;
473                 } else {
474                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
475                     return E_PROP_ID_UNSUPPORTED;
476                 }
477             }
478         }
479     } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
480                 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
481         ULONG wid;
482         unsigned int widn;
483         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
484         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
485         widn = waveInGetNumDevs();
486         for (wid = 0; wid < widn; wid++) {
487             if (IsEqualGUID( &dev_guid, &guid) ) {
488                 DSDRIVERDESC desc;
489                 ppd->WaveDeviceId = wid;
490                 ppd->Devnode = wid;
491                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
492                 if (err == DS_OK) {
493                     PIDSCDRIVER drv;
494                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
495                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
496                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
497                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
498                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
499                     if (err == DS_OK && drv)
500                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
501                     else
502                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
503                     break;
504                 } else {
505                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
506                     return E_PROP_ID_UNSUPPORTED;
507                 }
508             }
509         }
510     } else {
511         BOOL found = FALSE;
512         ULONG wod;
513         unsigned int wodn;
514         /* given specific device so try the render devices first */
515         wodn = waveOutGetNumDevs();
516         for (wod = 0; wod < wodn; wod++) {
517             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
518                 DSDRIVERDESC desc;
519                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
520                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
521                 ppd->WaveDeviceId = wod;
522                 ppd->Devnode = wod;
523                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
524                 if (err == DS_OK) {
525                     PIDSDRIVER drv = NULL;
526                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
527                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
528                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
529                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
530                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
531                     if (err == DS_OK && drv)
532                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
533                     else
534                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
535                     found = TRUE;
536                     break;
537                 } else {
538                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
539                     return E_PROP_ID_UNSUPPORTED;
540                 }
541             }
542         }
543
544         if (found == FALSE) {
545             ULONG wid;
546             unsigned int widn;
547             /* given specific device so try the capture devices next */
548             widn = waveInGetNumDevs();
549             for (wid = 0; wid < widn; wid++) {
550                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
551                     DSDRIVERDESC desc;
552                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
553                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
554                     ppd->WaveDeviceId = wid;
555                     ppd->Devnode = wid;
556                     err = mmErr(waveInMessage((HWAVEIN)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
557                     if (err == DS_OK) {
558                         PIDSDRIVER drv = NULL;
559                         lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
560                         lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
561                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
562                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
563                         err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
564                         if (err == DS_OK && drv)
565                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
566                         else
567                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
568                         found = TRUE;
569                         break;
570                     } else {
571                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
572                         return E_PROP_ID_UNSUPPORTED;
573                     }
574                 }
575             }
576
577             if (found == FALSE) {
578                 WARN("device not found\n");
579                 return E_PROP_ID_UNSUPPORTED;
580             }
581         }
582     }
583
584     if (pcbReturned) {
585         *pcbReturned = cbPropData;
586         TRACE("*pcbReturned=%d\n", *pcbReturned);
587     }
588
589     return S_OK;
590 }
591
592 static HRESULT WINAPI DSPROPERTY_DescriptionA(
593     LPVOID pPropData,
594     ULONG cbPropData,
595     PULONG pcbReturned )
596 {
597     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
598     HRESULT err;
599     GUID dev_guid;
600     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
601           pPropData,cbPropData,pcbReturned);
602
603     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
604     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
605         /* default device of type specified by ppd->DataFlow */
606         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
607             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
608         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
609             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
610         } else {
611             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
612         }
613         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
614               pPropData,cbPropData,pcbReturned);
615         return E_PROP_ID_UNSUPPORTED;
616     }
617
618     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
619     GetDeviceID(&ppd->DeviceId, &dev_guid);
620
621     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
622          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
623         ULONG wod;
624         unsigned int wodn;
625         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
626             TRACE("DSDEVID_DefaultPlayback\n");
627         else
628             TRACE("DSDEVID_DefaultVoicePlayback\n");
629         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
630         wodn = waveOutGetNumDevs();
631         for (wod = 0; wod < wodn; wod++) {
632             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
633                 DSDRIVERDESC desc;
634                 ppd->WaveDeviceId = wod;
635                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
636                 if (err == DS_OK) {
637                     PIDSDRIVER drv = NULL;
638                     /* FIXME: this is a memory leak */
639                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
640                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
641                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
642
643                     if (szDescription && szModule && szInterface) {
644                         strcpy(szDescription, desc.szDesc);
645                         strcpy(szModule, desc.szDrvname);
646                         strcpy(szInterface, "Interface");
647
648                         ppd->Description = szDescription;
649                         ppd->Module = szModule;
650                         ppd->Interface = szInterface;
651                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
652                         if (err == DS_OK && drv)
653                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
654                         else
655                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
656                         break;
657                     } else {
658                         WARN("no memory\n");
659                         HeapFree(GetProcessHeap(), 0, szDescription);
660                         HeapFree(GetProcessHeap(), 0, szModule);
661                         HeapFree(GetProcessHeap(), 0, szInterface);
662                         return E_OUTOFMEMORY;
663                     }
664                 } else {
665                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
666                     return E_PROP_ID_UNSUPPORTED;
667                 }
668             }
669         }
670     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
671                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
672         ULONG wid;
673         unsigned int widn;
674         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) )
675             TRACE("DSDEVID_DefaultCapture\n");
676         else
677             TRACE("DSDEVID_DefaultVoiceCapture\n");
678         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
679         widn = waveInGetNumDevs();
680         for (wid = 0; wid < widn; wid++) {
681             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
682                 DSDRIVERDESC desc;
683                 ppd->WaveDeviceId = wid;
684                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
685                 if (err == DS_OK) {
686                     PIDSCDRIVER drv;
687                     /* FIXME: this is a memory leak */
688                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
689                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
690                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
691
692                     if (szDescription && szModule && szInterface) {
693                         strcpy(szDescription, desc.szDesc);
694                         strcpy(szModule, desc.szDrvname);
695                         strcpy(szInterface, "Interface");
696
697                         ppd->Description = szDescription;
698                         ppd->Module = szModule;
699                         ppd->Interface = szInterface;
700                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
701                         if (err == DS_OK && drv)
702                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
703                         else
704                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
705                         break;
706                     } else {
707                         WARN("no memory\n");
708                         HeapFree(GetProcessHeap(), 0, szDescription);
709                         HeapFree(GetProcessHeap(), 0, szModule);
710                         HeapFree(GetProcessHeap(), 0, szInterface);
711                         return E_OUTOFMEMORY;
712                     }
713                 } else {
714                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
715                     return E_PROP_ID_UNSUPPORTED;
716                 }
717             }
718         }
719     } else {
720         BOOL found = FALSE;
721         ULONG wod;
722         unsigned int wodn;
723         /* given specific device so try the render devices first */
724         TRACE("Checking renderer devices\n");
725         wodn = waveOutGetNumDevs();
726         for (wod = 0; wod < wodn; wod++) {
727             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
728                 DSDRIVERDESC desc;
729                 TRACE("DSOUND_renderer_guids[%d]\n", wod);
730                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
731                 ppd->WaveDeviceId = wod;
732                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
733                 if (err == DS_OK) {
734                     PIDSDRIVER drv = NULL;
735                     /* FIXME: this is a memory leak */
736                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
737                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
738                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
739
740                     if (szDescription && szModule && szInterface) {
741                         strcpy(szDescription, desc.szDesc);
742                         strcpy(szModule, desc.szDrvname);
743                         strcpy(szInterface, "Interface");
744
745                         ppd->Description = szDescription;
746                         ppd->Module = szModule;
747                         ppd->Interface = szInterface;
748                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
749                         if (err == DS_OK && drv)
750                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
751                         else
752                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
753                         found = TRUE;
754                         break;
755                     } else {
756                         WARN("no memory\n");
757                         HeapFree(GetProcessHeap(), 0, szDescription);
758                         HeapFree(GetProcessHeap(), 0, szModule);
759                         HeapFree(GetProcessHeap(), 0, szInterface);
760                         return E_OUTOFMEMORY;
761                     }
762                 } else {
763                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
764                     return E_PROP_ID_UNSUPPORTED;
765                 }
766             }
767         }
768
769         if (found == FALSE) {
770             ULONG wid;
771             unsigned int widn;
772             TRACE("Checking capture devices\n");
773             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
774             widn = waveInGetNumDevs();
775             for (wid = 0; wid < widn; wid++) {
776                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
777                     DSDRIVERDESC desc;
778                     TRACE("DSOUND_capture_guids[%d]\n", wid);
779                     ppd->WaveDeviceId = wid;
780                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
781                     if (err == DS_OK) {
782                         PIDSCDRIVER drv;
783                         /* FIXME: this is a memory leak */
784                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
785                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
786                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
787
788                         if (szDescription && szModule && szInterface) {
789                             strcpy(szDescription, desc.szDesc);
790                             strcpy(szModule, desc.szDrvname);
791                             strcpy(szInterface, "Interface");
792
793                             ppd->Description = szDescription;
794                             ppd->Module = szModule;
795                             ppd->Interface = szInterface;
796                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
797                             if (err == DS_OK && drv)
798                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
799                             else
800                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
801                             found = TRUE;
802                             break;
803                         } else {
804                             WARN("no memory\n");
805                             HeapFree(GetProcessHeap(), 0, szDescription);
806                             HeapFree(GetProcessHeap(), 0, szModule);
807                             HeapFree(GetProcessHeap(), 0, szInterface);
808                             return E_OUTOFMEMORY;
809                         }
810                     } else {
811                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
812                         return E_PROP_ID_UNSUPPORTED;
813                     }
814                 }
815             }
816         }
817
818         if (found == FALSE) {
819             WARN("device not found\n");
820             return E_PROP_ID_UNSUPPORTED;
821         }
822     }
823
824     if (pcbReturned) {
825         *pcbReturned = cbPropData;
826         TRACE("*pcbReturned=%d\n", *pcbReturned);
827     }
828
829     return S_OK;
830 }
831
832 static HRESULT WINAPI DSPROPERTY_DescriptionW(
833     LPVOID pPropData,
834     ULONG cbPropData,
835     PULONG pcbReturned )
836 {
837     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
838     HRESULT err;
839     GUID dev_guid;
840     TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
841           pPropData,cbPropData,pcbReturned);
842
843     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
844     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
845         /* default device of type specified by ppd->DataFlow */
846         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
847             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
848         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
849             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
850         } else {
851             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
852         }
853         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
854               pPropData,cbPropData,pcbReturned);
855         return E_PROP_ID_UNSUPPORTED;
856     }
857
858     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
859     GetDeviceID(&ppd->DeviceId, &dev_guid);
860
861     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
862          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
863         ULONG wod;
864         unsigned int wodn;
865         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
866             TRACE("DSDEVID_DefaultPlayback\n");
867         else
868             TRACE("DSDEVID_DefaultVoicePlayback\n");
869         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
870         wodn = waveOutGetNumDevs();
871         for (wod = 0; wod < wodn; wod++) {
872             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
873                 DSDRIVERDESC desc;
874                 TRACE("DSOUND_renderer_guids[%d]\n", wod);
875                 ppd->WaveDeviceId = wod;
876                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
877                 if (err == DS_OK) {
878                     PIDSDRIVER drv = NULL;
879                     /* FIXME: this is a memory leak */
880                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
881                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
882                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
883
884                     if (wDescription && wModule && wInterface) {
885                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
886                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
887                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
888
889                         ppd->Description = wDescription;
890                         ppd->Module = wModule;
891                         ppd->Interface = wInterface;
892                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
893                         if (err == DS_OK && drv)
894                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
895                         else
896                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
897                         break;
898                     } else {
899                         WARN("no memory\n");
900                         HeapFree(GetProcessHeap(), 0, wDescription);
901                         HeapFree(GetProcessHeap(), 0, wModule);
902                         HeapFree(GetProcessHeap(), 0, wInterface);
903                         return E_OUTOFMEMORY;
904                     }
905                 } else {
906                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
907                     return E_PROP_ID_UNSUPPORTED;
908                 }
909             }
910         }
911     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
912                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
913         ULONG wid;
914         unsigned int widn;
915         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture))
916             TRACE("DSDEVID_DefaultCapture\n");
917         else
918             TRACE("DSDEVID_DefaultVoiceCapture\n");
919         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
920         widn = waveInGetNumDevs();
921         for (wid = 0; wid < widn; wid++) {
922             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
923                 DSDRIVERDESC desc;
924                 ppd->WaveDeviceId = wid;
925                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
926                 if (err == DS_OK) {
927                     PIDSCDRIVER drv;
928                     /* FIXME: this is a memory leak */
929                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
930                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
931                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
932
933                     if (wDescription && wModule && wInterface) {
934                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
935                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
936                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
937
938                         ppd->Description = wDescription;
939                         ppd->Module = wModule;
940                         ppd->Interface = wInterface;
941                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
942                         if (err == DS_OK && drv)
943                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
944                         else
945                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
946                         break;
947                     } else {
948                         WARN("no memory\n");
949                         HeapFree(GetProcessHeap(), 0, wDescription);
950                         HeapFree(GetProcessHeap(), 0, wModule);
951                         HeapFree(GetProcessHeap(), 0, wInterface);
952                         return E_OUTOFMEMORY;
953                     }
954                 } else {
955                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
956                     return E_PROP_ID_UNSUPPORTED;
957                 }
958             }
959         }
960     } else {
961         BOOL found = FALSE;
962         ULONG wod;
963         unsigned int wodn;
964         TRACE("Checking renderer devices\n");
965         /* given specific device so try the render devices first */
966         wodn = waveOutGetNumDevs();
967         for (wod = 0; wod < wodn; wod++) {
968             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
969                 DSDRIVERDESC desc;
970                 TRACE("DSOUND_renderer_guids[%d]\n", wod);
971                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
972                 ppd->WaveDeviceId = wod;
973                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
974                 if (err == DS_OK) {
975                     PIDSDRIVER drv = NULL;
976                     /* FIXME: this is a memory leak */
977                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
978                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
979                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
980
981                     if (wDescription && wModule && wInterface) {
982                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
983                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
984                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
985
986                         ppd->Description = wDescription;
987                         ppd->Module = wModule;
988                         ppd->Interface = wInterface;
989                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
990                         if (err == DS_OK && drv)
991                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
992                         else
993                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
994                         found = TRUE;
995                         break;
996                     } else {
997                         WARN("no memory\n");
998                         HeapFree(GetProcessHeap(), 0, wDescription);
999                         HeapFree(GetProcessHeap(), 0, wModule);
1000                         HeapFree(GetProcessHeap(), 0, wInterface);
1001                         return E_OUTOFMEMORY;
1002                     }
1003                 } else {
1004                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
1005                     return E_PROP_ID_UNSUPPORTED;
1006                 }
1007             }
1008         }
1009
1010         if (found == FALSE) {
1011             ULONG wid;
1012             unsigned int widn;
1013             TRACE("Checking capture devices\n");
1014             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1015             widn = waveInGetNumDevs();
1016             for (wid = 0; wid < widn; wid++) {
1017                 if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
1018                     DSDRIVERDESC desc;
1019                     TRACE("DSOUND_capture_guids[%d]\n", wid);
1020                     ppd->WaveDeviceId = wid;
1021                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
1022                     if (err == DS_OK) {
1023                         PIDSCDRIVER drv;
1024                         /* FIXME: this is a memory leak */
1025                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
1026                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
1027                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
1028
1029                         if (wDescription && wModule && wInterface) {
1030                             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
1031                             MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
1032                             MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
1033
1034                             ppd->Description = wDescription;
1035                             ppd->Module = wModule;
1036                             ppd->Interface = wInterface;
1037                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
1038                             if (err == DS_OK && drv)
1039                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1040                             else
1041                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1042                             found = TRUE;
1043                             break;
1044                         } else {
1045                             WARN("no memory\n");
1046                             HeapFree(GetProcessHeap(), 0, wDescription);
1047                             HeapFree(GetProcessHeap(), 0, wModule);
1048                             HeapFree(GetProcessHeap(), 0, wInterface);
1049                             return E_OUTOFMEMORY;
1050                         }
1051                     } else {
1052                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
1053                         return E_PROP_ID_UNSUPPORTED;
1054                     }
1055                 }
1056             }
1057         }
1058
1059         if (found == FALSE) {
1060             WARN("device not found\n");
1061             return E_PROP_ID_UNSUPPORTED;
1062         }
1063     }
1064
1065     if (pcbReturned) {
1066         *pcbReturned = cbPropData;
1067         TRACE("*pcbReturned=%d\n", *pcbReturned);
1068     }
1069
1070     return S_OK;
1071 }
1072
1073 static HRESULT WINAPI DSPROPERTY_Enumerate1(
1074     LPVOID pPropData,
1075     ULONG cbPropData,
1076     PULONG pcbReturned )
1077 {
1078     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData;
1079     HRESULT err;
1080     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
1081           pPropData,cbPropData,pcbReturned);
1082
1083     if (ppd) {
1084         if (ppd->Callback) {
1085             unsigned devs, wod, wid;
1086             DSDRIVERDESC desc;
1087             DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data;
1088
1089             devs = waveOutGetNumDevs();
1090             for (wod = 0; wod < devs; ++wod) {
1091                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1092                 if (err == DS_OK) {
1093                     PIDSCDRIVER drv;
1094                     ZeroMemory(&data, sizeof(data));
1095                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1096                     data.WaveDeviceId = wod;
1097                     data.DeviceId = DSOUND_renderer_guids[wod];
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)/sizeof(WCHAR) );
1102                     MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
1103
1104                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1105                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1106                     if (err == DS_OK && drv)
1107                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1108                     else
1109                         WARN("waveOutMessage(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             devs = waveInGetNumDevs();
1117             for (wid = 0; wid < devs; ++wid) {
1118                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1119                 if (err == DS_OK) {
1120                     PIDSCDRIVER drv;
1121                     ZeroMemory(&data, sizeof(data));
1122                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1123                     data.WaveDeviceId = wid;
1124                     data.DeviceId = DSOUND_capture_guids[wid];
1125                     lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
1126                     lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));
1127
1128                     MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
1129                     MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );
1130
1131                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1132                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1133                     if (err == DS_OK && drv)
1134                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1135                     else
1136                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1137
1138                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1139                     (ppd->Callback)(&data, ppd->Context);
1140                 }
1141             }
1142
1143             return S_OK;
1144         }
1145     }
1146
1147     if (pcbReturned) {
1148         *pcbReturned = 0;
1149         FIXME("*pcbReturned=%d\n", *pcbReturned);
1150     }
1151
1152     return E_PROP_ID_UNSUPPORTED;
1153 }
1154
1155 static HRESULT WINAPI DSPROPERTY_EnumerateA(
1156     LPVOID pPropData,
1157     ULONG cbPropData,
1158     PULONG pcbReturned )
1159 {
1160     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
1161     HRESULT err;
1162     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
1163           pPropData,cbPropData,pcbReturned);
1164
1165     if (ppd) {
1166         if (ppd->Callback) {
1167             unsigned devs, wod, wid;
1168             DSDRIVERDESC desc;
1169             DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
1170
1171             devs = waveOutGetNumDevs();
1172             for (wod = 0; wod < devs; ++wod) {
1173                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1174                 if (err == DS_OK) {
1175                     DWORD size;
1176                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1177                     if (err == DS_OK) {
1178                         WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1179                         if (nameW) {
1180                             err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1181                             if (err == DS_OK) {
1182                                 CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1183                                 if (szInterface) {
1184                                     PIDSCDRIVER drv;
1185                                     ZeroMemory(&data, sizeof(data));
1186                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
1187                                     data.WaveDeviceId = wod;
1188                                     data.DeviceId = DSOUND_renderer_guids[wod];
1189                                     data.Description = desc.szDesc;
1190                                     data.Module = desc.szDrvname;
1191                                     WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1192                                     data.Interface = szInterface;
1193
1194                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1195                                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1196                                     if (err == DS_OK && drv)
1197                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1198                                     else
1199                                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1200
1201                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1202                                     (ppd->Callback)(&data, ppd->Context);
1203                                 }
1204                                 HeapFree(GetProcessHeap(),0,szInterface);
1205                             }
1206                         }
1207                         HeapFree(GetProcessHeap(),0,nameW);
1208                     }
1209                 }
1210             }
1211
1212             devs = waveInGetNumDevs();
1213             for (wid = 0; wid < devs; ++wid) {
1214                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
1215                 if (err == DS_OK) {
1216                     DWORD size;
1217                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
1218                     if (err == DS_OK) {
1219                         WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
1220                         if (nameW) {
1221                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
1222                             if (err == DS_OK) {
1223                                 CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
1224                                 if (szInterface) {
1225                                     PIDSCDRIVER drv;
1226                                     ZeroMemory(&data, sizeof(data));
1227                                     data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
1228                                     data.WaveDeviceId = wid;
1229                                     data.DeviceId = DSOUND_capture_guids[wid];
1230                                     data.Description = desc.szDesc;
1231                                     data.Module = desc.szDrvname;
1232                                     WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
1233                                     data.Interface = szInterface;
1234
1235                                     data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
1236                                     err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
1237                                     if (err == DS_OK && drv)
1238                                         data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
1239                                     else
1240                                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
1241
1242                                     TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
1243                                     (ppd->Callback)(&data, ppd->Context);
1244                                 }
1245                                 HeapFree(GetProcessHeap(),0,szInterface);
1246                             }
1247                         }
1248                         HeapFree(GetProcessHeap(),0,nameW);
1249                     }
1250                 }
1251             }
1252
1253             return S_OK;
1254         }
1255     }
1256
1257     if (pcbReturned) {
1258         *pcbReturned = 0;
1259         FIXME("*pcbReturned=%d\n", *pcbReturned);
1260     }
1261
1262     return E_PROP_ID_UNSUPPORTED;
1263 }
1264
1265 static HRESULT WINAPI DSPROPERTY_EnumerateW(
1266     LPVOID pPropData,
1267     ULONG cbPropData,
1268     PULONG pcbReturned )
1269 {
1270     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
1271     HRESULT err;
1272     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
1273           pPropData,cbPropData,pcbReturned);
1274
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_PTR)&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_PTR)&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_PTR)&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_PTR)&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
1376     if (pcbReturned) {
1377         *pcbReturned = 0;
1378         FIXME("*pcbReturned=%d\n", *pcbReturned);
1379     }
1380
1381     return E_PROP_ID_UNSUPPORTED;
1382 }
1383
1384 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
1385     LPKSPROPERTYSET iface,
1386     REFGUID guidPropSet,
1387     ULONG dwPropID,
1388     LPVOID pInstanceData,
1389     ULONG cbInstanceData,
1390     LPVOID pPropData,
1391     ULONG cbPropData,
1392     PULONG pcbReturned )
1393 {
1394     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1395     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
1396           This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
1397
1398     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1399         switch (dwPropID) {
1400         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1401             return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
1402         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1403             return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
1404         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1405             return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
1406         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1407             return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
1408         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1409             return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
1410         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1411             return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
1412         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1413             return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
1414         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1415             return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
1416         default:
1417             FIXME("unsupported ID: %d\n",dwPropID);
1418             break;
1419         }
1420     } else {
1421         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1422     }
1423
1424     if (pcbReturned) {
1425         *pcbReturned = 0;
1426         FIXME("*pcbReturned=%d\n", *pcbReturned);
1427     }
1428
1429     return E_PROP_ID_UNSUPPORTED;
1430 }
1431
1432 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
1433     LPKSPROPERTYSET iface,
1434     REFGUID guidPropSet,
1435     ULONG dwPropID,
1436     LPVOID pInstanceData,
1437     ULONG cbInstanceData,
1438     LPVOID pPropData,
1439     ULONG cbPropData )
1440 {
1441     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1442
1443     FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
1444     return E_PROP_ID_UNSUPPORTED;
1445 }
1446
1447 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
1448     LPKSPROPERTYSET iface,
1449     REFGUID guidPropSet,
1450     ULONG dwPropID,
1451     PULONG pTypeSupport )
1452 {
1453     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1454     TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
1455
1456     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1457         switch (dwPropID) {
1458         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1459             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1460             return S_OK;
1461         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1462             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1463             return S_OK;
1464         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1465             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1466             return S_OK;
1467         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1468             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1469             return S_OK;
1470         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1471             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1472             return S_OK;
1473         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1474             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1475             return S_OK;
1476         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1477             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1478             return S_OK;
1479         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1480             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1481             return S_OK;
1482         default:
1483             FIXME("unsupported ID: %d\n",dwPropID);
1484             break;
1485         }
1486     } else {
1487         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1488     }
1489
1490     return E_PROP_ID_UNSUPPORTED;
1491 }
1492
1493 static const IKsPropertySetVtbl ikspvt = {
1494     IKsPrivatePropertySetImpl_QueryInterface,
1495     IKsPrivatePropertySetImpl_AddRef,
1496     IKsPrivatePropertySetImpl_Release,
1497     IKsPrivatePropertySetImpl_Get,
1498     IKsPrivatePropertySetImpl_Set,
1499     IKsPrivatePropertySetImpl_QuerySupport
1500 };
1501
1502 HRESULT IKsPrivatePropertySetImpl_Create(
1503     REFIID riid,
1504     IKsPrivatePropertySetImpl **piks)
1505 {
1506     IKsPrivatePropertySetImpl *iks;
1507     TRACE("(%s, %p)\n", debugstr_guid(riid), piks);
1508
1509     if (!IsEqualIID(riid, &IID_IUnknown) &&
1510         !IsEqualIID(riid, &IID_IKsPropertySet)) {
1511         *piks = 0;
1512         return E_NOINTERFACE;
1513     }
1514
1515     iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
1516     iks->ref = 1;
1517     iks->lpVtbl = &ikspvt;
1518
1519     *piks = iks;
1520     return S_OK;
1521 }