/*  			DirectSound
 *
 * Copyright 1998 Marcus Meissner
 * Copyright 1998 Rob Riggs
 * Copyright 2000-2002 TransGaming Technologies, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define COBJMACROS
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "mmsystem.h"
#include "winternl.h"
#include "winnls.h"
#include "vfwmsgs.h"
#include "mmddk.h"
#include "wine/debug.h"
#include "dsound.h"
#include "dsdriver.h"
#include "dsound_private.h"
#include "dsconf.h"

#ifdef NONAMELESSSTRUCT
# define S(x) (x).s
#else
# define S(x) (x)
#endif

WINE_DEFAULT_DEBUG_CHANNEL(dsound);


/*******************************************************************************
 *              IKsBufferPropertySet
 */

/* IUnknown methods */
static HRESULT WINAPI IKsBufferPropertySetImpl_QueryInterface(
    LPKSPROPERTYSET iface,
    REFIID riid,
    LPVOID *ppobj )
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
}

static ULONG WINAPI IKsBufferPropertySetImpl_AddRef(LPKSPROPERTYSET iface)
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    ULONG ref = InterlockedIncrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref - 1);
    return ref;
}

static ULONG WINAPI IKsBufferPropertySetImpl_Release(LPKSPROPERTYSET iface)
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    ULONG ref = InterlockedDecrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref + 1);

    if (!ref) {
	This->dsb->iks = 0;
	IDirectSoundBuffer_Release((LPDIRECTSOUND3DBUFFER)This->dsb);
	HeapFree(GetProcessHeap(), 0, This);
	TRACE("(%p) released\n", This);
    }
    return ref;
}

static HRESULT WINAPI IKsBufferPropertySetImpl_Get(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    PIDSDRIVERPROPERTYSET ps;
    TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);

    if (This->dsb->hwbuf) {
        IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);

        if (ps) {
	    DSPROPERTY prop;
	    HRESULT hres;

	    S(prop).Set = *guidPropSet;
	    S(prop).Id = dwPropID;
	    S(prop).Flags = 0;	/* unused */
	    S(prop).InstanceId = (ULONG)This->dsb->device;

	    hres = IDsDriverPropertySet_Get(ps, &prop, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);

	    IDsDriverPropertySet_Release(ps);

	    return hres;
        }
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI IKsBufferPropertySetImpl_Set(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData )
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    PIDSDRIVERPROPERTYSET ps;
    TRACE("(%p,%s,%d,%p,%d,%p,%d)\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);

    if (This->dsb->hwbuf) {
        IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);

        if (ps) {
	    DSPROPERTY prop;
	    HRESULT hres;

	    S(prop).Set = *guidPropSet;
	    S(prop).Id = dwPropID;
	    S(prop).Flags = 0;	/* unused */
	    S(prop).InstanceId = (ULONG)This->dsb->device;
	    hres = IDsDriverPropertySet_Set(ps,&prop,pInstanceData,cbInstanceData,pPropData,cbPropData);

	    IDsDriverPropertySet_Release(ps);

	    return hres;
        }
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI IKsBufferPropertySetImpl_QuerySupport(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    PULONG pTypeSupport )
{
    IKsBufferPropertySetImpl *This = (IKsBufferPropertySetImpl *)iface;
    PIDSDRIVERPROPERTYSET ps;
    TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);

    if (This->dsb->hwbuf) {
        IDsDriver_QueryInterface(This->dsb->hwbuf, &IID_IDsDriverPropertySet, (void **)&ps);

        if (ps) {
            HRESULT hres;

            hres = IDsDriverPropertySet_QuerySupport(ps,guidPropSet, dwPropID,pTypeSupport);

            IDsDriverPropertySet_Release(ps);

            return hres;
        }
    }

    return E_PROP_ID_UNSUPPORTED;
}

static const IKsPropertySetVtbl iksbvt = {
    IKsBufferPropertySetImpl_QueryInterface,
    IKsBufferPropertySetImpl_AddRef,
    IKsBufferPropertySetImpl_Release,
    IKsBufferPropertySetImpl_Get,
    IKsBufferPropertySetImpl_Set,
    IKsBufferPropertySetImpl_QuerySupport
};

HRESULT IKsBufferPropertySetImpl_Create(
    IDirectSoundBufferImpl *dsb,
    IKsBufferPropertySetImpl **piks)
{
    IKsBufferPropertySetImpl *iks;
    TRACE("(%p,%p)\n",dsb,piks);
    *piks = NULL;

    iks = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*iks));
    if (iks == 0) {
        WARN("out of memory\n");
        *piks = NULL;
        return DSERR_OUTOFMEMORY;
    }

    iks->ref = 0;
    iks->dsb = dsb;
    dsb->iks = iks;
    iks->lpVtbl = &iksbvt;

    IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)dsb);

    *piks = iks;
    return S_OK;
}

