Removed W->A from DEFWND_ImmIsUIMessageW.
[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 "config.h"
23 #include <assert.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <sys/types.h>
27 #include <sys/fcntl.h>
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>       /* Insomnia - pow() function */
34
35 #define NONAMELESSUNION
36 #define NONAMELESSSTRUCT
37 #include "windef.h"
38 #include "winbase.h"
39 #include "wingdi.h"
40 #include "winuser.h"
41 #include "winerror.h"
42 #include "mmsystem.h"
43 #include "winreg.h"
44 #include "winternl.h"
45 #include "winnls.h"
46 #include "mmddk.h"
47 #include "wine/windef16.h"
48 #include "wine/debug.h"
49 #include "dsound.h"
50 #include "dsdriver.h"
51 #include "dsound_private.h"
52 #include "initguid.h"
53 #include "dsconf.h"
54
55 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
56
57
58 /*******************************************************************************
59  *              IKsBufferPropertySet
60  */
61
62 /* IUnknown methods */
63 static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(
64     LPKSPROPERTYSET iface,
65     REFIID riid,
66     LPVOID *ppobj )
67 {
68     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
69     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
70
71     return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
72 }
73
74 static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
75 {
76     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
77     TRACE("(%p) ref was %ld\n", This, This->ref);
78     return InterlockedIncrement(&(This->ref));
79 }
80
81 static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
82 {
83     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
84     ULONG ulReturn;
85
86     TRACE("(%p) ref was %ld\n", This, This->ref);
87     ulReturn = InterlockedDecrement(&(This->ref));
88     if (!ulReturn) {
89         This->dsb->iks = 0;
90         IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
91         HeapFree(GetProcessHeap(),0,This);
92         TRACE("(%p) released\n",This);
93     }
94     return ulReturn;
95 }
96
97 static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
98     LPKSPROPERTYSET iface,
99     REFGUID guidPropSet,
100     ULONG dwPropID,
101     LPVOID pInstanceData,
102     ULONG cbInstanceData,
103     LPVOID pPropData,
104     ULONG cbPropData,
105     PULONG pcbReturned )
106 {
107     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
108     PIDSDRIVERPROPERTYSET ps;
109     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
110         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
111
112     IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
113
114     if (ps) {
115         DSPROPERTY prop;
116         HRESULT hres;
117
118         prop.s.Set = *guidPropSet;
119         prop.s.Id = dwPropID;
120         prop.s.Flags = 0;       /* unused */
121         prop.s.InstanceId = (ULONG)This->dsb->dsound;
122
123         hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
124
125         IDsDriverPropertySet_Release(ps);
126
127         return hres;
128     }
129
130     return E_PROP_ID_UNSUPPORTED;
131 }
132
133 static HRESULT WINAPI IKsBufferPropertySetImpl_Set(
134     LPKSPROPERTYSET iface,
135     REFGUID guidPropSet,
136     ULONG dwPropID,
137     LPVOID pInstanceData,
138     ULONG cbInstanceData,
139     LPVOID pPropData,
140     ULONG cbPropData )
141 {
142     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
143     PIDSDRIVERPROPERTYSET ps;
144     TRACE("(%p,%s,%ld,%p,%ld,%p,%ld)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
145
146     IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
147
148     if (ps) {
149         DSPROPERTY prop;
150         HRESULT hres;
151
152         prop.s.Set = *guidPropSet;
153         prop.s.Id = dwPropID;
154         prop.s.Flags = 0;       /* unused */
155         prop.s.InstanceId = (ULONG)This->dsb->dsound;
156         hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);
157
158         IDsDriverPropertySet_Release(ps);
159
160         return hres;
161     }
162
163     return E_PROP_ID_UNSUPPORTED;
164 }
165
166 static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(
167     LPKSPROPERTYSET iface,
168     REFGUID guidPropSet,
169     ULONG dwPropID,
170     PULONG pTypeSupport )
171 {
172     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
173     PIDSDRIVERPROPERTYSET ps;
174     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
175
176     IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
177
178     if (ps) {
179         HRESULT hres;
180
181         hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);
182
183         IDsDriverPropertySet_Release(ps);
184
185         return hres;
186     }
187
188     return E_PROP_ID_UNSUPPORTED;
189 }
190
191 static IKsPropertySetVtbl iksbvt = {
192     IKsBufferPropertySetImpl_QueryInterface,
193     IKsBufferPropertySetImpl_AddRef,
194     IKsBufferPropertySetImpl_Release,
195     IKsBufferPropertySetImpl_Get,
196     IKsBufferPropertySetImpl_Set,
197     IKsBufferPropertySetImpl_QuerySupport
198 };
199
200 HRESULT WINAPI IKsBufferPropertySetImpl_Create(
201     IDirectSoundBufferImpl *dsb,
202     IKsBufferPropertySetImpl **piks)
203 {
204     IKsBufferPropertySetImpl *iks;
205     TRACE("(%p,%p)\n",dsb,piks);
206
207     iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
208     iks->ref = 0;
209     iks->dsb = dsb;
210     dsb->iks = iks;
211     iks->lpVtbl = &iksbvt;
212
213     IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
214
215     *piks = iks;
216     return S_OK;
217 }
218
219 HRESULT WINAPI IKsBufferPropertySetImpl_Destroy(
220     IKsBufferPropertySetImpl *piks)
221 {
222     TRACE("(%p)\n",piks);
223
224     while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
225
226     return S_OK;
227 }
228
229 /*******************************************************************************
230  *              IKsPrivatePropertySet
231  */
232
233 /* IUnknown methods */
234 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
235     LPKSPROPERTYSET iface,
236     REFIID riid,
237     LPVOID *ppobj )
238 {
239     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
240     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
241
242     *ppobj = NULL;
243     return DSERR_INVALIDPARAM;
244 }
245
246 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
247 {
248     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
249     TRACE("(%p) ref was %ld\n", This, This->ref);
250     return InterlockedIncrement(&(This->ref));
251 }
252
253 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
254 {
255     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
256     ULONG ulReturn;
257
258     TRACE("(%p) ref was %ld\n", This, This->ref);
259     ulReturn = InterlockedDecrement(&(This->ref));
260     if (ulReturn == 0) {
261         HeapFree(GetProcessHeap(),0,This);
262         TRACE("(%p) released\n",This);
263     }
264     return ulReturn;
265 }
266
267 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
268     REFGUID guidPropSet,
269     LPVOID pPropData,
270     ULONG cbPropData,
271     PULONG pcbReturned )
272 {
273     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
274     FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) not implemented!\n",
275         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
276
277     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA) pPropData;
278
279     if (!ppd) {
280         WARN("invalid parameter: pPropData\n");
281         return DSERR_INVALIDPARAM;
282     }
283
284     FIXME("DeviceName=%s\n",ppd->DeviceName);
285     FIXME("DataFlow=%s\n",
286         ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "DIRECTSOUNDDEVICE_DATAFLOW_RENDER" :
287         ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ? "DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE" : "UNKNOWN");
288
289     /* FIXME: match the name to a wave device somehow. */
290     ppd->DeviceId = GUID_NULL;
291
292     if (pcbReturned) {
293         *pcbReturned = cbPropData;
294         FIXME("*pcbReturned=%ld\n", *pcbReturned);
295     }
296
297     return S_OK;
298 }
299
300 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
301     REFGUID guidPropSet,
302     LPVOID pPropData,
303     ULONG cbPropData,
304     PULONG pcbReturned )
305 {
306     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
307     FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) not implemented!\n",
308         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
309
310     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA) pPropData;
311
312     if (!ppd) {
313         WARN("invalid parameter: pPropData\n");
314         return DSERR_INVALIDPARAM;
315     }
316
317     FIXME("DeviceName=%s\n",debugstr_w(ppd->DeviceName));
318     FIXME("DataFlow=%s\n",
319         ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER ? "DIRECTSOUNDDEVICE_DATAFLOW_RENDER" :
320         ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE ? "DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE" : "UNKNOWN");
321
322     /* FIXME: match the name to a wave device somehow. */
323     ppd->DeviceId = GUID_NULL;
324
325     if (pcbReturned) {
326         *pcbReturned = cbPropData;
327         FIXME("*pcbReturned=%ld\n", *pcbReturned);
328     }
329
330     return S_OK;
331 }
332
333 static HRESULT WINAPI DSPROPERTY_Description1(
334     REFGUID guidPropSet,
335     LPVOID pPropData,
336     ULONG cbPropData,
337     PULONG pcbReturned )
338 {
339     HRESULT err;
340     GUID guid, dev_guid;
341     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_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_DESCRIPTION_1_DATA) pPropData;
346
347     if (!ppd) {
348         WARN("invalid parameter: pPropData\n");
349         return DSERR_INVALIDPARAM;
350     }
351
352     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
353     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
354         /* default device of type specified by ppd->DataFlow */
355         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
356             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
357         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
358             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
359         } else {
360             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
361         }
362         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
363             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
364         return E_PROP_ID_UNSUPPORTED;
365     }
366
367     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
368     GetDeviceID(&ppd->DeviceId, &dev_guid);
369
370     if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
371          IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
372         ULONG wod;
373         unsigned int wodn;
374         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
375         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
376         wodn = waveOutGetNumDevs();
377         for (wod = 0; wod < wodn; wod++) {
378             if (IsEqualGUID( &dev_guid, &renderer_guids[wod] ) ) {
379                 DSDRIVERDESC desc;
380                 ppd->WaveDeviceId = wod;
381                 ppd->Devnode = wod;
382                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
383                 if (err == DS_OK) {
384                     PIDSDRIVER drv = NULL;
385                     strncpy(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA) - 1);
386                     strncpy(ppd->ModuleA, desc.szDrvName, sizeof(ppd->ModuleA) - 1);
387                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
388                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
389                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
390                     if (err == DS_OK && drv)
391                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
392                     break;
393                 } else {
394                     WARN("waveOutMessage failed\n");
395                     return E_PROP_ID_UNSUPPORTED;
396                 }
397             }
398         }
399     } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
400                 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
401         ULONG wid;
402         unsigned int widn;
403         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
404         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
405         widn = waveInGetNumDevs();
406         for (wid = 0; wid < widn; wid++) {
407             if (IsEqualGUID( &dev_guid, &guid) ) {
408                 DSDRIVERDESC desc;
409                 ppd->WaveDeviceId = wid;
410                 ppd->Devnode = wid;
411                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
412                 if (err == DS_OK) {
413                     PIDSCDRIVER drv;
414                     strncpy(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA) - 1);
415                     strncpy(ppd->ModuleA, desc.szDrvName, sizeof(ppd->ModuleA) - 1);
416                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
417                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
418                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
419                     if (err == DS_OK && drv)
420                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
421                     break;
422                 } else {
423                     WARN("waveInMessage failed\n");
424                     return E_PROP_ID_UNSUPPORTED;
425                 }
426             }
427         }
428     } else {
429         BOOL found = FALSE;
430         ULONG wod;
431         unsigned int wodn;
432         /* given specific device so try the render devices first */
433         wodn = waveOutGetNumDevs();
434         for (wod = 0; wod < wodn; wod++) {
435             if (IsEqualGUID( &ppd->DeviceId, &renderer_guids[wod] ) ) {
436                 DSDRIVERDESC desc;
437                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
438                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
439                 ppd->WaveDeviceId = wod;
440                 ppd->Devnode = wod;
441                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
442                 if (err == DS_OK) {
443                     PIDSDRIVER drv = NULL;
444                     strncpy(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA) - 1);
445                     strncpy(ppd->ModuleA, desc.szDrvName, sizeof(ppd->ModuleA) - 1);
446                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
447                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
448                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
449                     if (err == DS_OK && drv)
450                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
451                     found = TRUE;
452                     break;
453                 } else {
454                     WARN("waveOutMessage failed\n");
455                     return E_PROP_ID_UNSUPPORTED;
456                 }
457             }
458         }
459
460         if (found == FALSE) {
461             ULONG wid;
462             unsigned int widn;
463             /* given specific device so try the capture devices next */
464             widn = waveInGetNumDevs();
465             for (wid = 0; wid < widn; wid++) {
466                 if (IsEqualGUID( &ppd->DeviceId, &capture_guids[wid] ) ) {
467                     DSDRIVERDESC desc;
468                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
469                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
470                     ppd->WaveDeviceId = wid;
471                     ppd->Devnode = wid;
472                     err = mmErr(waveInMessage((HWAVEIN)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
473                     if (err == DS_OK) {
474                         PIDSDRIVER drv = NULL;
475                         strncpy(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA) - 1);
476                         strncpy(ppd->ModuleA, desc.szDrvName, sizeof(ppd->ModuleA) - 1);
477                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
478                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
479                         err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
480                         if (err == DS_OK && drv)
481                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
482                         found = TRUE;
483                         break;
484                     } else {
485                         WARN("waveInMessage failed\n");
486                         return E_PROP_ID_UNSUPPORTED;
487                     }
488                 }
489             }
490
491             if (found == FALSE) {
492                 WARN("device not found\n");
493                 return E_PROP_ID_UNSUPPORTED;
494             }
495         }
496     }
497
498     if (pcbReturned) {
499         *pcbReturned = cbPropData;
500         TRACE("*pcbReturned=%ld\n", *pcbReturned);
501     }
502
503     return S_OK;
504 }
505
506 static HRESULT WINAPI DSPROPERTY_DescriptionA(
507     REFGUID guidPropSet,
508     LPVOID pPropData,
509     ULONG cbPropData,
510     PULONG pcbReturned )
511 {
512     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
513     HRESULT err;
514     GUID dev_guid;
515     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
516         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
517
518     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
519     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
520         /* default device of type specified by ppd->DataFlow */
521         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
522             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
523         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
524             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
525         } else {
526             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
527         }
528         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
529             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
530         return E_PROP_ID_UNSUPPORTED;
531     }
532
533     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
534     GetDeviceID(&ppd->DeviceId, &dev_guid);
535
536     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
537          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
538         ULONG wod;
539         unsigned int wodn;
540         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
541         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
542         wodn = waveOutGetNumDevs();
543         for (wod = 0; wod < wodn; wod++) {
544                 if (IsEqualGUID( &dev_guid, &renderer_guids[wod] ) ) {
545                     DSDRIVERDESC desc;
546                     ppd->WaveDeviceId = wod;
547                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
548                     if (err == DS_OK) {
549                         PIDSDRIVER drv = NULL;
550                         /* FIXME: this is a memory leak */
551                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
552                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
553                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
554
555                         strcpy(szDescription, desc.szDesc);
556                         strcpy(szModule, desc.szDrvName);
557                         strcpy(szInterface, "Interface");
558
559                         ppd->Description = szDescription;
560                         ppd->Module = szModule;
561                         ppd->Interface = szInterface;
562                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
563                         if (err == DS_OK && drv)
564                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
565                         break;
566                     } else {
567                         WARN("waveOutMessage failed\n");
568                         return E_PROP_ID_UNSUPPORTED;
569                     }
570                 }
571         }
572     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
573                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
574         ULONG wid;
575         unsigned int widn;
576         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
577         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
578         widn = waveInGetNumDevs();
579         for (wid = 0; wid < widn; wid++) {
580                 if (IsEqualGUID( &dev_guid, &capture_guids[wid] ) ) {
581                     DSDRIVERDESC desc;
582                     ppd->WaveDeviceId = wid;
583                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
584                     if (err == DS_OK) {
585                         PIDSCDRIVER drv;
586                         /* FIXME: this is a memory leak */
587                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
588                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
589                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
590
591                         strcpy(szDescription, desc.szDesc);
592                         strcpy(szModule, desc.szDrvName);
593                         strcpy(szInterface, "Interface");
594
595                         ppd->Description = szDescription;
596                         ppd->Module = szModule;
597                         ppd->Interface = szInterface;
598                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
599                         if (err == DS_OK && drv)
600                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
601                         break;
602                     } else {
603                         WARN("waveInMessage failed\n");
604                         return E_PROP_ID_UNSUPPORTED;
605                     }
606                     break;
607                 }
608         }
609     } else {
610         BOOL found = FALSE;
611         ULONG wod;
612         unsigned int wodn;
613         /* given specific device so try the render devices first */
614         wodn = waveOutGetNumDevs();
615         for (wod = 0; wod < wodn; wod++) {
616                 if (IsEqualGUID( &ppd->DeviceId, &renderer_guids[wod] ) ) {
617                     DSDRIVERDESC desc;
618                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
619                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
620                     ppd->WaveDeviceId = wod;
621                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
622                     if (err == DS_OK) {
623                         PIDSDRIVER drv = NULL;
624                         /* FIXME: this is a memory leak */
625                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
626                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
627                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
628
629                         strcpy(szDescription, desc.szDesc);
630                         strcpy(szModule, desc.szDrvName);
631                         strcpy(szInterface, "Interface");
632
633                         ppd->Description = szDescription;
634                         ppd->Module = szModule;
635                         ppd->Interface = szInterface;
636                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
637                         if (err == DS_OK && drv)
638                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
639                         found = TRUE;
640                         break;
641                     } else {
642                         WARN("waveOutMessage failed\n");
643                         return E_PROP_ID_UNSUPPORTED;
644                     }
645                 }
646         }
647
648         if (found == FALSE) {
649             WARN("device not found\n");
650             return E_PROP_ID_UNSUPPORTED;
651         }
652     }
653
654     if (pcbReturned) {
655         *pcbReturned = cbPropData;
656         TRACE("*pcbReturned=%ld\n", *pcbReturned);
657     }
658
659     return S_OK;
660 }
661
662 static HRESULT WINAPI DSPROPERTY_DescriptionW(
663     REFGUID guidPropSet,
664     LPVOID pPropData,
665     ULONG cbPropData,
666     PULONG pcbReturned )
667 {
668     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
669     HRESULT err;
670     GUID dev_guid;
671     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
672         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
673
674     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
675     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
676         /* default device of type specified by ppd->DataFlow */
677         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
678             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
679         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
680             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
681         } else {
682             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
683         }
684         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
685             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
686         return E_PROP_ID_UNSUPPORTED;
687     }
688
689     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
690     GetDeviceID(&ppd->DeviceId, &dev_guid);
691
692     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
693          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
694         ULONG wod;
695         unsigned int wodn;
696         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
697         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
698         wodn = waveOutGetNumDevs();
699         for (wod = 0; wod < wodn; wod++) {
700                 if (IsEqualGUID( &dev_guid, &renderer_guids[wod] ) ) {
701                     DSDRIVERDESC desc;
702                     ppd->WaveDeviceId = wod;
703                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
704                     if (err == DS_OK) {
705                         PIDSDRIVER drv = NULL;
706                         /* FIXME: this is a memory leak */
707                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
708                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
709                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
710
711                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
712                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
713                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
714
715                         ppd->Description = wDescription;
716                         ppd->Module = wModule;
717                         ppd->Interface = wInterface;
718                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
719                         if (err == DS_OK && drv)
720                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
721                             break;
722                     } else {
723                         WARN("waveOutMessage failed\n");
724                         return E_PROP_ID_UNSUPPORTED;
725                     }
726                 }
727         }
728     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
729                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
730         ULONG wid;
731         unsigned int widn;
732         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
733         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
734         widn = waveInGetNumDevs();
735         for (wid = 0; wid < widn; wid++) {
736                 if (IsEqualGUID( &dev_guid, &capture_guids[wid] ) ) {
737                     DSDRIVERDESC desc;
738                     ppd->WaveDeviceId = wid;
739                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
740                     if (err == DS_OK) {
741                         PIDSCDRIVER drv;
742                         /* FIXME: this is a memory leak */
743                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
744                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
745                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
746
747                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
748                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
749                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
750
751                         ppd->Description = wDescription;
752                         ppd->Module = wModule;
753                         ppd->Interface = wInterface;
754                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
755                         if (err == DS_OK && drv)
756                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
757                         break;
758                     } else {
759                         WARN("waveInMessage failed\n");
760                         return E_PROP_ID_UNSUPPORTED;
761                     }
762                     break;
763                 }
764         }
765     } else {
766         BOOL found = FALSE;
767         ULONG wod;
768         unsigned int wodn;
769         /* given specific device so try the render devices first */
770         wodn = waveOutGetNumDevs();
771         for (wod = 0; wod < wodn; wod++) {
772                 if (IsEqualGUID( &ppd->DeviceId, &renderer_guids[wod] ) ) {
773                     DSDRIVERDESC desc;
774                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
775                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
776                     ppd->WaveDeviceId = wod;
777                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
778                     if (err == DS_OK) {
779                         PIDSDRIVER drv = NULL;
780                         /* FIXME: this is a memory leak */
781                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
782                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
783                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
784
785                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
786                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
787                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
788
789                         ppd->Description = wDescription;
790                         ppd->Module = wModule;
791                         ppd->Interface = wInterface;
792                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
793                         if (err == DS_OK && drv)
794                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
795                         found = TRUE;
796                         break;
797                     } else {
798                         WARN("waveOutMessage failed\n");
799                         return E_PROP_ID_UNSUPPORTED;
800                     }
801                 }
802         }
803
804         if (found == FALSE) {
805             WARN("device not found\n");
806             return E_PROP_ID_UNSUPPORTED;
807         }
808     }
809
810     if (pcbReturned) {
811         *pcbReturned = cbPropData;
812         TRACE("*pcbReturned=%ld\n", *pcbReturned);
813     }
814
815     return S_OK;
816 }
817
818 static HRESULT WINAPI DSPROPERTY_Enumerate1(
819     REFGUID guidPropSet,
820     LPVOID pPropData,
821     ULONG cbPropData,
822     PULONG pcbReturned )
823 {
824     FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
825         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
826     return E_PROP_ID_UNSUPPORTED;
827 }
828
829 static HRESULT WINAPI DSPROPERTY_EnumerateA(
830     REFGUID guidPropSet,
831     LPVOID pPropData,
832     ULONG cbPropData,
833     PULONG pcbReturned )
834 {
835     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
836     HRESULT err;
837     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
838         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
839
840     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
841         if (ppd) {
842             if (ppd->Callback) {
843                 unsigned devs, wod, wid;
844                 DSDRIVERDESC desc;
845                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
846
847                 devs = waveOutGetNumDevs();
848                 for (wod = 0; wod < devs; ++wod) {
849                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
850                     if (err == DS_OK) {
851                         memset(&data, 0, sizeof(data));
852                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
853                         data.WaveDeviceId = wod;
854                         data.DeviceId = renderer_guids[wod];
855                         data.Description = desc.szDesc;
856                         data.Module = desc.szDrvName;
857                         data.Interface = "Interface";
858                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
859                         (ppd->Callback)(&data, ppd->Context);
860                     }
861                 }
862
863                 devs = waveInGetNumDevs();
864                 for (wid = 0; wid < devs; ++wid) {
865                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
866                     if (err == DS_OK) {
867                         memset(&data, 0, sizeof(data));
868                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
869                         data.WaveDeviceId = wid;
870                         data.DeviceId = capture_guids[wid];
871                         data.Description = desc.szDesc;
872                         data.Module = desc.szDrvName;
873                         data.Interface = "Interface";
874                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
875                         (ppd->Callback)(&data, ppd->Context);
876                     }
877                 }
878
879                 return S_OK;
880             }
881         }
882     } else {
883         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
884     }
885
886     if (pcbReturned) {
887         *pcbReturned = 0;
888         FIXME("*pcbReturned=%ld\n", *pcbReturned);
889     }
890
891     return E_PROP_ID_UNSUPPORTED;
892 }
893
894 static HRESULT WINAPI DSPROPERTY_EnumerateW(
895     REFGUID guidPropSet,
896     LPVOID pPropData,
897     ULONG cbPropData,
898     PULONG pcbReturned )
899 {
900     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
901     HRESULT err;
902     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
903         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
904
905     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
906         if (ppd) {
907             if (ppd->Callback) {
908                 unsigned devs, wod, wid;
909                 DSDRIVERDESC desc;
910                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
911
912                 devs = waveOutGetNumDevs();
913                 for (wod = 0; wod < devs; ++wod) {
914                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
915                     if (err == DS_OK) {
916                         /* FIXME: this is a memory leak */
917                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
918                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
919                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
920
921                         memset(&data, 0, sizeof(data));
922                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
923                         data.WaveDeviceId = wod;
924                         data.DeviceId = renderer_guids[wod];
925
926                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
927                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
928                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
929
930                         data.Description = wDescription;
931                         data.Module = wModule;
932                         data.Interface = wInterface;
933                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
934                         (ppd->Callback)(&data, ppd->Context);
935                     }
936                 }
937
938                 devs = waveInGetNumDevs();
939                 for (wid = 0; wid < devs; ++wid) {
940                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
941                     if (err == DS_OK) {
942                         /* FIXME: this is a memory leak */
943                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
944                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
945                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
946
947                         memset(&data, 0, sizeof(data));
948                         data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
949                         data.WaveDeviceId = wid;
950                         data.DeviceId = capture_guids[wid];
951
952                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
953                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
954                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
955
956                         data.Description = wDescription;
957                         data.Module = wModule;
958                         data.Interface = wInterface;
959                         TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
960                         (ppd->Callback)(&data, ppd->Context);
961                     }
962                 }
963
964                 return S_OK;
965             }
966         }
967     } else {
968         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
969     }
970
971     if (pcbReturned) {
972         *pcbReturned = 0;
973         FIXME("*pcbReturned=%ld\n", *pcbReturned);
974     }
975
976     return E_PROP_ID_UNSUPPORTED;
977 }
978
979 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
980     LPKSPROPERTYSET iface,
981     REFGUID guidPropSet,
982     ULONG dwPropID,
983     LPVOID pInstanceData,
984     ULONG cbInstanceData,
985     LPVOID pPropData,
986     ULONG cbPropData,
987     PULONG pcbReturned
988 ) {
989     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
990     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
991         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
992
993     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
994         switch (dwPropID) {
995         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
996             return DSPROPERTY_WaveDeviceMappingA(guidPropSet,pPropData,cbPropData,pcbReturned);
997         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
998             return DSPROPERTY_Description1(guidPropSet,pPropData,cbPropData,pcbReturned);
999         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1000             return DSPROPERTY_Enumerate1(guidPropSet,pPropData,cbPropData,pcbReturned);
1001         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1002             return DSPROPERTY_WaveDeviceMappingW(guidPropSet,pPropData,cbPropData,pcbReturned);
1003         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1004             return DSPROPERTY_DescriptionA(guidPropSet,pPropData,cbPropData,pcbReturned);
1005         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1006             return DSPROPERTY_DescriptionW(guidPropSet,pPropData,cbPropData,pcbReturned);
1007         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1008             return DSPROPERTY_EnumerateA(guidPropSet,pPropData,cbPropData,pcbReturned);
1009         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1010             return DSPROPERTY_EnumerateW(guidPropSet,pPropData,cbPropData,pcbReturned);
1011         default:
1012             FIXME("unsupported ID: %ld\n",dwPropID);
1013             break;
1014         }
1015     } else {
1016         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1017     }
1018
1019     if (pcbReturned) {
1020         *pcbReturned = 0;
1021         FIXME("*pcbReturned=%ld\n", *pcbReturned);
1022     }
1023
1024     return E_PROP_ID_UNSUPPORTED;
1025 }
1026
1027 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
1028     LPKSPROPERTYSET iface,
1029     REFGUID guidPropSet,
1030     ULONG dwPropID,
1031     LPVOID pInstanceData,
1032     ULONG cbInstanceData,
1033     LPVOID pPropData,
1034     ULONG cbPropData )
1035 {
1036     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1037
1038     FIXME("(%p,%s,%ld,%p,%ld,%p,%ld), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
1039     return E_PROP_ID_UNSUPPORTED;
1040 }
1041
1042 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
1043     LPKSPROPERTYSET iface,
1044     REFGUID guidPropSet,
1045     ULONG dwPropID,
1046     PULONG pTypeSupport )
1047 {
1048     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
1049     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
1050
1051     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
1052         switch (dwPropID) {
1053         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
1054             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1055             return S_OK;
1056         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
1057             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1058             return S_OK;
1059         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
1060             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1061             return S_OK;
1062         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
1063             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1064             return S_OK;
1065         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
1066             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1067             return S_OK;
1068         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
1069             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1070             return S_OK;
1071         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
1072             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1073             return S_OK;
1074         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
1075             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
1076             return S_OK;
1077         default:
1078             FIXME("unsupported ID: %ld\n",dwPropID);
1079             break;
1080         }
1081     } else {
1082         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
1083     }
1084
1085     return E_PROP_ID_UNSUPPORTED;
1086 }
1087
1088 static IKsPropertySetVtbl ikspvt = {
1089     IKsPrivatePropertySetImpl_QueryInterface,
1090     IKsPrivatePropertySetImpl_AddRef,
1091     IKsPrivatePropertySetImpl_Release,
1092     IKsPrivatePropertySetImpl_Get,
1093     IKsPrivatePropertySetImpl_Set,
1094     IKsPrivatePropertySetImpl_QuerySupport
1095 };
1096
1097 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
1098     IKsPrivatePropertySetImpl **piks)
1099 {
1100     IKsPrivatePropertySetImpl *iks;
1101
1102     iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
1103     iks->ref = 0;
1104     iks->lpVtbl = &ikspvt;
1105
1106     *piks = iks;
1107     return S_OK;
1108 }