~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/dsound/propset.c

Version: ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*                      DirectSound
  2  *
  3  * Copyright 1998 Marcus Meissner
  4  * Copyright 1998 Rob Riggs
  5  * Copyright 2000-2002 TransGaming Technologies, Inc.
  6  *
  7  * This library is free software; you can redistribute it and/or
  8  * modify it under the terms of the GNU Lesser General Public
  9  * License as published by the Free Software Foundation; either
 10  * version 2.1 of the License, or (at your option) any later version.
 11  *
 12  * This library is distributed in the hope that it will be useful,
 13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15  * Lesser General Public License for more details.
 16  *
 17  * You should have received a copy of the GNU Lesser General Public
 18  * License along with this library; if not, write to the Free Software
 19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 20  */
 21 
 22 #define COBJMACROS
 23 #include <stdarg.h>
 24 
 25 #include "windef.h"
 26 #include "winbase.h"
 27 #include "winuser.h"
 28 #include "mmsystem.h"
 29 #include "winternl.h"
 30 #include "winnls.h"
 31 #include "vfwmsgs.h"
 32 #include "mmddk.h"
 33 #include "wine/debug.h"
 34 #include "dsound.h"
 35 #include "dsdriver.h"
 36 #include "dsound_private.h"
 37 #include "dsconf.h"
 38 
 39 #ifdef NONAMELESSSTRUCT
 40 # define S(x) (x).s
 41 #else
 42 # define S(x) (x)
 43 #endif
 44 
 45 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
 46 
 47 
 48 /*******************************************************************************
 49  *              IKsBufferPropertySet
 50  */
 51 
 52 /* IUnknown methods */
 53 static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(
 54     LPKSPROPERTYSET iface,
 55     REFIID riid,
 56     LPVOID *ppobj )
 57 {
 58     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
 59     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
 60 
 61     return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
 62 }
 63 
 64 static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
 65 {
 66     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
 67     ULONG ref = InterlockedIncrement(&(This->ref));
 68     TRACE("(%p) ref was %d\n", This, ref - 1);
 69     return ref;
 70 }
 71 
 72 static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
 73 {
 74     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
 75     ULONG ref = InterlockedDecrement(&(This->ref));
 76     TRACE("(%p) ref was %d\n", This, ref + 1);
 77 
 78     if (!ref) {
 79         This->dsb->iks = 0;
 80         IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
 81         HeapFree(GetProcessHeap(), 0, This);
 82         TRACE("(%p) released\n", This);
 83     }
 84     return ref;
 85 }
 86 
 87 static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
 88     LPKSPROPERTYSET iface,
 89     REFGUID guidPropSet,
 90     ULONG dwPropID,
 91     LPVOID pInstanceData,
 92     ULONG cbInstanceData,
 93     LPVOID pPropData,
 94     ULONG cbPropData,
 95     PULONG pcbReturned )
 96 {
 97     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
 98     PIDSDRIVERPROPERTYSET ps;
 99     TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
100         This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);
101 
102     if (This->dsb->hwbuf) {
103         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
104 
105         if (ps) {
106             DSPROPERTY prop;
107             HRESULT hres;
108 
109             S(prop).Set = *guidPropSet;
110             S(prop).Id = dwPropID;
111             S(prop).Flags = 0;  /* unused */
112             S(prop).InstanceId = (ULONG)This->dsb->device;
113 
114             hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
115 
116             IDsDriverPropertySet_Release(ps);
117 
118             return hres;
119         }
120     }
121 
122     return E_PROP_ID_UNSUPPORTED;
123 }
124 
125 static HRESULT WINAPI IKsBufferPropertySetImpl_Set(
126     LPKSPROPERTYSET iface,
127     REFGUID guidPropSet,
128     ULONG dwPropID,
129     LPVOID pInstanceData,
130     ULONG cbInstanceData,
131     LPVOID pPropData,
132     ULONG cbPropData )
133 {
134     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
135     PIDSDRIVERPROPERTYSET ps;
136     TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
137 
138     if (This->dsb->hwbuf) {
139         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
140 
141         if (ps) {
142             DSPROPERTY prop;
143             HRESULT hres;
144 
145             S(prop).Set = *guidPropSet;
146             S(prop).Id = dwPropID;
147             S(prop).Flags = 0;  /* unused */
148             S(prop).InstanceId = (ULONG)This->dsb->device;
149             hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);
150 
151             IDsDriverPropertySet_Release(ps);
152 
153             return hres;
154         }
155     }
156 
157     return E_PROP_ID_UNSUPPORTED;
158 }
159 
160 static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(
161     LPKSPROPERTYSET iface,
162     REFGUID guidPropSet,
163     ULONG dwPropID,
164     PULONG pTypeSupport )
165 {
166     IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
167     PIDSDRIVERPROPERTYSET ps;
168     TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);
169 
170     if (This->dsb->hwbuf) {
171         IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);
172 
173         if (ps) {
174             HRESULT hres;
175 
176             hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);
177 
178             IDsDriverPropertySet_Release(ps);
179 
180             return hres;
181         }
182     }
183 
184     return E_PROP_ID_UNSUPPORTED;
185 }
186 
187 static const IKsPropertySetVtbl iksbvt = {
188     IKsBufferPropertySetImpl_QueryInterface,
189     IKsBufferPropertySetImpl_AddRef,
190     IKsBufferPropertySetImpl_Release,
191     IKsBufferPropertySetImpl_Get,
192     IKsBufferPropertySetImpl_Set,
193     IKsBufferPropertySetImpl_QuerySupport
194 };
195 
196 HRESULT IKsBufferPropertySetImpl_Create(
197     IDirectSoundBufferImpl *dsb,
198     IKsBufferPropertySetImpl **piks)
199 {
200     IKsBufferPropertySetImpl *iks;
201     TRACE("(%p,%p)\n",dsb,piks);
202     *piks = NULL;
203 
204     iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
205     if (iks == 0) {
206         WARN("out of memory\n");
207         *piks = NULL;
208         return DSERR_OUTOFMEMORY;
209     }
210 
211     iks->ref = 0;
212     iks->dsb = dsb;
213     dsb->iks = iks;
214     iks->lpVtbl = &iksbvt;
215 
216     IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);
217 
218     *piks = iks;
219     return S_OK;
220 }
221 
222 HRESULT IKsBufferPropertySetImpl_Destroy(
223     IKsBufferPropertySetImpl *piks)
224 {
225     TRACE("(%p)\n",piks);
226 
227     while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);
228 
229     return S_OK;
230 }
231 
232 /*******************************************************************************
233  *              IKsPrivatePropertySet
234  */
235 
236 /* IUnknown methods */
237 static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
238     LPKSPROPERTYSET iface,
239     REFIID riid,
240     LPVOID *ppobj )
241 {
242     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
243     TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
244 
245     if (IsEqualIID(riid, &IID_IUnknown) ||
246         IsEqualIID(riid, &IID_IKsPropertySet)) {
247         *ppobj = iface;
248         IUnknown_AddRef(iface);
249         return S_OK;
250     }
251     *ppobj = NULL;
252     return E_NOINTERFACE;
253 }
254 
255 static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
256 {
257     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
258     ULONG ref = InterlockedIncrement(&(This->ref));
259     TRACE("(%p) ref was %d\n", This, ref - 1);
260     return ref;
261 }
262 
263 static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
264 {
265     IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
266     ULONG ref = InterlockedDecrement(&(This->ref));
267     TRACE("(%p) ref was %d\n", This, ref + 1);
268 
269     if (!ref) {
270         HeapFree(GetProcessHeap(), 0, This);
271         TRACE("(%p) released\n", This);
272     }
273     return ref;
274 }
275 
276 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
277     LPVOID pPropData,
278     ULONG cbPropData,
279     PULONG pcbReturned )
280 {
281     HRESULT hr = DSERR_INVALIDPARAM;
282     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
283     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
284           pPropData,cbPropData,pcbReturned);
285 
286     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA) pPropData;
287 
288     if (!ppd) {
289         WARN("invalid parameter: pPropData\n");
290         return DSERR_INVALIDPARAM;
291     }
292 
293     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
294         ULONG wod;
295         unsigned int wodn;
296         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
297         wodn = waveOutGetNumDevs();
298         for (wod = 0; wod < wodn; wod++) {
299             WAVEOUTCAPSA capsA;
300             MMRESULT res;
301             res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA));
302             if (res == MMSYSERR_NOERROR) {
303                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
304                     ppd->DeviceId = DSOUND_renderer_guids[wod];
305                     hr = DS_OK;
306                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
307                           ppd->DeviceName);
308                     break;
309                 }
310             }
311         }
312     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
313         ULONG wid;
314         unsigned int widn;
315         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
316         widn = waveInGetNumDevs();
317         for (wid = 0; wid < widn; wid++) {
318             WAVEINCAPSA capsA;
319             MMRESULT res;
320             res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA));
321             if (res == MMSYSERR_NOERROR) {
322                 if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
323                     ppd->DeviceId = DSOUND_capture_guids[wid];
324                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
325                           ppd->DeviceName);
326                     hr = DS_OK;
327                     break;
328                 }
329             }
330         }
331     }
332 
333     if (pcbReturned)
334         *pcbReturned = cbPropData;
335 
336     return hr;
337 }
338 
339 static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
340     LPVOID pPropData,
341     ULONG cbPropData,
342     PULONG pcbReturned )
343 {
344     HRESULT hr = DSERR_INVALIDPARAM;
345     PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
346     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
347           pPropData,cbPropData,pcbReturned);
348 
349     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA) pPropData;
350 
351     if (!ppd) {
352         WARN("invalid parameter: pPropData\n");
353         return DSERR_INVALIDPARAM;
354     }
355 
356     if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
357         ULONG wod;
358         unsigned int wodn;
359         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
360         wodn = waveOutGetNumDevs();
361         for (wod = 0; wod < wodn; wod++) {
362             WAVEOUTCAPSW capsW;
363             MMRESULT res;
364             res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
365             if (res == MMSYSERR_NOERROR) {
366                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
367                     ppd->DeviceId = DSOUND_renderer_guids[wod];
368                     hr = DS_OK;
369                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
370                           debugstr_w(ppd->DeviceName));
371                     break;
372                 }
373             }
374         }
375     } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
376         ULONG wid;
377         unsigned int widn;
378         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
379         widn = waveInGetNumDevs();
380         for (wid = 0; wid < widn; wid++) {
381             WAVEINCAPSW capsW;
382             MMRESULT res;
383             res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
384             if (res == MMSYSERR_NOERROR) {
385                 if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
386                     ppd->DeviceId = DSOUND_capture_guids[wid];
387                     hr = DS_OK;
388                     TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
389                           debugstr_w(ppd->DeviceName));
390                     break;
391                 }
392             }
393         }
394     }
395 
396     if (pcbReturned)
397         *pcbReturned = cbPropData;
398 
399     return hr;
400 }
401 
402 static HRESULT WINAPI DSPROPERTY_Description1(
403     LPVOID pPropData,
404     ULONG cbPropData,
405     PULONG pcbReturned )
406 {
407     HRESULT err;
408     GUID guid, dev_guid;
409     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd;
410     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
411         pPropData,cbPropData,pcbReturned);
412 
413     ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData;
414 
415     if (!ppd) {
416         WARN("invalid parameter: pPropData\n");
417         return DSERR_INVALIDPARAM;
418     }
419 
420     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
421     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
422         /* default device of type specified by ppd->DataFlow */
423         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
424             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
425         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
426             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
427         } else {
428             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
429         }
430         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
431               pPropData,cbPropData,pcbReturned);
432         return E_PROP_ID_UNSUPPORTED;
433     }
434 
435     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
436     GetDeviceID(&ppd->DeviceId, &dev_guid);
437 
438     if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
439          IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
440         ULONG wod;
441         unsigned int wodn;
442         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
443         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
444         wodn = waveOutGetNumDevs();
445         for (wod = 0; wod < wodn; wod++) {
446             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
447                 DSDRIVERDESC desc;
448                 ppd->WaveDeviceId = wod;
449                 ppd->Devnode = wod;
450                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
451                 if (err == DS_OK) {
452                     PIDSDRIVER drv = NULL;
453                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
454                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
455                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
456                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
457                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
458                     if (err == DS_OK && drv)
459                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
460                     else
461                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
462                     break;
463                 } else {
464                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
465                     return E_PROP_ID_UNSUPPORTED;
466                 }
467             }
468         }
469     } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
470                 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
471         ULONG wid;
472         unsigned int widn;
473         TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
474         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
475         widn = waveInGetNumDevs();
476         for (wid = 0; wid < widn; wid++) {
477             if (IsEqualGUID( &dev_guid, &guid) ) {
478                 DSDRIVERDESC desc;
479                 ppd->WaveDeviceId = wid;
480                 ppd->Devnode = wid;
481                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
482                 if (err == DS_OK) {
483                     PIDSCDRIVER drv;
484                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
485                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
486                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
487                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
488                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
489                     if (err == DS_OK && drv)
490                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
491                     else
492                         WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
493                     break;
494                 } else {
495                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
496                     return E_PROP_ID_UNSUPPORTED;
497                 }
498             }
499         }
500     } else {
501         BOOL found = FALSE;
502         ULONG wod;
503         unsigned int wodn;
504         /* given specific device so try the render devices first */
505         wodn = waveOutGetNumDevs();
506         for (wod = 0; wod < wodn; wod++) {
507             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
508                 DSDRIVERDESC desc;
509                 TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
510                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
511                 ppd->WaveDeviceId = wod;
512                 ppd->Devnode = wod;
513                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
514                 if (err == DS_OK) {
515                     PIDSDRIVER drv = NULL;
516                     lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
517                     lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
518                     MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
519                     MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
520                     err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
521                     if (err == DS_OK && drv)
522                         ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
523                     else
524                         WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
525                     found = TRUE;
526                     break;
527                 } else {
528                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
529                     return E_PROP_ID_UNSUPPORTED;
530                 }
531             }
532         }
533 
534         if (found == FALSE) {
535             ULONG wid;
536             unsigned int widn;
537             /* given specific device so try the capture devices next */
538             widn = waveInGetNumDevs();
539             for (wid = 0; wid < widn; wid++) {
540                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
541                     DSDRIVERDESC desc;
542                     TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
543                     ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
544                     ppd->WaveDeviceId = wid;
545                     ppd->Devnode = wid;
546                     err = mmErr(waveInMessage((HWAVEIN)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
547                     if (err == DS_OK) {
548                         PIDSDRIVER drv = NULL;
549                         lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
550                         lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
551                         MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
552                         MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
553                         err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
554                         if (err == DS_OK && drv)
555                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
556                         else
557                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
558                         found = TRUE;
559                         break;
560                     } else {
561                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
562                         return E_PROP_ID_UNSUPPORTED;
563                     }
564                 }
565             }
566 
567             if (found == FALSE) {
568                 WARN("device not found\n");
569                 return E_PROP_ID_UNSUPPORTED;
570             }
571         }
572     }
573 
574     if (pcbReturned) {
575         *pcbReturned = cbPropData;
576         TRACE("*pcbReturned=%d\n", *pcbReturned);
577     }
578 
579     return S_OK;
580 }
581 
582 static HRESULT WINAPI DSPROPERTY_DescriptionA(
583     LPVOID pPropData,
584     ULONG cbPropData,
585     PULONG pcbReturned )
586 {
587     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
588     HRESULT err;
589     GUID dev_guid;
590     TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
591           pPropData,cbPropData,pcbReturned);
592 
593     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
594     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
595         /* default device of type specified by ppd->DataFlow */
596         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
597             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
598         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
599             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
600         } else {
601             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
602         }
603         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
604               pPropData,cbPropData,pcbReturned);
605         return E_PROP_ID_UNSUPPORTED;
606     }
607 
608     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
609     GetDeviceID(&ppd->DeviceId, &dev_guid);
610 
611     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
612          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
613         ULONG wod;
614         unsigned int wodn;
615         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
616             TRACE("DSDEVID_DefaultPlayback\n");
617         else
618             TRACE("DSDEVID_DefaultVoicePlayback\n");
619         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
620         wodn = waveOutGetNumDevs();
621         for (wod = 0; wod < wodn; wod++) {
622             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
623                 DSDRIVERDESC desc;
624                 ppd->WaveDeviceId = wod;
625                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
626                 if (err == DS_OK) {
627                     PIDSDRIVER drv = NULL;
628                     /* FIXME: this is a memory leak */
629                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
630                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
631                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
632 
633                     if (szDescription && szModule && szInterface) {
634                         strcpy(szDescription, desc.szDesc);
635                         strcpy(szModule, desc.szDrvname);
636                         strcpy(szInterface, "Interface");
637 
638                         ppd->Description = szDescription;
639                         ppd->Module = szModule;
640                         ppd->Interface = szInterface;
641                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
642                         if (err == DS_OK && drv)
643                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
644                         else
645                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
646                         break;
647                     } else {
648                         WARN("no memory\n");
649                         HeapFree(GetProcessHeap(), 0, szDescription);
650                         HeapFree(GetProcessHeap(), 0, szModule);
651                         HeapFree(GetProcessHeap(), 0, szInterface);
652                         return E_OUTOFMEMORY;
653                     }
654                 } else {
655                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
656                     return E_PROP_ID_UNSUPPORTED;
657                 }
658             }
659         }
660     } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
661                IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
662         ULONG wid;
663         unsigned int widn;
664         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) )
665             TRACE("DSDEVID_DefaultCapture\n");
666         else
667             TRACE("DSDEVID_DefaultVoiceCapture\n");
668         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
669         widn = waveInGetNumDevs();
670         for (wid = 0; wid < widn; wid++) {
671             if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
672                 DSDRIVERDESC desc;
673                 ppd->WaveDeviceId = wid;
674                 err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
675                 if (err == DS_OK) {
676                     PIDSCDRIVER drv;
677                     /* FIXME: this is a memory leak */
678                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
679                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
680                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
681 
682                     if (szDescription && szModule && szInterface) {
683                         strcpy(szDescription, desc.szDesc);
684                         strcpy(szModule, desc.szDrvname);
685                         strcpy(szInterface, "Interface");
686 
687                         ppd->Description = szDescription;
688                         ppd->Module = szModule;
689                         ppd->Interface = szInterface;
690                         err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
691                         if (err == DS_OK && drv)
692                             ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
693                         else
694                             WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
695                         break;
696                     } else {
697                         WARN("no memory\n");
698                         HeapFree(GetProcessHeap(), 0, szDescription);
699                         HeapFree(GetProcessHeap(), 0, szModule);
700                         HeapFree(GetProcessHeap(), 0, szInterface);
701                         return E_OUTOFMEMORY;
702                     }
703                 } else {
704                     WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
705                     return E_PROP_ID_UNSUPPORTED;
706                 }
707             }
708         }
709     } else {
710         BOOL found = FALSE;
711         ULONG wod;
712         unsigned int wodn;
713         /* given specific device so try the render devices first */
714         TRACE("Checking renderer devices\n");
715         wodn = waveOutGetNumDevs();
716         for (wod = 0; wod < wodn; wod++) {
717             if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
718                 DSDRIVERDESC desc;
719                 TRACE("DSOUND_renderer_guids[%d]\n", wod);
720                 ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
721                 ppd->WaveDeviceId = wod;
722                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
723                 if (err == DS_OK) {
724                     PIDSDRIVER drv = NULL;
725                     /* FIXME: this is a memory leak */
726                     CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
727                     CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
728                     CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
729 
730                     if (szDescription && szModule && szInterface) {
731                         strcpy(szDescription, desc.szDesc);
732                         strcpy(szModule, desc.szDrvname);
733                         strcpy(szInterface, "Interface");
734 
735                         ppd->Description = szDescription;
736                         ppd->Module = szModule;
737                         ppd->Interface = szInterface;
738                         err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
739                         if (err == DS_OK && drv)
740                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
741                         else
742                             WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
743                         found = TRUE;
744                         break;
745                     } else {
746                         WARN("no memory\n");
747                         HeapFree(GetProcessHeap(), 0, szDescription);
748                         HeapFree(GetProcessHeap(), 0, szModule);
749                         HeapFree(GetProcessHeap(), 0, szInterface);
750                         return E_OUTOFMEMORY;
751                     }
752                 } else {
753                     WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
754                     return E_PROP_ID_UNSUPPORTED;
755                 }
756             }
757         }
758 
759         if (found == FALSE) {
760             ULONG wid;
761             unsigned int widn;
762             TRACE("Checking capture devices\n");
763             ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
764             widn = waveInGetNumDevs();
765             for (wid = 0; wid < widn; wid++) {
766                 if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
767                     DSDRIVERDESC desc;
768                     TRACE("DSOUND_capture_guids[%d]\n", wid);
769                     ppd->WaveDeviceId = wid;
770                     err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
771                     if (err == DS_OK) {
772                         PIDSCDRIVER drv;
773                         /* FIXME: this is a memory leak */
774                         CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
775                         CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
776                         CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);
777 
778                         if (szDescription && szModule && szInterface) {
779                             strcpy(szDescription, desc.szDesc);
780                             strcpy(szModule, desc.szDrvname);
781                             strcpy(szInterface, "Interface");
782 
783                             ppd->Description = szDescription;
784                             ppd->Module = szModule;
785                             ppd->Interface = szInterface;
786                             err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
787                             if (err == DS_OK && drv)
788                                 ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
789                             else
790                                 WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
791                             found = TRUE;
792                             break;
793                         } else {
794                             WARN("no memory\n");
795                             HeapFree(GetProcessHeap(), 0, szDescription);
796                             HeapFree(GetProcessHeap(), 0, szModule);
797                             HeapFree(GetProcessHeap(), 0, szInterface);
798                             return E_OUTOFMEMORY;
799                         }
800                     } else {
801                         WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
802                         return E_PROP_ID_UNSUPPORTED;
803                     }
804                 }
805             }
806         }
807 
808         if (found == FALSE) {
809             WARN("device not found\n");
810             return E_PROP_ID_UNSUPPORTED;
811         }
812     }
813 
814     if (pcbReturned) {
815         *pcbReturned = cbPropData;
816         TRACE("*pcbReturned=%d\n", *pcbReturned);
817     }
818 
819     return S_OK;
820 }
821 
822 static HRESULT WINAPI DSPROPERTY_DescriptionW(
823     LPVOID pPropData,
824     ULONG cbPropData,
825     PULONG pcbReturned )
826 {
827     PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
828     HRESULT err;
829     GUID dev_guid;
830     TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
831           pPropData,cbPropData,pcbReturned);
832 
833     TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
834     if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
835         /* default device of type specified by ppd->DataFlow */
836         if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
837             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
838         } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
839             TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
840         } else {
841             TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
842         }
843         FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
844               pPropData,cbPropData,pcbReturned);
845         return E_PROP_ID_UNSUPPORTED;
846     }
847 
848     ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
849     GetDeviceID(&ppd->DeviceId, &dev_guid);
850 
851     if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
852          IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
853         ULONG wod;
854         unsigned int wodn;
855         if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
856             TRACE("DSDEVID_DefaultPlayback\n");
857         else
858             TRACE("DSDEVID_DefaultVoicePlayback\n");
859         ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
860         wodn = waveOutGetNumDevs();
861         for (wod = 0; wod < wodn; wod++) {
862             if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
863                 DSDRIVERDESC desc;
864                 TRACE("DSOUND_renderer_guids[%d]\n", wod);
865                 ppd->WaveDeviceId = wod;
866                 err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
867                 if (err == DS_OK) {
868                     PIDSDRIVER drv = NULL;
869                     /* FIXME: this is a memory leak */
870                     WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
871                     WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
872                     WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);