HRESULT IKsBufferPropertySetImpl_Destroy(
    IKsBufferPropertySetImpl *piks)
{
    TRACE("(%p)\n",piks);

    while (IKsBufferPropertySetImpl_Release((LPKSPROPERTYSET)piks) > 0);

    return S_OK;
}

/*******************************************************************************
 *              IKsPrivatePropertySet
 */

/* IUnknown methods */
static HRESULT WINAPI IKsPrivatePropertySetImpl_QueryInterface(
    LPKSPROPERTYSET iface,
    REFIID riid,
    LPVOID *ppobj )
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if (IsEqualIID(riid, &IID_IUnknown) ||
        IsEqualIID(riid, &IID_IKsPropertySet)) {
        *ppobj = iface;
        IUnknown_AddRef(iface);
        return S_OK;
    }
    *ppobj = NULL;
    return E_NOINTERFACE;
}

static ULONG WINAPI IKsPrivatePropertySetImpl_AddRef(LPKSPROPERTYSET iface)
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
    ULONG ref = InterlockedIncrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref - 1);
    return ref;
}

static ULONG WINAPI IKsPrivatePropertySetImpl_Release(LPKSPROPERTYSET iface)
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
    ULONG ref = InterlockedDecrement(&(This->ref));
    TRACE("(%p) ref was %d\n", This, ref + 1);

    if (!ref) {
        HeapFree(GetProcessHeap(), 0, This);
	TRACE("(%p) released\n", This);
    }
    return ref;
}

static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingA(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    HRESULT hr = DSERR_INVALIDPARAM;
    PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA ppd;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	  pPropData,cbPropData,pcbReturned);

    ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA) pPropData;

    if (!ppd) {
	WARN("invalid parameter: pPropData\n");
	return DSERR_INVALIDPARAM;
    }

    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
        ULONG wod;
        unsigned int wodn;
        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
        wodn = waveOutGetNumDevs();
        for (wod = 0; wod < wodn; wod++) {
            WAVEOUTCAPSA capsA;
            MMRESULT res;
            res = waveOutGetDevCapsA(wod, &capsA, sizeof(capsA));
            if (res == MMSYSERR_NOERROR) {
                if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
                    ppd->DeviceId = DSOUND_renderer_guids[wod];
                    hr = DS_OK;
                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
                          ppd->DeviceName);
                    break;
                }
            }
        }
    } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
        ULONG wid;
        unsigned int widn;
        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
        widn = waveInGetNumDevs();
        for (wid = 0; wid < widn; wid++) {
            WAVEINCAPSA capsA;
            MMRESULT res;
            res = waveInGetDevCapsA(wid, &capsA, sizeof(capsA));
            if (res == MMSYSERR_NOERROR) {
                if (lstrcmpA(capsA.szPname, ppd->DeviceName) == 0) {
                    ppd->DeviceId = DSOUND_capture_guids[wid];
                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
                          ppd->DeviceName);
                    hr = DS_OK;
                    break;
                }
            }
        }
    }

    if (pcbReturned)
	*pcbReturned = cbPropData;

    return hr;
}

static HRESULT WINAPI DSPROPERTY_WaveDeviceMappingW(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    HRESULT hr = DSERR_INVALIDPARAM;
    PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA ppd;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	  pPropData,cbPropData,pcbReturned);

    ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA) pPropData;

    if (!ppd) {
	WARN("invalid parameter: pPropData\n");
	return DSERR_INVALIDPARAM;
    }

    if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
        ULONG wod;
        unsigned int wodn;
        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
        wodn = waveOutGetNumDevs();
        for (wod = 0; wod < wodn; wod++) {
            WAVEOUTCAPSW capsW;
            MMRESULT res;
            res = waveOutGetDevCapsW(wod, &capsW, sizeof(capsW));
            if (res == MMSYSERR_NOERROR) {
                if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
                    ppd->DeviceId = DSOUND_renderer_guids[wod];
                    hr = DS_OK;
                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
                          debugstr_w(ppd->DeviceName));
                    break;
                }
            }
        }
    } else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
        ULONG wid;
        unsigned int widn;
        TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
        widn = waveInGetNumDevs();
        for (wid = 0; wid < widn; wid++) {
            WAVEINCAPSW capsW;
            MMRESULT res;
            res = waveInGetDevCapsW(wid, &capsW, sizeof(capsW));
            if (res == MMSYSERR_NOERROR) {
                if (lstrcmpW(capsW.szPname, ppd->DeviceName) == 0) {
                    ppd->DeviceId = DSOUND_capture_guids[wid];
                    hr = DS_OK;
                    TRACE("found %s for %s\n", debugstr_guid(&ppd->DeviceId),
                          debugstr_w(ppd->DeviceName));
                    break;
                }
            }
        }
    }

    if (pcbReturned)
        *pcbReturned = cbPropData;

    return hr;
}

