Fixed definitions of TTTOOLINFOA/W_V1_SIZE and
[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         FIXME("DeviceId=Unknown\n");
435         return E_PROP_ID_UNSUPPORTED;
436     }
437
438     if (pcbReturned) {
439         *pcbReturned = cbPropData; 
440         TRACE("*pcbReturned=%ld\n", *pcbReturned);
441     }
442
443     return S_OK;
444 }
445
446 static HRESULT WINAPI DSPROPERTY_DescriptionA(
447     REFGUID guidPropSet,
448     LPVOID pPropData,
449     ULONG cbPropData,
450     PULONG pcbReturned )
451 {
452     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
453     HRESULT err;
454     GUID guid, dev_guid;
455     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
456         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
457
458     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
459     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
460         /* default device of type specified by ppd->DataFlow */
461         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
462             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
463         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
464             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
465         } else {
466             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
467         }
468         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
469             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
470         return E_PROP_ID_UNSUPPORTED;
471     }
472
473     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
474     GetDeviceID(&ppd->DeviceId, &dev_guid);
475
476     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
477          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
478         ULONG wod;
479         int wodn;
480         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
481         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
482         wodn = waveOutGetNumDevs();
483         for (wod = 0; wod < wodn; wod++) {
484             err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
485             if (err == DS_OK) {
486                 if (IsEqualGUID( &dev_guid, &guid) ) {
487                     DSDRIVERDESC desc;
488                     ppd->WaveDeviceId = wod;
489                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
490                     if (err == DS_OK) {
491                         PIDSDRIVER drv = NULL;
492                         /* FIXME: this is a memory leak */
493                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
494                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
495                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
496
497                         strcpy(szDescription, desc.szDesc);
498                         strcpy(szModule, desc.szDrvName);
499                         strcpy(szInterface, "Interface");
500
501                         ppd->Description = szDescription;
502                         ppd->Module = szModule;
503                         ppd->Interface = szInterface;
504                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
505                         if (err == DS_OK && drv)
506                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
507                         break;
508                     } else {
509                         WARN("waveOutMessage failed\n");
510                         return E_PROP_ID_UNSUPPORTED;
511                     }
512                 }
513             } else {
514                 WARN("waveOutMessage failed\n");
515                 return E_PROP_ID_UNSUPPORTED;
516             }
517         }
518     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
519                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
520         ULONG wid;
521         int widn;
522         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
523         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
524         widn = waveInGetNumDevs();
525         for (wid = 0; wid < widn; wid++) {
526             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
527             if (err == DS_OK) {
528                 if (IsEqualGUID( &dev_guid, &guid) ) {
529                     DSDRIVERDESC desc;
530                     ppd->WaveDeviceId = wid;
531                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
532                     if (err == DS_OK) {
533                         PIDSCDRIVER drv;
534                         /* FIXME: this is a memory leak */
535                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
536                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvName) + 1);
537                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
538
539                         strcpy(szDescription, desc.szDesc);
540                         strcpy(szModule, desc.szDrvName);
541                         strcpy(szInterface, "Interface");
542
543                         ppd->Description = szDescription;
544                         ppd->Module = szModule;
545                         ppd->Interface = szInterface;
546                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
547                         if (err == DS_OK && drv)
548                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
549                         break;
550                     } else {
551                         WARN("waveInMessage failed\n");
552                         return E_PROP_ID_UNSUPPORTED;
553                     }
554                     break;
555                 }
556             } else {
557                 WARN("waveOutMessage failed\n");
558                 return E_PROP_ID_UNSUPPORTED;
559             }
560         }
561     }
562
563     if (pcbReturned) {
564         *pcbReturned = cbPropData;
565         TRACE("*pcbReturned=%ld\n", *pcbReturned);
566     }
567
568     return S_OK;
569 }
570
571 static HRESULT WINAPI DSPROPERTY_DescriptionW(
572     REFGUID guidPropSet,
573     LPVOID pPropData,
574     ULONG cbPropData,
575     PULONG pcbReturned )
576 {
577     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
578     HRESULT err;
579     GUID guid, dev_guid;
580     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
581         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
582
583     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
584     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
585         /* default device of type specified by ppd->DataFlow */
586         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
587             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
588         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
589             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
590         } else {
591             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
592         }
593         FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p) GUID_NULL not implemented!\n",
594             debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
595         return E_PROP_ID_UNSUPPORTED;
596     }
597
598     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
599     GetDeviceID(&ppd->DeviceId, &dev_guid);
600
601     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) || 
602          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
603         ULONG wod;
604         int wodn;
605         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
606         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
607         wodn = waveOutGetNumDevs();
608         for (wod = 0; wod < wodn; wod++) {
609             err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
610             if (err == DS_OK) {
611                 if (IsEqualGUID( &dev_guid, &guid) ) {
612                     DSDRIVERDESC desc;
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                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
619                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
620                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
621
622                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
623                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
624                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
625
626                         ppd->Description = wDescription;
627                         ppd->Module = wModule;
628                         ppd->Interface = wInterface;
629                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0));
630                         if (err == DS_OK && drv)
631                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
632                             break;
633                     } else {
634                         WARN("waveOutMessage failed\n");
635                         return E_PROP_ID_UNSUPPORTED;
636                     }
637                 }
638             } else {
639                 WARN("waveOutMessage failed\n");
640                 return E_PROP_ID_UNSUPPORTED;
641             }
642         }
643     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
644                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
645         ULONG wid;
646         int widn;
647         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
648         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
649         widn = waveInGetNumDevs();
650         for (wid = 0; wid < widn; wid++) {
651             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
652             if (err == DS_OK) {
653                 if (IsEqualGUID( &dev_guid, &guid) ) {
654                     DSDRIVERDESC desc;
655                     ppd->WaveDeviceId = wid;
656                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&(desc),0));
657                     if (err == DS_OK) {
658                         PIDSCDRIVER drv;
659                         /* FIXME: this is a memory leak */
660                         WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
661                         WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
662                         WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
663
664                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
665                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
666                         MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
667
668                         ppd->Description = wDescription;
669                         ppd->Module = wModule;
670                         ppd->Interface = wInterface;
671                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD)&drv,0));
672                         if (err == DS_OK && drv)
673                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
674                         break;
675                     } else {
676                         WARN("waveInMessage failed\n");
677                         return E_PROP_ID_UNSUPPORTED;
678                     }
679                     break;
680                 }
681             } else {
682                 WARN("waveInMessage failed\n");
683                 return E_PROP_ID_UNSUPPORTED;
684             }
685         }
686     } else {
687         FIXME("DeviceId=Unknown\n");
688         return E_PROP_ID_UNSUPPORTED;
689     }
690
691     if (pcbReturned) {
692         *pcbReturned = cbPropData; 
693         TRACE("*pcbReturned=%ld\n", *pcbReturned);
694     }
695
696     return S_OK;
697 }
698
699 static HRESULT WINAPI DSPROPERTY_Enumerate1(
700     REFGUID guidPropSet,
701     LPVOID pPropData,
702     ULONG cbPropData,
703     PULONG pcbReturned )
704 {
705     FIXME("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
706         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
707     return E_PROP_ID_UNSUPPORTED;
708 }
709
710 static HRESULT WINAPI DSPROPERTY_EnumerateA(
711     REFGUID guidPropSet,
712     LPVOID pPropData,
713     ULONG cbPropData,
714     PULONG pcbReturned )
715 {
716     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
717     HRESULT err;
718     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
719         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
720
721     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
722         if (ppd) {
723             if (ppd->Callback) {
724                 unsigned devs, wod, wid;
725                 DSDRIVERDESC desc;
726                 GUID guid;
727                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;
728
729                 devs = waveOutGetNumDevs();
730                 for (wod = 0; wod < devs; ++wod) {
731                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
732                     if (err == DS_OK) {
733                         err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
734                         if (err == DS_OK) {
735                             memset(&data, 0, sizeof(data));
736                             data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
737                             data.WaveDeviceId = wod;
738                             data.DeviceId = guid;
739                             data.Description = desc.szDesc;
740                             data.Module = desc.szDrvName;
741                             data.Interface = "Interface";
742                             TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
743                             (ppd->Callback)(&data, ppd->Context);
744                         }
745                     }
746                 }
747
748                 devs = waveInGetNumDevs();
749                 for (wid = 0; wid < devs; ++wid) {
750                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
751                     if (err == DS_OK) {
752                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
753                         if (err == DS_OK) {
754                             memset(&data, 0, sizeof(data));
755                             data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
756                             data.WaveDeviceId = wid;
757                             data.DeviceId = guid;
758                             data.Description = desc.szDesc;
759                             data.Module = desc.szDrvName;
760                             data.Interface = "Interface";
761                             TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
762                             (ppd->Callback)(&data, ppd->Context);
763                         }
764                     }
765                 }
766
767                 return S_OK;
768             }
769         }
770     } else {
771         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
772     }
773
774     if (pcbReturned) {
775         *pcbReturned = 0; 
776         FIXME("*pcbReturned=%ld\n", *pcbReturned);
777     }
778     
779     return E_PROP_ID_UNSUPPORTED;
780 }
781
782 static HRESULT WINAPI DSPROPERTY_EnumerateW(
783     REFGUID guidPropSet,
784     LPVOID pPropData,
785     ULONG cbPropData,
786     PULONG pcbReturned )
787 {
788     PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
789     HRESULT err;
790     TRACE("(guidPropSet=%s,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
791         debugstr_guid(guidPropSet),pPropData,cbPropData,pcbReturned);
792
793     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
794         if (ppd) {
795             if (ppd->Callback) {
796                 unsigned devs, wod, wid;
797                 DSDRIVERDESC desc;
798                 GUID guid;
799                 DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
800
801                 devs = waveOutGetNumDevs();
802                 for (wod = 0; wod < devs; ++wod) {
803                     err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
804                     if (err == DS_OK) {
805                         err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
806                         if (err == DS_OK) {
807                             /* FIXME: this is a memory leak */
808                             WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
809                             WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
810                             WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
811                             
812                             memset(&data, 0, sizeof(data));
813                             data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
814                             data.WaveDeviceId = wod;
815                             data.DeviceId = guid;
816
817                             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
818                             MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
819                             MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
820
821                             data.Description = wDescription;
822                             data.Module = wModule;
823                             data.Interface = wInterface;
824                             TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
825                             (ppd->Callback)(&data, ppd->Context);
826                         }
827                     }
828                 }
829
830                 devs = waveInGetNumDevs();
831                 for (wid = 0; wid < devs; ++wid) {
832                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
833                     if (err == DS_OK) {
834                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
835                         if (err == DS_OK) {
836                             /* FIXME: this is a memory leak */
837                             WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
838                             WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
839                             WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);
840                             
841                             memset(&data, 0, sizeof(data));
842                             data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
843                             data.WaveDeviceId = wid;
844                             data.DeviceId = guid;
845
846                             MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
847                             MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1, wModule, 0x100 );
848                             MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );
849
850                             data.Description = wDescription;
851                             data.Module = wModule;
852                             data.Interface = wInterface;
853                             TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
854                             (ppd->Callback)(&data, ppd->Context);
855                         }
856                     }
857                 }
858
859                 return S_OK;
860             }
861         }
862     } else {
863         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
864     }
865
866     if (pcbReturned) {
867         *pcbReturned = 0; 
868         FIXME("*pcbReturned=%ld\n", *pcbReturned);
869     }
870     
871     return E_PROP_ID_UNSUPPORTED;
872 }
873
874 static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
875     LPKSPROPERTYSET iface,
876     REFGUID guidPropSet,
877     ULONG dwPropID,
878     LPVOID pInstanceData,
879     ULONG cbInstanceData,
880     LPVOID pPropData,
881     ULONG cbPropData,
882     PULONG pcbReturned
883 ) {
884     ICOM_THIS(IKsPrivatePropertySetImpl,iface);
885     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%ld,pInstanceData=%p,cbInstanceData=%ld,pPropData=%p,cbPropData=%ld,pcbReturned=%p)\n",
886         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
887
888     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
889         switch (dwPropID) {
890         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
891             return DSPROPERTY_WaveDeviceMappingA(guidPropSet,pPropData,cbPropData,pcbReturned);
892         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
893             return DSPROPERTY_Description1(guidPropSet,pPropData,cbPropData,pcbReturned);
894         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
895             return DSPROPERTY_Enumerate1(guidPropSet,pPropData,cbPropData,pcbReturned);
896         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
897             return DSPROPERTY_WaveDeviceMappingW(guidPropSet,pPropData,cbPropData,pcbReturned);
898         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
899             return DSPROPERTY_DescriptionA(guidPropSet,pPropData,cbPropData,pcbReturned);
900         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
901             return DSPROPERTY_DescriptionW(guidPropSet,pPropData,cbPropData,pcbReturned);
902         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
903             return DSPROPERTY_EnumerateA(guidPropSet,pPropData,cbPropData,pcbReturned);
904         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
905             return DSPROPERTY_EnumerateW(guidPropSet,pPropData,cbPropData,pcbReturned);
906         default:
907             FIXME("unsupported ID: %ld\n",dwPropID);
908             break;
909         }
910     } else {
911         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
912     }
913
914     if (pcbReturned) {
915         *pcbReturned = 0; 
916         FIXME("*pcbReturned=%ld\n", *pcbReturned);
917     }
918
919     return E_PROP_ID_UNSUPPORTED;
920 }
921
922 static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
923     LPKSPROPERTYSET iface,
924     REFGUID guidPropSet,
925     ULONG dwPropID,
926     LPVOID pInstanceData,
927     ULONG cbInstanceData,
928     LPVOID pPropData,
929     ULONG cbPropData )
930 {
931     ICOM_THIS(IKsPrivatePropertySetImpl,iface);
932
933     FIXME("(%p,%s,%ld,%p,%ld,%p,%ld), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
934     return E_PROP_ID_UNSUPPORTED;
935 }
936
937 static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
938     LPKSPROPERTYSET iface,
939     REFGUID guidPropSet,
940     ULONG dwPropID,
941     PULONG pTypeSupport )
942 {
943     ICOM_THIS(IKsPrivatePropertySetImpl,iface);
944     TRACE("(%p,%s,%ld,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
945
946     if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
947         switch (dwPropID) {
948         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
949             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
950             return S_OK;
951         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
952             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
953             return S_OK;
954         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
955             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
956             return S_OK;
957         case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
958             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
959             return S_OK;
960         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
961             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
962             return S_OK;
963         case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
964             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
965             return S_OK;
966         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
967             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
968             return S_OK;
969         case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
970             *pTypeSupport = KSPROPERTY_SUPPORT_GET;
971             return S_OK;
972         default:
973             FIXME("unsupported ID: %ld\n",dwPropID);
974             break;
975         }
976     } else {
977         FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
978     }
979
980     return E_PROP_ID_UNSUPPORTED;
981 }
982
983 static ICOM_VTABLE(IKsPropertySet) ikspvt = {
984     ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
985     IKsPrivatePropertySetImpl_QueryInterface,
986     IKsPrivatePropertySetImpl_AddRef,
987     IKsPrivatePropertySetImpl_Release,
988     IKsPrivatePropertySetImpl_Get,
989     IKsPrivatePropertySetImpl_Set,
990     IKsPrivatePropertySetImpl_QuerySupport
991 };
992
993 HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
994     IKsPrivatePropertySetImpl **piks)
995 {
996     IKsPrivatePropertySetImpl *iks;
997
998     iks = (IKsPrivatePropertySetImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
999     iks->ref = 0;
1000     iks->lpVtbl = &ikspvt;
1001
1002     *piks = iks;
1003     return S_OK;
1004 }