From: David McFarland corngood@gmail.com
--- dlls/mmdevapi/devenum.c | 298 ++++++++++++++++++++++++++++++- dlls/mmdevapi/mmdevapi_private.h | 1 + dlls/mmdevapi/tests/mmdevenum.c | 1 - 3 files changed, 298 insertions(+), 2 deletions(-)
diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 3c2085339ed..a8aaaa197a3 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -667,7 +667,7 @@ static HRESULT WINAPI MMDevice_Activate(IMMDevice *iface, REFIID riid, DWORD cls } else if (IsEqualIID(riid, &IID_IDeviceTopology)) { - FIXME("IID_IDeviceTopology unsupported\n"); + hr = DeviceTopology_Create(iface, (IDeviceTopology**)ppv); } else if (IsEqualIID(riid, &IID_IDirectSound) || IsEqualIID(riid, &IID_IDirectSound8)) @@ -1660,3 +1660,299 @@ static const IMMDeviceVtbl info_device_Vtbl = static IMMDevice info_device = { &info_device_Vtbl }; + +struct connector { + IConnector IConnector_iface; + + LONG ref; +}; + +static inline struct connector *impl_from_IConnector(IConnector *iface) +{ + return CONTAINING_RECORD(iface, struct connector, IConnector_iface); +} + +static HRESULT WINAPI connector_QueryInterface(IConnector *iface, REFIID riid, void **ppv) +{ + struct connector *This = impl_from_IConnector(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IConnector)) + *ppv = &This->IConnector_iface; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*ppv); + + return S_OK; +} + +static ULONG WINAPI connector_AddRef(IConnector *iface) +{ + struct connector *This = impl_from_IConnector(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + return ref; +} + +static ULONG WINAPI connector_Release(IConnector *iface) +{ + struct connector *This = impl_from_IConnector(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI connector_GetType( + IConnector *This, + ConnectorType *pType) +{ + FIXME("(%p) - partial stub\n", This); + *pType = Physical_Internal; + return S_OK; +} + +static HRESULT WINAPI connector_GetDataFlow( + IConnector *This, + DataFlow *pFlow) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_ConnectTo( + IConnector *This, + IConnector *pConnectTo) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_Disconnect( + IConnector *This) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_IsConnected( + IConnector *This, + BOOL *pbConnected) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_GetConnectedTo( + IConnector *This, + IConnector **ppConTo) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_GetConnectorIdConnectedTo( + IConnector *This, + LPWSTR *ppwstrConnectorId) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI connector_GetDeviceIdConnectedTo( + IConnector *This, + LPWSTR *ppwstrDeviceId) +{ + FIXME("(%p) - stub\n", This); + return E_NOTIMPL; +} + +static const IConnectorVtbl Connector_Vtbl = +{ + connector_QueryInterface, + connector_AddRef, + connector_Release, + connector_GetType, + connector_GetDataFlow, + connector_ConnectTo, + connector_Disconnect, + connector_IsConnected, + connector_GetConnectedTo, + connector_GetConnectorIdConnectedTo, + connector_GetDeviceIdConnectedTo, +}; + +HRESULT connector_Create(IConnector **ppv) +{ + struct connector *This; + + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->IConnector_iface.lpVtbl = &Connector_Vtbl; + This->ref = 1; + + *ppv = &This->IConnector_iface; + + return S_OK; +} + +struct device_topology { + IDeviceTopology IDeviceTopology_iface; + + LONG ref; +}; + +static inline struct device_topology *impl_from_IDeviceTopology(IDeviceTopology *iface) +{ + return CONTAINING_RECORD(iface, struct device_topology, IDeviceTopology_iface); +} + +static HRESULT WINAPI DT_QueryInterface(IDeviceTopology *iface, REFIID riid, void **ppv) +{ + struct device_topology *This = impl_from_IDeviceTopology(iface); + TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv); + + if (!ppv) + return E_POINTER; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IDeviceTopology)) + *ppv = &This->IDeviceTopology_iface; + else { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*ppv); + + return S_OK; +} + +static ULONG WINAPI DT_AddRef(IDeviceTopology *iface) +{ + struct device_topology *This = impl_from_IDeviceTopology(iface); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + return ref; +} + +static ULONG WINAPI DT_Release(IDeviceTopology *iface) +{ + struct device_topology *This = impl_from_IDeviceTopology(iface); + ULONG ref = InterlockedDecrement(&This->ref); + TRACE("(%p) new ref %lu\n", This, ref); + + if (!ref) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI DT_GetConnectorCount(IDeviceTopology *This, + UINT *pCount) +{ + FIXME("(%p)->(%p) - partial stub\n", This, pCount); + + if (!pCount) + return E_POINTER; + + *pCount = 1; + return S_OK; +} + +static HRESULT WINAPI DT_GetConnector(IDeviceTopology *This, + UINT nIndex, + IConnector **ppConnector) +{ + FIXME("(%p)->(%u, %p) - partial stub\n", This, nIndex, ppConnector); + + if (nIndex == 0) + { + return connector_Create(ppConnector); + } + + return E_INVALIDARG; +} + +static HRESULT WINAPI DT_GetSubunitCount(IDeviceTopology *This, + UINT *pCount) +{ + FIXME("(%p)->(%p) - stub\n", This, pCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI DT_GetSubunit(IDeviceTopology *This, + UINT nIndex, + ISubUnit **ppConnector) +{ + FIXME("(%p)->(%u, %p) - stub\n", This, nIndex, ppConnector); + return E_NOTIMPL; +} + +static HRESULT WINAPI DT_GetPartById(IDeviceTopology *This, + UINT nId, + IPart **ppPart) +{ + FIXME("(%p)->(%u, %p) - stub\n", This, nId, ppPart); + return E_NOTIMPL; +} + +static HRESULT WINAPI DT_GetDeviceId(IDeviceTopology *This, + LPWSTR *ppwstrDeviceId) +{ + FIXME("(%p)->(%p) - stub\n", This, ppwstrDeviceId); + return E_NOTIMPL; +} + +static HRESULT WINAPI DT_GetSignalPath(IDeviceTopology *This, + IPart *pIPartFrom, + IPart *pIPartTo, + BOOL bRejectMixedPaths, + IPartsList **ppParts) +{ + FIXME("(%p)->(%p, %p, %s, %p) - stub\n", + This, pIPartFrom, pIPartTo, bRejectMixedPaths ? "TRUE" : "FALSE", ppParts); + return E_NOTIMPL; +} + +static const IDeviceTopologyVtbl DeviceTopology_Vtbl = +{ + DT_QueryInterface, + DT_AddRef, + DT_Release, + DT_GetConnectorCount, + DT_GetConnector, + DT_GetSubunitCount, + DT_GetSubunit, + DT_GetPartById, + DT_GetDeviceId, + DT_GetSignalPath, +}; + +HRESULT DeviceTopology_Create(IMMDevice *device, IDeviceTopology **ppv) +{ + struct device_topology *This; + + This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This)); + if (!This) + return E_OUTOFMEMORY; + + This->IDeviceTopology_iface.lpVtbl = &DeviceTopology_Vtbl; + This->ref = 1; + + *ppv = &This->IDeviceTopology_iface; + + return S_OK; +} diff --git a/dlls/mmdevapi/mmdevapi_private.h b/dlls/mmdevapi/mmdevapi_private.h index 5ef19ffc0d1..950251a1457 100644 --- a/dlls/mmdevapi/mmdevapi_private.h +++ b/dlls/mmdevapi/mmdevapi_private.h @@ -73,6 +73,7 @@ extern HRESULT AudioClient_Create(GUID *guid, IMMDevice *device, IAudioClient ** extern HRESULT AudioEndpointVolume_Create(MMDevice *parent, IAudioEndpointVolumeEx **ppv); extern HRESULT AudioSessionManager_Create(IMMDevice *device, IAudioSessionManager2 **ppv); extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out); +extern HRESULT DeviceTopology_Create(IMMDevice *device, IDeviceTopology **out);
extern HRESULT load_devices_from_reg(void); extern HRESULT load_driver_devices(EDataFlow flow); diff --git a/dlls/mmdevapi/tests/mmdevenum.c b/dlls/mmdevapi/tests/mmdevenum.c index f34386a575a..3bceefb91a3 100644 --- a/dlls/mmdevapi/tests/mmdevenum.c +++ b/dlls/mmdevapi/tests/mmdevenum.c @@ -432,7 +432,6 @@ static void test_DeviceTopology(IMMDeviceEnumerator *mme) if (hr != S_OK || !dev) { if (hr == E_NOINTERFACE) - todo_wine win_skip("IDeviceTopology interface not found\n"); else skip("IDeviceTopology Activation returns 0x%08lx\n", hr);