static HRESULT WINAPI DSPROPERTY_Description1(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    HRESULT err;
    GUID guid, dev_guid;
    PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA ppd;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	pPropData,cbPropData,pcbReturned);

    ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA) pPropData;

    if (!ppd) {
	WARN("invalid parameter: pPropData\n");
	return DSERR_INVALIDPARAM;
    }

    TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
    if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
	/* default device of type specified by ppd->DataFlow */
	if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
	} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
	} else {
	    TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
	}
	FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
	      pPropData,cbPropData,pcbReturned);
	return E_PROP_ID_UNSUPPORTED;
    }

    ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
    GetDeviceID(&ppd->DeviceId, &dev_guid);

    if ( IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultPlayback) ||
	 IsEqualGUID( &ppd->DeviceId, &DSDEVID_DefaultVoicePlayback) ) {
	ULONG wod;
	unsigned int wodn;
	TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                ppd->WaveDeviceId = wod;
                ppd->Devnode = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
                    lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
                    MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
                    MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
                    err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                    if (err == DS_OK && drv)
                        ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                    else
                        WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                    break;
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
                }
            }
	}
    } else if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
	        IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
	ULONG wid;
	unsigned int widn;
	TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
	widn = waveInGetNumDevs();
	for (wid = 0; wid < widn; wid++) {
            if (IsEqualGUID( &dev_guid, &guid) ) {
                DSDRIVERDESC desc;
                ppd->WaveDeviceId = wid;
                ppd->Devnode = wid;
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSCDRIVER drv;
                    lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
                    lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
                    MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
                    MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
                    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
                    if (err == DS_OK && drv)
                        ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                    else
                        WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                    break;
                } else {
                    WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
                }
            }
	}
    } else {
	BOOL found = FALSE;
	ULONG wod;
	unsigned int wodn;
	/* given specific device so try the render devices first */
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
                ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                ppd->WaveDeviceId = wod;
                ppd->Devnode = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
                    lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
                    MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
                    MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
                    err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                    if (err == DS_OK && drv)
                        ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                    else
                        WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                    found = TRUE;
                    break;
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
                }
            }
	}

	if (found == FALSE) {
            ULONG wid;
            unsigned int widn;
            /* given specific device so try the capture devices next */
            widn = waveInGetNumDevs();
            for (wid = 0; wid < widn; wid++) {
                if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
                    DSDRIVERDESC desc;
                    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
                    ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
                    ppd->WaveDeviceId = wid;
                    ppd->Devnode = wid;
                    err = mmErr(waveInMessage((HWAVEIN)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                    if (err == DS_OK) {
                        PIDSDRIVER drv = NULL;
                        lstrcpynA(ppd->DescriptionA, desc.szDesc, sizeof(ppd->DescriptionA));
                        lstrcpynA(ppd->ModuleA, desc.szDrvname, sizeof(ppd->ModuleA));
                        MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->DescriptionW, sizeof(ppd->DescriptionW)/sizeof(WCHAR) );
                        MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->ModuleW, sizeof(ppd->ModuleW)/sizeof(WCHAR) );
                        err = mmErr(waveInMessage((HWAVEIN)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                        if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                        found = TRUE;
                        break;
                    } else {
                        WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                        return E_PROP_ID_UNSUPPORTED;
                    }
                }
            }

            if (found == FALSE) {
                WARN("device not found\n");
                return E_PROP_ID_UNSUPPORTED;
            }
	}
    }

    if (pcbReturned) {
	*pcbReturned = cbPropData;
	TRACE("*pcbReturned=%d\n", *pcbReturned);
    }

    return S_OK;
}

