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