wine/dlls/dsound/propset.c
Maarten Lankhorst ef0a0d8b86 Revert "dsound: Only initialize one guid for capture and renderer."
Reverts b474649e0e. Some games use
pointers to the guid rather than copying the guid even after the
enumeration function returns. Allocating on the stack breaks those
games.
2010-01-06 09:54:18 +01:00

645 lines
20 KiB
C

/* 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);
/*******************************************************************************
* 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 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 = 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 DSPROPERTY_WaveDeviceMappingA(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A_DATA *ppd = pPropData;
DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W_DATA data;
DWORD len;
HRESULT hr;
TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
pPropData,cbPropData,pcbReturned);
if (!ppd || !ppd->DeviceName) {
WARN("invalid parameter: ppd=%p\n", ppd);
return DSERR_INVALIDPARAM;
}
data.DataFlow = ppd->DataFlow;
len = MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, NULL, 0);
data.DeviceName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (!data.DeviceName)
return E_OUTOFMEMORY;
MultiByteToWideChar(CP_ACP, 0, ppd->DeviceName, -1, data.DeviceName, len);
hr = DSPROPERTY_WaveDeviceMappingW(&data, cbPropData, pcbReturned);
HeapFree(GetProcessHeap(), 0, data.DeviceName);
ppd->DeviceId = data.DeviceId;
if (pcbReturned)
*pcbReturned = cbPropData;
return hr;
}
static HRESULT DSPROPERTY_DescriptionW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA ppd = pPropData;
HRESULT err;
GUID dev_guid;
ULONG wod, wid, wodn, widn;
DSDRIVERDESC desc;
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");
ppd->DeviceId = DSDEVID_DefaultCapture;
} else if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER) {
TRACE("DataFlow=DIRECTSOUNDDEVICE_DATAFLOW_RENDER\n");
ppd->DeviceId = DSDEVID_DefaultPlayback;
} else {
WARN("DataFlow=Unknown(%d)\n", ppd->DataFlow);
return E_PROP_ID_UNSUPPORTED;
}
}
GetDeviceID(&ppd->DeviceId, &dev_guid);
wodn = waveOutGetNumDevs();
widn = waveInGetNumDevs();
wid = wod = dev_guid.Data4[7];
if (!memcmp(&dev_guid, &DSOUND_renderer_guids[0], sizeof(GUID)-1)
&& wod < wodn)
{
ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
ppd->WaveDeviceId = wod;
}
else if (!memcmp(&dev_guid, &DSOUND_capture_guids[0], sizeof(GUID)-1)
&& wid < widn)
{
ppd->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
ppd->WaveDeviceId = wid;
}
else
{
WARN("Device not found\n");
return E_PROP_ID_UNSUPPORTED;
}
if (ppd->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_RENDER)
err = waveOutMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
else
err = waveInMessage(UlongToHandle(wod),DRV_QUERYDSOUNDDESC,(DWORD_PTR)&desc,0);
if (err != MMSYSERR_NOERROR)
{
WARN("waveMessage(DRV_QUERYDSOUNDDESC) failed!\n");
return E_PROP_ID_UNSUPPORTED;
}
else
{
/* FIXME: Still a memory leak.. */
int desclen, modlen;
static WCHAR wInterface[] = { 'I','n','t','e','r','f','a','c','e',0 };
modlen = MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, NULL, 0 );
desclen = MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, NULL, 0 );
ppd->Module = HeapAlloc(GetProcessHeap(),0,modlen*sizeof(WCHAR));
ppd->Description = HeapAlloc(GetProcessHeap(),0,desclen*sizeof(WCHAR));
ppd->Interface = wInterface;
if (!ppd->Description || !ppd->Module)
{
WARN("Out of memory\n");
HeapFree(GetProcessHeap(), 0, ppd->Description);
HeapFree(GetProcessHeap(), 0, ppd->Module);
ppd->Description = ppd->Module = NULL;
return E_OUTOFMEMORY;
}
MultiByteToWideChar( CP_ACP, 0, desc.szDrvname, -1, ppd->Module, modlen );
MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1, ppd->Description, desclen );
}
ppd->Type = DIRECTSOUNDDEVICE_TYPE_VXD;
if (pcbReturned) {
*pcbReturned = sizeof(*ppd);
TRACE("*pcbReturned=%d\n", *pcbReturned);
}
return S_OK;
}
static HRESULT DSPROPERTY_EnumerateW(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned )
{
PDSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA ppd = pPropData;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
BOOL ret;
int widn, wodn, i;
TRACE("(pPropData=%p,cbPropData=%d,pcbReturned=%p)\n",
pPropData,cbPropData,pcbReturned);
if (pcbReturned)
*pcbReturned = 0;
if (!ppd || !ppd->Callback)
{
WARN("Invalid ppd %p\n", ppd);
return E_PROP_ID_UNSUPPORTED;
}
wodn = waveOutGetNumDevs();
widn = waveInGetNumDevs();
data.DeviceId = DSOUND_renderer_guids[0];
for (i = 0; i < wodn; ++i)
{
HRESULT hr;
data.DeviceId.Data4[7] = i;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
{
ERR("DescriptionW failed!\n");
return S_OK;
}
ret = ppd->Callback(&data, ppd->Context);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Description);
if (!ret)
return S_OK;
}
data.DeviceId = DSOUND_capture_guids[0];
for (i = 0; i < widn; ++i)
{
HRESULT hr;
data.DeviceId.Data4[7] = i;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
{
ERR("DescriptionW failed!\n");
return S_OK;
}
ret = ppd->Callback(&data, ppd->Context);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Description);
if (!ret)
return S_OK;
}
return S_OK;
}
static BOOL DSPROPERTY_descWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *dataA)
{
DWORD modlen, desclen;
static char Interface[] = "Interface";
modlen = WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, NULL, 0, NULL, NULL);
desclen = WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, NULL, 0, NULL, NULL);
dataA->Type = dataW->Type;
dataA->DataFlow = dataW->DataFlow;
dataA->DeviceId = dataW->DeviceId;
dataA->WaveDeviceId = dataW->WaveDeviceId;
dataA->Interface = Interface;
dataA->Module = HeapAlloc(GetProcessHeap(), 0, modlen);
dataA->Description = HeapAlloc(GetProcessHeap(), 0, desclen);
if (!dataA->Module || !dataA->Description)
{
HeapFree(GetProcessHeap(), 0, dataA->Module);
HeapFree(GetProcessHeap(), 0, dataA->Description);
dataA->Module = dataA->Description = NULL;
return FALSE;
}
WideCharToMultiByte(CP_ACP, 0, dataW->Module, -1, dataA->Module, modlen, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, dataW->Description, -1, dataA->Description, desclen, NULL, NULL);
return TRUE;
}
static void DSPROPERTY_descWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *dataW,
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *data1)
{
data1->DeviceId = dataW->DeviceId;
lstrcpynW(data1->ModuleW, dataW->Module, sizeof(data1->ModuleW)/sizeof(*data1->ModuleW));
lstrcpynW(data1->DescriptionW, dataW->Description, sizeof(data1->DescriptionW)/sizeof(*data1->DescriptionW));
WideCharToMultiByte(CP_ACP, 0, data1->DescriptionW, -1, data1->DescriptionA, sizeof(data1->DescriptionA)-1, NULL, NULL);
WideCharToMultiByte(CP_ACP, 0, data1->ModuleW, -1, data1->ModuleA, sizeof(data1->ModuleA)-1, NULL, NULL);
data1->DescriptionA[sizeof(data1->DescriptionA)-1] = 0;
data1->ModuleA[sizeof(data1->ModuleA)-1] = 0;
data1->Type = dataW->Type;
data1->DataFlow = dataW->DataFlow;
data1->WaveDeviceId = data1->Devnode = dataW->WaveDeviceId;
}
static BOOL CALLBACK DSPROPERTY_enumWtoA(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
{
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA descA;
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = data;
BOOL ret;
ret = DSPROPERTY_descWtoA(descW, &descA);
if (!ret)
return FALSE;
ret = ppd->Callback(&descA, ppd->Context);
HeapFree(GetProcessHeap(), 0, descA.Module);
HeapFree(GetProcessHeap(), 0, descA.Description);
return ret;
}
static HRESULT DSPROPERTY_EnumerateA(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned)
{
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A_DATA *ppd = pPropData;
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
if (!ppd || !ppd->Callback)
{
WARN("Invalid ppd %p\n", ppd);
return E_PROP_ID_UNSUPPORTED;
}
data.Callback = DSPROPERTY_enumWtoA;
data.Context = ppd;
return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}
static BOOL CALLBACK DSPROPERTY_enumWto1(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA *descW, void *data)
{
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA desc1;
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = data;
BOOL ret;
DSPROPERTY_descWto1(descW, &desc1);
ret = ppd->Callback(&desc1, ppd->Context);
return ret;
}
static HRESULT DSPROPERTY_Enumerate1(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned)
{
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1_DATA *ppd = pPropData;
DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W_DATA data;
if (!ppd || !ppd->Callback)
{
WARN("Invalid ppd %p\n", ppd);
return E_PROP_ID_UNSUPPORTED;
}
data.Callback = DSPROPERTY_enumWto1;
data.Context = ppd;
return DSPROPERTY_EnumerateW(&data, cbPropData, pcbReturned);
}
static HRESULT DSPROPERTY_DescriptionA(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned)
{
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A_DATA *ppd = pPropData;
HRESULT hr;
if (pcbReturned)
*pcbReturned = sizeof(*ppd);
if (!pPropData)
return S_OK;
data.DeviceId = ppd->DeviceId;
data.DataFlow = ppd->DataFlow;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
return hr;
if (!DSPROPERTY_descWtoA(&data, ppd))
hr = E_OUTOFMEMORY;
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Interface);
return hr;
}
static HRESULT DSPROPERTY_Description1(
LPVOID pPropData,
ULONG cbPropData,
PULONG pcbReturned)
{
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W_DATA data;
DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA *ppd = pPropData;
HRESULT hr;
if (pcbReturned)
*pcbReturned = sizeof(*ppd);
if (!pPropData)
return S_OK;
data.DeviceId = ppd->DeviceId;
data.DataFlow = ppd->DataFlow;
hr = DSPROPERTY_DescriptionW(&data, sizeof(data), NULL);
if (FAILED(hr))
return hr;
DSPROPERTY_descWto1(&data, ppd);
HeapFree(GetProcessHeap(), 0, data.Module);
HeapFree(GetProcessHeap(), 0, data.Interface);
return hr;
}
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;
}