static HRESULT WINAPI DSPROPERTY_DescriptionA(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA) pPropData;
    HRESULT err;
    GUID dev_guid;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	  pPropData,cbPropData,pcbReturned);

    TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
    if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
	/* default device of type specified by ppd->DataFlow */
	if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
	} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
	} else {
	    TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
	}
	FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
	      pPropData,cbPropData,pcbReturned);
	return E_PROP_ID_UNSUPPORTED;
    }

    ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
    GetDeviceID(&ppd->DeviceId, &dev_guid);

    if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
	 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
	ULONG wod;
	unsigned int wodn;
        if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
            TRACE("DSDEVID_DefaultPlayback\n");
        else
            TRACE("DSDEVID_DefaultVoicePlayback\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                ppd->WaveDeviceId = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    /* FIXME: this is a memory leak */
                    CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
                    CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
                    CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);

                    if (szDescription && szModule && szInterface) {
                        strcpy(szDescription, desc.szDesc);
                        strcpy(szModule, desc.szDrvname);
                        strcpy(szInterface, "Interface");

                        ppd->Description = szDescription;
                        ppd->Module = szModule;
                        ppd->Interface = szInterface;
                        err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                        if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                        break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, szDescription);
                        HeapFree(GetProcessHeap(), 0, szModule);
                        HeapFree(GetProcessHeap(), 0, szInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
	}
    } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
	       IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
	ULONG wid;
	unsigned int widn;
        if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) )
            TRACE("DSDEVID_DefaultCapture\n");
        else
            TRACE("DSDEVID_DefaultVoiceCapture\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
	widn = waveInGetNumDevs();
	for (wid = 0; wid < widn; wid++) {
            if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
                DSDRIVERDESC desc;
                ppd->WaveDeviceId = wid;
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSCDRIVER drv;
                    /* FIXME: this is a memory leak */
                    CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
                    CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
                    CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);

                    if (szDescription && szModule && szInterface) {
                        strcpy(szDescription, desc.szDesc);
                        strcpy(szModule, desc.szDrvname);
                        strcpy(szInterface, "Interface");

                        ppd->Description = szDescription;
                        ppd->Module = szModule;
                        ppd->Interface = szInterface;
                        err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
                        if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                        break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, szDescription);
                        HeapFree(GetProcessHeap(), 0, szModule);
                        HeapFree(GetProcessHeap(), 0, szInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
	}
    } else {
	BOOL found = FALSE;
	ULONG wod;
	unsigned int wodn;
	/* given specific device so try the render devices first */
        TRACE("Checking renderer devices\n");
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                TRACE("DSOUND_renderer_guids[%d]\n", wod);
                ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                ppd->WaveDeviceId = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    /* FIXME: this is a memory leak */
                    CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
                    CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
                    CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);

                    if (szDescription && szModule && szInterface) {
			strcpy(szDescription, desc.szDesc);
			strcpy(szModule, desc.szDrvname);
			strcpy(szInterface, "Interface");

			ppd->Description = szDescription;
			ppd->Module = szModule;
			ppd->Interface = szInterface;
			err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
			if (err == DS_OK && drv)
				ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
			found = TRUE;
			break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, szDescription);
                        HeapFree(GetProcessHeap(), 0, szModule);
                        HeapFree(GetProcessHeap(), 0, szInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
        }

        if (found == FALSE) {
            ULONG wid;
            unsigned int widn;
            TRACE("Checking capture devices\n");
            ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
            widn = waveInGetNumDevs();
            for (wid = 0; wid < widn; wid++) {
                if (IsEqualGUID( &ppd->DeviceId, &DSOUND_capture_guids[wid] ) ) {
                    DSDRIVERDESC desc;
                    TRACE("DSOUND_capture_guids[%d]\n", wid);
                    ppd->WaveDeviceId = wid;
                    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                    if (err == DS_OK) {
                        PIDSCDRIVER drv;
                        /* FIXME: this is a memory leak */
                        CHAR * szDescription = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDesc) + 1);
                        CHAR * szModule = HeapAlloc(GetProcessHeap(),0,strlen(desc.szDrvname) + 1);
                        CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,strlen("Interface") + 1);

                        if (szDescription && szModule && szInterface) {
                            strcpy(szDescription, desc.szDesc);
                            strcpy(szModule, desc.szDrvname);
                            strcpy(szInterface, "Interface");

                            ppd->Description = szDescription;
                            ppd->Module = szModule;
                            ppd->Interface = szInterface;
                            err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
                            if (err == DS_OK && drv)
                                ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                            else
                                WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                            found = TRUE;
                            break;
                        } else {
                            WARN("no memory\n");
                            HeapFree(GetProcessHeap(), 0, szDescription);
                            HeapFree(GetProcessHeap(), 0, szModule);
                            HeapFree(GetProcessHeap(), 0, szInterface);
                            return E_OUTOFMEMORY;
                        }
                    } else {
                        WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                        return E_PROP_ID_UNSUPPORTED;
                    }
                }
            }
	}

	if (found == FALSE) {
	    WARN("device not found\n");
	    return E_PROP_ID_UNSUPPORTED;
	}
    }

    if (pcbReturned) {
	*pcbReturned = cbPropData;
	TRACE("*pcbReturned=%d\n", *pcbReturned);
    }

    return S_OK;
}

