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