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