static HRESULT WINAPI DSPROPERTY_DescriptionW(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA) pPropData;
    HRESULT err;
    GUID dev_guid;
    TRACE("pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
	  pPropData,cbPropData,pcbReturned);

    TRACE("DeviceId=%s\n",debugstr_guid(&ppd->DeviceId));
    if ( IsEqualGUID( &ppd->DeviceId , &GUID_NULL) ) {
	/* default device of type specified by ppd->DataFlow */
	if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE\n");
	} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
	    TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
	} else {
	    TRACE("DataFlow=Unknown(%d)\n", ppd->DataFlow);
	}
	FIXME("(pPropData=%p,cbPropData=%d,pcbReturned=%p) GUID_NULL not implemented!\n",
	      pPropData,cbPropData,pcbReturned);
	return E_PROP_ID_UNSUPPORTED;
    }

    ppd->Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
    GetDeviceID(&ppd->DeviceId, &dev_guid);

    if ( IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) ||
	 IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoicePlayback) ) {
	ULONG wod;
	unsigned int wodn;
        if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultPlayback) )
            TRACE("DSDEVID_DefaultPlayback\n");
        else
            TRACE("DSDEVID_DefaultVoicePlayback\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &dev_guid, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                TRACE("DSOUND_renderer_guids[%d]\n", wod);
                ppd->WaveDeviceId = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    /* FIXME: this is a memory leak */
                    WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);

                    if (wDescription && wModule && wInterface) {
                        MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
                        MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
                        MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );

                        ppd->Description = wDescription;
                        ppd->Module = wModule;
                        ppd->Interface = wInterface;
                        err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                        if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                        break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, wDescription);
                        HeapFree(GetProcessHeap(), 0, wModule);
                        HeapFree(GetProcessHeap(), 0, wInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
	}
    } else if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture) ||
	       IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultVoiceCapture) ) {
	ULONG wid;
	unsigned int widn;
        if (IsEqualGUID( &ppd->DeviceId , &DSDEVID_DefaultCapture))
            TRACE("DSDEVID_DefaultCapture\n");
        else
            TRACE("DSDEVID_DefaultVoiceCapture\n");
	ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
	widn = waveInGetNumDevs();
	for (wid = 0; wid < widn; wid++) {
            if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
                DSDRIVERDESC desc;
                ppd->WaveDeviceId = wid;
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSCDRIVER drv;
                    /* FIXME: this is a memory leak */
                    WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);

                    if (wDescription && wModule && wInterface) {
                        MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
                        MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
                        MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );

                        ppd->Description = wDescription;
                        ppd->Module = wModule;
                        ppd->Interface = wInterface;
                        err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
                        if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
			break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, wDescription);
                        HeapFree(GetProcessHeap(), 0, wModule);
                        HeapFree(GetProcessHeap(), 0, wInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
	}
    } else {
	BOOL found = FALSE;
	ULONG wod;
	unsigned int wodn;
        TRACE("Checking renderer devices\n");
	/* given specific device so try the render devices first */
	wodn = waveOutGetNumDevs();
	for (wod = 0; wod < wodn; wod++) {
            if (IsEqualGUID( &ppd->DeviceId, &DSOUND_renderer_guids[wod] ) ) {
                DSDRIVERDESC desc;
                TRACE("DSOUND_renderer_guids[%d]\n", wod);
                ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                ppd->WaveDeviceId = wod;
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                if (err == DS_OK) {
                    PIDSDRIVER drv = NULL;
                    /* FIXME: this is a memory leak */
                    WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);

                    if (wDescription && wModule && wInterface) {
			MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
			MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
			MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );

			ppd->Description = wDescription;
			ppd->Module = wModule;
			ppd->Interface = wInterface;
			err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
			if (err == DS_OK && drv)
                            ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                        else
                            WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");
			found = TRUE;
			break;
		    } else {
                        WARN("no memory\n");
                        HeapFree(GetProcessHeap(), 0, wDescription);
                        HeapFree(GetProcessHeap(), 0, wModule);
                        HeapFree(GetProcessHeap(), 0, wInterface);
                        return E_OUTOFMEMORY;
		    }
                } else {
                    WARN("waveOutMessage(DRV_QUERYDSOUNDDESC) failed\n");
                    return E_PROP_ID_UNSUPPORTED;
		}
            }
        }

        if (found == FALSE) {
            ULONG wid;
            unsigned int widn;
            TRACE("Checking capture devices\n");
            ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
            widn = waveInGetNumDevs();
            for (wid = 0; wid < widn; wid++) {
                if (IsEqualGUID( &dev_guid, &DSOUND_capture_guids[wid] ) ) {
                    DSDRIVERDESC desc;
                    TRACE("DSOUND_capture_guids[%d]\n", wid);
                    ppd->WaveDeviceId = wid;
                    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&(desc),0));
                    if (err == DS_OK) {
                        PIDSCDRIVER drv;
                        /* FIXME: this is a memory leak */
                        WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                        WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                        WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,0x200);

                        if (wDescription && wModule && wInterface) {
                            MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100  );
                            MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );
                            MultiByteToWideChar( CP_ACP, 0, "Interface", -1, wInterface, 0x100 );

                            ppd->Description = wDescription;
                            ppd->Module = wModule;
                            ppd->Interface = wInterface;
                            err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDIFACE,(DWORD_PTR)&drv,0));
                            if (err == DS_OK && drv)
                                ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                            else
                                WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");
                            found = TRUE;
                            break;
                        } else {
                            WARN("no memory\n");
                            HeapFree(GetProcessHeap(), 0, wDescription);
                            HeapFree(GetProcessHeap(), 0, wModule);
                            HeapFree(GetProcessHeap(), 0, wInterface);
                            return E_OUTOFMEMORY;
                        }
                    } else {
                        WARN("waveInMessage(DRV_QUERYDSOUNDDESC) failed\n");
                        return E_PROP_ID_UNSUPPORTED;
                    }
                }
            }
        }

	if (found == FALSE) {
	    WARN("device not found\n");
	    return E_PROP_ID_UNSUPPORTED;
	}
    }

    if (pcbReturned) {
	*pcbReturned = cbPropData;
	TRACE("*pcbReturned=%d\n", *pcbReturned);
    }

    return S_OK;
}

