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