diff options
author | Vladimir Belyavsky <belyavskyv@gmail.com> | 2023-11-02 11:46:32 +0300 |
---|---|---|
committer | Vladimir Belyavsky <belyavskyv@gmail.com> | 2023-11-07 11:57:22 +0000 |
commit | 963fefe80ab1ceb686928b733a7d60b250c73823 (patch) | |
tree | 369213608feb0fb0054b12bdccaec3fd6cb350f6 | |
parent | 50a591426bad1ba6211674c93626bc8b72448ac8 (diff) |
QWindowsMediaDevices: fix potential nullptr access
Fix potential crash in QWindowsMediaDevices::availableDevices()
due to nullptr access to m_deviceEnumerator. This may happen in
case where m_deviceEnumerator instantiation was failed by some
reason in QWindowsMediaDevices constructor. Also make the warning
in such situations more informative.
Fixes: QTBUG-118706
Pick-to: 6.5
Change-Id: I60c7fab3ea13f6f576de89f184c1bf9cd80579c4
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
(cherry picked from commit cf96c6862fe9b46a8d9fbad9494b04c9d3c7e644)
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
-rw-r--r-- | src/multimedia/windows/qwindowsmediadevices.cpp | 53 |
1 files changed, 29 insertions, 24 deletions
diff --git a/src/multimedia/windows/qwindowsmediadevices.cpp b/src/multimedia/windows/qwindowsmediadevices.cpp index 1b1ad194c..d7728370c 100644 --- a/src/multimedia/windows/qwindowsmediadevices.cpp +++ b/src/multimedia/windows/qwindowsmediadevices.cpp @@ -19,6 +19,7 @@ #include <qwindowsmfdefs_p.h> #include <QtCore/qmap.h> +#include <private/qsystemerror_p.h> QT_BEGIN_NAMESPACE @@ -155,35 +156,36 @@ QWindowsMediaDevices::QWindowsMediaDevices() CLSCTX_INPROC_SERVER,__uuidof(IMMDeviceEnumerator), (void**)&m_deviceEnumerator); - if (SUCCEEDED(hr)) { - QMap<QString, DWORD> devState; - ComPtr<IMMDeviceCollection> devColl; - UINT count = 0; + if (FAILED(hr)) { + qWarning("Failed to instantiate IMMDeviceEnumerator (%s)." + "Audio device change notification will be disabled", + qPrintable(QSystemError::windowsComString(hr))); + return; + } - if (SUCCEEDED(m_deviceEnumerator->EnumAudioEndpoints(EDataFlow::eAll, DEVICE_STATEMASK_ALL, devColl.GetAddressOf())) - && SUCCEEDED(devColl->GetCount(&count))) - { - for (UINT i = 0; i < count; i++) { - ComPtr<IMMDevice> device; - DWORD state = 0; - QComTaskResource<WCHAR> id; - - if (SUCCEEDED(devColl->Item(i, device.GetAddressOf())) - && SUCCEEDED(device->GetState(&state)) - && SUCCEEDED(device->GetId(id.address()))) { - devState.insert(QString::fromWCharArray(id.get()), state); - } + QMap<QString, DWORD> devState; + ComPtr<IMMDeviceCollection> devColl; + UINT count = 0; + + if (SUCCEEDED(m_deviceEnumerator->EnumAudioEndpoints(EDataFlow::eAll, DEVICE_STATEMASK_ALL, devColl.GetAddressOf())) + && SUCCEEDED(devColl->GetCount(&count))) + { + for (UINT i = 0; i < count; i++) { + ComPtr<IMMDevice> device; + DWORD state = 0; + QComTaskResource<WCHAR> id; + + if (SUCCEEDED(devColl->Item(i, device.GetAddressOf())) + && SUCCEEDED(device->GetState(&state)) + && SUCCEEDED(device->GetId(id.address()))) { + devState.insert(QString::fromWCharArray(id.get()), state); } } + } - m_notificationClient = - makeComObject<CMMNotificationClient>(this, m_deviceEnumerator, std::move(devState)); - m_deviceEnumerator->RegisterEndpointNotificationCallback(m_notificationClient.Get()); - - } else { - qWarning() << "Audio device change notification disabled"; - } + m_notificationClient = makeComObject<CMMNotificationClient>(this, m_deviceEnumerator, std::move(devState)); + m_deviceEnumerator->RegisterEndpointNotificationCallback(m_notificationClient.Get()); } QWindowsMediaDevices::~QWindowsMediaDevices() @@ -207,6 +209,9 @@ QWindowsMediaDevices::~QWindowsMediaDevices() QList<QAudioDevice> QWindowsMediaDevices::availableDevices(QAudioDevice::Mode mode) const { + if (!m_deviceEnumerator) + return {}; + const auto audioOut = mode == QAudioDevice::Output; const auto defaultAudioDeviceID = [this, audioOut]{ |