static HRESULT WINAPI DSPROPERTY_Enumerate1(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA) pPropData;
    HRESULT err;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
          pPropData,cbPropData,pcbReturned);

    if (ppd) {
        if (ppd->Callback) {
            unsigned devs, wod, wid;
            DSDRIVERDESC desc;
            DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA data;

            devs = waveOutGetNumDevs();
            for (wod = 0; wod < devs; ++wod) {
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    PIDSCDRIVER drv;
                    ZeroMemory(&data, sizeof(data));
                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                    data.WaveDeviceId = wod;
                    data.DeviceId = DSOUND_renderer_guids[wod];
                    lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
                    lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));

                    MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
                    MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );

                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                    err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                    if (err == DS_OK && drv)
                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                    else
                        WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                    (ppd->Callback)(&data, ppd->Context);
                }
            }

            devs = waveInGetNumDevs();
            for (wid = 0; wid < devs; ++wid) {
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    PIDSCDRIVER drv;
                    ZeroMemory(&data, sizeof(data));
                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
                    data.WaveDeviceId = wid;
                    data.DeviceId = DSOUND_capture_guids[wid];
                    lstrcpynA(data.DescriptionA, desc.szDesc, sizeof(data.DescriptionA));
                    lstrcpynA(data.ModuleA, desc.szDrvname, sizeof(data.ModuleA));

                    MultiByteToWideChar( CP_ACP, 0, data.DescriptionA, -1, data.DescriptionW, sizeof(data.DescriptionW)/sizeof(WCHAR) );
                    MultiByteToWideChar( CP_ACP, 0, data.ModuleA, -1, data.ModuleW, sizeof(data.ModuleW)/sizeof(WCHAR) );

                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                    err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                    if (err == DS_OK && drv)
                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                    else
                        WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                    (ppd->Callback)(&data, ppd->Context);
                }
            }

            return S_OK;
        }
    }

    if (pcbReturned) {
        *pcbReturned = 0;
        FIXME("*pcbReturned=%d\n", *pcbReturned);
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI DSPROPERTY_EnumerateA(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA) pPropData;
    HRESULT err;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
          pPropData,cbPropData,pcbReturned);

    if (ppd) {
        if (ppd->Callback) {
            unsigned devs, wod, wid;
            DSDRIVERDESC desc;
            DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA data;

            devs = waveOutGetNumDevs();
            for (wod = 0; wod < devs; ++wod) {
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    DWORD size;
                    err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
                    if (err == DS_OK) {
                        WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
                        if (nameW) {
                            err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
                            if (err == DS_OK) {
                                CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
                                if (szInterface) {
                                    PIDSCDRIVER drv;
                                    ZeroMemory(&data, sizeof(data));
                                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                                    data.WaveDeviceId = wod;
                                    data.DeviceId = DSOUND_renderer_guids[wod];
                                    data.Description = desc.szDesc;
                                    data.Module = desc.szDrvname;
                                    WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
                                    data.Interface = szInterface;

                                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                                    err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                                    if (err == DS_OK && drv)
                                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                                    else
                                        WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                                    (ppd->Callback)(&data, ppd->Context);
                                }
                                HeapFree(GetProcessHeap(),0,szInterface);
                            }
                        }
                        HeapFree(GetProcessHeap(),0,nameW);
                    }
                }
            }

            devs = waveInGetNumDevs();
            for (wid = 0; wid < devs; ++wid) {
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    DWORD size;
                    err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE,(DWORD_PTR)&size,0));
                    if (err == DS_OK) {
                        WCHAR * nameW = HeapAlloc(GetProcessHeap(),0,size);
                        if (nameW) {
                            err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACE,(DWORD_PTR)nameW,size));
                            if (err == DS_OK) {
                                CHAR * szInterface = HeapAlloc(GetProcessHeap(),0,size/sizeof(WCHAR));
                                if (szInterface) {
                                    PIDSCDRIVER drv;
                                    ZeroMemory(&data, sizeof(data));
                                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
                                    data.WaveDeviceId = wid;
                                    data.DeviceId = DSOUND_capture_guids[wid];
                                    data.Description = desc.szDesc;
                                    data.Module = desc.szDrvname;
                                    WideCharToMultiByte( CP_ACP, 0, nameW, size/sizeof(WCHAR), szInterface, size/sizeof(WCHAR), NULL, NULL );
                                    data.Interface = szInterface;

                                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                                    err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                                    if (err == DS_OK && drv)
                                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                                    else
                                        WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                                    (ppd->Callback)(&data, ppd->Context);
                                }
                                HeapFree(GetProcessHeap(),0,szInterface);
                            }
                        }
                        HeapFree(GetProcessHeap(),0,nameW);
                    }
                }
            }

            return S_OK;
        }
    }

    if (pcbReturned) {
        *pcbReturned = 0;
        FIXME("*pcbReturned=%d\n", *pcbReturned);
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI DSPROPERTY_EnumerateW(
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = (PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA) pPropData;
    HRESULT err;
    TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
          pPropData,cbPropData,pcbReturned);

    if (ppd) {
        if (ppd->Callback) {
            unsigned devs, wod, wid;
            DSDRIVERDESC desc;
            DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;

            devs = waveOutGetNumDevs();
            for (wod = 0; wod < devs; ++wod) {
                err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                    if (wDescription && wModule) {
                        DWORD size;
                        err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
                        if (err == DS_OK) {
                            WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
                            if (wInterface) {
                                err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
                                if (err == DS_OK) {
                                    PIDSCDRIVER drv;
                                    ZeroMemory(&data, sizeof(data));
                                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
                                    data.WaveDeviceId = wod;
                                    data.DeviceId = DSOUND_renderer_guids[wod];

                                    MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
                                    MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );

                                    data.Description = wDescription;
                                    data.Module = wModule;
                                    data.Interface = wInterface;

                                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                                    err = mmErr(waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                                    if (err == DS_OK && drv)
                                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                                    else
                                        WARN("waveOutMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                                    (ppd->Callback)(&data, ppd->Context);
                                    }
                            }
                            HeapFree(GetProcessHeap(),0,wInterface);
                        }
                    }
                    HeapFree(GetProcessHeap(),0,wDescription);
                    HeapFree(GetProcessHeap(),0,wModule);
                }
            }

            devs = waveInGetNumDevs();
            for (wid = 0; wid < devs; ++wid) {
                err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0));
                if (err == DS_OK) {
                    WCHAR * wDescription = HeapAlloc(GetProcessHeap(),0,0x200);
                    WCHAR * wModule = HeapAlloc(GetProcessHeap(),0,0x200);
                    if (wDescription && wModule) {
                        DWORD size;
                        err = mmErr(waveInMessage((HWAVEIN)wid,DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&size, 0));
                        if (err == DS_OK) {
                            WCHAR * wInterface = HeapAlloc(GetProcessHeap(),0,size);
                            if (wInterface) {
                                err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)wInterface, size));
                                if (err == DS_OK) {
                                    PIDSCDRIVER drv;
                                    ZeroMemory(&data, sizeof(data));
                                    data.DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
                                    data.WaveDeviceId = wid;
                                    data.DeviceId = DSOUND_capture_guids[wid];

                                    MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, wDescription, 0x100 );
                                    MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, wModule, 0x100 );

                                    data.Description = wDescription;
                                    data.Module = wModule;
                                    data.Interface = wInterface;
                                    data.Type = DIRECTSOUNDDEVICE_TYPE_EMULATED;
                                    err = mmErr(waveInMessage((HWAVEIN)wid, DRV_QUERYDSOUNDIFACE, (DWORD_PTR)&drv, 0));
                                    if (err == DS_OK && drv)
                                        data.Type = DIRECTSOUNDDEVICE_TYPE_VXD;
                                    else
                                        WARN("waveInMessage(DRV_QUERYDSOUNDIFACE) failed\n");

                                    TRACE("calling Callback(%p,%p)\n", &data, ppd->Context);
                                    (ppd->Callback)(&data, ppd->Context);
                                }
                            }
                            HeapFree(GetProcessHeap(),0,wInterface);
                        }
                    }
                    HeapFree(GetProcessHeap(),0,wDescription);
                    HeapFree(GetProcessHeap(),0,wModule);
                }
            }

            return S_OK;
        }
    }

    if (pcbReturned) {
        *pcbReturned = 0;
        FIXME("*pcbReturned=%d\n", *pcbReturned);
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI IKsPrivatePropertySetImpl_Get(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData,
    PULONG pcbReturned )
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
    TRACE("(iface=%p,guidPropSet=%s,dwPropID=%d,pInstanceData=%p,cbInstanceData=%d,pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
          This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData,pcbReturned);

    if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
        switch (dwPropID) {
        case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
            return DSPROPERTY_WaveDeviceMappingA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
            return DSPROPERTY_Description1(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
            return DSPROPERTY_Enumerate1(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
            return DSPROPERTY_WaveDeviceMappingW(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
            return DSPROPERTY_DescriptionA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
            return DSPROPERTY_DescriptionW(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
            return DSPROPERTY_EnumerateA(pPropData,cbPropData,pcbReturned);
        case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
            return DSPROPERTY_EnumerateW(pPropData,cbPropData,pcbReturned);
        default:
            FIXME("unsupported ID: %d\n",dwPropID);
            break;
        }
    } else {
        FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
    }

    if (pcbReturned) {
        *pcbReturned = 0;
        FIXME("*pcbReturned=%d\n", *pcbReturned);
    }

    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI IKsPrivatePropertySetImpl_Set(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    LPVOID pInstanceData,
    ULONG cbInstanceData,
    LPVOID pPropData,
    ULONG cbPropData )
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;

    FIXME("(%p,%s,%d,%p,%d,%p,%d), stub!\n",This,debugstr_guid(guidPropSet),dwPropID,pInstanceData,cbInstanceData,pPropData,cbPropData);
    return E_PROP_ID_UNSUPPORTED;
}

static HRESULT WINAPI IKsPrivatePropertySetImpl_QuerySupport(
    LPKSPROPERTYSET iface,
    REFGUID guidPropSet,
    ULONG dwPropID,
    PULONG pTypeSupport )
{
    IKsPrivatePropertySetImpl *This = (IKsPrivatePropertySetImpl *)iface;
    TRACE("(%p,%s,%d,%p)\n",This,debugstr_guid(guidPropSet),dwPropID,pTypeSupport);

    if ( IsEqualGUID( &DSPROPSETID_DirectSoundDevice, guidPropSet) ) {
	switch (dwPropID) {
	case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	case DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W:
	    *pTypeSupport = KSPROPERTY_SUPPORT_GET;
	    return S_OK;
	default:
            FIXME("unsupported ID: %d\n",dwPropID);
	    break;
	}
    } else {
	FIXME("unsupported property: %s\n",debugstr_guid(guidPropSet));
    }

    return E_PROP_ID_UNSUPPORTED;
}

static const IKsPropertySetVtbl ikspvt = {
    IKsPrivatePropertySetImpl_QueryInterface,
    IKsPrivatePropertySetImpl_AddRef,
    IKsPrivatePropertySetImpl_Release,
    IKsPrivatePropertySetImpl_Get,
    IKsPrivatePropertySetImpl_Set,
    IKsPrivatePropertySetImpl_QuerySupport
};

HRESULT IKsPrivatePropertySetImpl_Create(
    REFIID riid,
    IKsPrivatePropertySetImpl **piks)
{
    IKsPrivatePropertySetImpl *iks;
    TRACE("(%s, %p)\n", debugstr_guid(riid), piks);

    if (!IsEqualIID(riid, &IID_IUnknown) &&
        !IsEqualIID(riid, &IID_IKsPropertySet)) {
        *piks = 0;
        return E_NOINTERFACE;
    }

    iks = HeapAlloc(GetProcessHeap(),0,sizeof(*iks));
    iks->ref = 1;
    iks->lpVtbl = &ikspvt;

    *piks = iks;
    return S_OK;
}
