Since Yousician's last update, it was throwing an error when initialising audio output. Unfortunately I don't have access to the old version, but they seem to have dropped win<10 support, and are using only IAudioClient3_InitializeSharedAudioStream. They also use IDeviceTopology to get the type of the first output connector.
This is the bare minimum I needed to get it working.
-- v8: mmdevapi: add stub for IDeviceTopology mmdevapi/tests: add test for IDeviceTopology mmdevapi: implement IAudioClient3_InitializeSharedAudioStream mmdevapi/tests: add test for AudioClient3_InitializeSharedAudioStream
From: David McFarland corngood@gmail.com
--- dlls/mmdevapi/tests/render.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index 8e000f03acb..fb346958437 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -325,8 +325,28 @@ static void test_audioclient(void) broken(hr == E_NOINTERFACE) /* win8 */, "Failed to query IAudioClient3 interface: %08lx\n", hr);
- if(hr == S_OK) + if(hr == S_OK){ + UINT32 default_period = 0, unit_period, min_period, max_period; + + hr = IAudioClient3_GetSharedModeEnginePeriod( + ac3, pwfx, &default_period, &unit_period, &min_period, &max_period); + todo_wine + ok(hr == S_OK, "GetSharedModeEnginePeriod returns %08lx\n", hr); + + hr = IAudioClient3_InitializeSharedAudioStream( + ac3, AUDCLNT_SHAREMODE_SHARED, default_period, pwfx, NULL); + todo_wine + ok(hr == S_OK, "InitializeSharedAudioStream returns %08lx\n", hr); + IAudioClient3_Release(ac3); + IAudioClient_Release(ac); + + hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_INPROC_SERVER, + NULL, (void**)&ac); + ok(hr == S_OK, "Activation failed with %08lx\n", hr); + } + else + win_skip("IAudioClient3 is not present\n");
test_uninitialized(ac);
From: David McFarland corngood@gmail.com
Also, implement IAudioClient3_GetSharedModeEnginePeriod with min/max/default all set to ~10ms. --- dlls/mmdevapi/client.c | 26 ++++++++++++++++++++------ dlls/mmdevapi/tests/render.c | 2 -- 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/dlls/mmdevapi/client.c b/dlls/mmdevapi/client.c index 8146f8a53b4..220352dd1fe 100644 --- a/dlls/mmdevapi/client.c +++ b/dlls/mmdevapi/client.c @@ -929,10 +929,17 @@ static HRESULT WINAPI client_GetSharedModeEnginePeriod(IAudioClient3 *iface, UINT32 *max_period_frames) { struct audio_client *This = impl_from_IAudioClient3(iface); - FIXME("(%p)->(%p, %p, %p, %p, %p) - stub\n", This, format, default_period_frames, - unit_period_frames, min_period_frames, - max_period_frames); - return E_NOTIMPL; + FIXME("(%p)->(%p, %p, %p, %p, %p) - partial stub\n", + This, format, default_period_frames, + unit_period_frames, min_period_frames, + max_period_frames); + + *default_period_frames = + *min_period_frames = + *max_period_frames = + format->nSamplesPerSec / 100; // ~10ms + *unit_period_frames = 1; + return S_OK; }
static HRESULT WINAPI client_GetCurrentSharedModeEnginePeriod(IAudioClient3 *iface, @@ -949,9 +956,16 @@ static HRESULT WINAPI client_InitializeSharedAudioStream(IAudioClient3 *iface, D const WAVEFORMATEX *format, const GUID *session_guid) { + struct audio_client *This = impl_from_IAudioClient3(iface); - FIXME("(%p)->(0x%lx, %u, %p, %s) - stub\n", This, flags, period_frames, format, debugstr_guid(session_guid)); - return E_NOTIMPL; + REFERENCE_TIME duration; + FIXME("(%p)->(0x%lx, %u, %p, %s) - partial stub\n", This, flags, period_frames, format, debugstr_guid(session_guid)); + + if (!format) + return E_POINTER; + + duration = period_frames * (REFERENCE_TIME)10000000 / format->nSamplesPerSec; + return client_Initialize(iface, AUDCLNT_SHAREMODE_SHARED, flags, duration, 0, format, session_guid); }
const IAudioClient3Vtbl AudioClient3_Vtbl = diff --git a/dlls/mmdevapi/tests/render.c b/dlls/mmdevapi/tests/render.c index fb346958437..bbd766c0bfc 100644 --- a/dlls/mmdevapi/tests/render.c +++ b/dlls/mmdevapi/tests/render.c @@ -330,12 +330,10 @@ static void test_audioclient(void)
hr = IAudioClient3_GetSharedModeEnginePeriod( ac3, pwfx, &default_period, &unit_period, &min_period, &max_period); - todo_wine ok(hr == S_OK, "GetSharedModeEnginePeriod returns %08lx\n", hr);
hr = IAudioClient3_InitializeSharedAudioStream( ac3, AUDCLNT_SHAREMODE_SHARED, default_period, pwfx, NULL); - todo_wine ok(hr == S_OK, "InitializeSharedAudioStream returns %08lx\n", hr);
IAudioClient3_Release(ac3);
From: David McFarland corngood@gmail.com
--- dlls/mmdevapi/tests/Makefile.in | 1 + dlls/mmdevapi/tests/devicetopology.c | 104 +++++++++++++++++++++++++++ 2 files changed, 105 insertions(+) create mode 100644 dlls/mmdevapi/tests/devicetopology.c
diff --git a/dlls/mmdevapi/tests/Makefile.in b/dlls/mmdevapi/tests/Makefile.in index dd180a253b9..b63bd47043f 100644 --- a/dlls/mmdevapi/tests/Makefile.in +++ b/dlls/mmdevapi/tests/Makefile.in @@ -4,6 +4,7 @@ IMPORTS = ole32 version user32 advapi32 winmm C_SRCS = \ capture.c \ dependency.c \ + devicetopology.c \ mmdevenum.c \ propstore.c \ render.c \ diff --git a/dlls/mmdevapi/tests/devicetopology.c b/dlls/mmdevapi/tests/devicetopology.c new file mode 100644 index 00000000000..9762bae2d57 --- /dev/null +++ b/dlls/mmdevapi/tests/devicetopology.c @@ -0,0 +1,104 @@ +/* + * 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 + */ + +#include <math.h> +#include <stdio.h> + +#include "wine/test.h" + +#define COBJMACROS + +#include "mmdeviceapi.h" +#include "devicetopology.h" +#include "mmsystem.h" + +static IMMDeviceEnumerator *mme = NULL; +static IMMDevice *dev = NULL; +static IDeviceTopology *dt = NULL; + +static void test_connectors(void) +{ + HRESULT hr; + UINT connector_count; + + hr = IDeviceTopology_GetConnectorCount(dt, &connector_count); + ok(hr == S_OK, "GetConnectorCount returns 0x%08lx\n", hr); + trace("connector count: %u\n", connector_count); + + if (hr == S_OK && connector_count > 0) + { + IConnector *connector; + + hr = IDeviceTopology_GetConnector(dt, 0, &connector); + ok(hr == S_OK, "GetConnector returns 0x%08lx\n", hr); + + if (hr == S_OK) + { + ConnectorType type; + + hr = IConnector_GetType(connector, &type); + ok(hr == S_OK, "GetConnector returns 0x%08lx\n", hr); + trace("connector 0 type: %u\n", connector_count); + } + } +} + +START_TEST(devicetopology) +{ + HRESULT hr; + + CoInitializeEx(NULL, COINIT_MULTITHREADED); + hr = CoCreateInstance(&CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, &IID_IMMDeviceEnumerator, (void**)&mme); + if (FAILED(hr)) + { + skip("mmdevapi not available: 0x%08lx\n", hr); + goto cleanup; + } + + hr = IMMDeviceEnumerator_GetDefaultAudioEndpoint(mme, eRender, eMultimedia, &dev); + ok(hr == S_OK || hr == E_NOTFOUND, "GetDefaultAudioEndpoint failed: 0x%08lx\n", hr); + if (hr != S_OK || !dev) + { + if (hr == E_NOTFOUND) + win_skip("No sound card available\n"); + else + skip("GetDefaultAudioEndpoint returns 0x%08lx\n", hr); + goto cleanup; + } + + hr = IMMDevice_Activate(dev, &IID_IDeviceTopology, CLSCTX_INPROC_SERVER, NULL, (void**)&dt); + ok(hr == S_OK || hr == E_NOINTERFACE, "IDeviceTopology Activation failed: 0x%08lx\n", hr); + 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); + goto cleanup; + } + + test_connectors(); + + IDeviceTopology_Release(dt); + +cleanup: + if (dev) + IMMDevice_Release(dev); + if (mme) + IMMDeviceEnumerator_Release(mme); + CoUninitialize(); +}
From: David McFarland corngood@gmail.com
--- dlls/mmdevapi/Makefile.in | 1 + dlls/mmdevapi/devenum.c | 2 +- dlls/mmdevapi/devicetopology.c | 322 +++++++++++++++++++++++++++ dlls/mmdevapi/mmdevapi_private.h | 1 + dlls/mmdevapi/tests/devicetopology.c | 1 - 5 files changed, 325 insertions(+), 2 deletions(-) create mode 100644 dlls/mmdevapi/devicetopology.c
diff --git a/dlls/mmdevapi/Makefile.in b/dlls/mmdevapi/Makefile.in index d9ec97b87e5..a380e28f61d 100644 --- a/dlls/mmdevapi/Makefile.in +++ b/dlls/mmdevapi/Makefile.in @@ -6,6 +6,7 @@ C_SRCS = \ audiovolume.c \ client.c \ devenum.c \ + devicetopology.c \ main.c \ session.c \ spatialaudio.c diff --git a/dlls/mmdevapi/devenum.c b/dlls/mmdevapi/devenum.c index 2900d222795..5077da64466 100644 --- a/dlls/mmdevapi/devenum.c +++ b/dlls/mmdevapi/devenum.c @@ -689,7 +689,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)) diff --git a/dlls/mmdevapi/devicetopology.c b/dlls/mmdevapi/devicetopology.c new file mode 100644 index 00000000000..e23701695c9 --- /dev/null +++ b/dlls/mmdevapi/devicetopology.c @@ -0,0 +1,322 @@ +/* + * 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 <audiopolicy.h> +#include <mmdeviceapi.h> + +#include <wine/debug.h> + +#include "mmdevapi_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi); + +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 0ed9140c3ed..b96e99df96f 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) DECLSPEC_HIDDEN; extern HRESULT AudioSessionManager_Create(IMMDevice *device, IAudioSessionManager2 **ppv) DECLSPEC_HIDDEN; extern HRESULT SpatialAudioClient_Create(IMMDevice *device, ISpatialAudioClient **out) DECLSPEC_HIDDEN; +extern HRESULT DeviceTopology_Create(IMMDevice *device, IDeviceTopology **out) DECLSPEC_HIDDEN;
extern HRESULT load_devices_from_reg(void) DECLSPEC_HIDDEN; extern HRESULT load_driver_devices(EDataFlow flow) DECLSPEC_HIDDEN; diff --git a/dlls/mmdevapi/tests/devicetopology.c b/dlls/mmdevapi/tests/devicetopology.c index 9762bae2d57..e9f576f5007 100644 --- a/dlls/mmdevapi/tests/devicetopology.c +++ b/dlls/mmdevapi/tests/devicetopology.c @@ -84,7 +84,6 @@ START_TEST(devicetopology) 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);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=136765
Your paranoid android.
=== w1064v1507 (32 bit report) ===
mmdevapi: render.c:1360: Test failed: GetBuffer large (20671) at iteration 5
=== w1064_tsign (32 bit report) ===
mmdevapi: render.c:1360: Test failed: GetBuffer large (22500) at iteration 2 render.c:1360: Test failed: GetBuffer large (22500) at iteration 4
=== w1064_adm (64 bit report) ===
mmdevapi: render.c:1360: Test failed: GetBuffer large (22500) at iteration 7
Jeffrey Smith (@whydoubt) commented about dlls/mmdevapi/devicetopology.c:
+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);
The other files in mmdevapi have recently been changed to use CRT allocation functions (malloc, free, etc.), so you should follow suit here. ```suggestion:-0+0 free(This); ```
Jeffrey Smith (@whydoubt) commented about dlls/mmdevapi/devicetopology.c:
- 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));
```suggestion:-0+0 This = calloc(1, sizeof(*This)); ```
Jeffrey Smith (@whydoubt) commented about dlls/mmdevapi/devicetopology.c:
+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);
```suggestion:-0+0 free(This); ```
Jeffrey Smith (@whydoubt) commented about dlls/mmdevapi/devicetopology.c:
- 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));
```suggestion:-0+0 This = calloc(1, sizeof(*This)); ```