summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVladimir Belyavsky <belyavskyv@gmail.com>2023-11-02 11:46:32 +0300
committerVladimir Belyavsky <belyavskyv@gmail.com>2023-11-07 11:57:22 +0000
commit963fefe80ab1ceb686928b733a7d60b250c73823 (patch)
tree369213608feb0fb0054b12bdccaec3fd6cb350f6
parent50a591426bad1ba6211674c93626bc8b72448ac8 (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.cpp53
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]{