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