From 170ce6e6e8008f05dfaf13c94aa0a240f1e1ddd1 Mon Sep 17 00:00:00 2001 From: Richard Stanway Date: Fri, 31 Jul 2026 21:20:39 +0200 Subject: [PATCH] virtualcam-module: Improve lock tracking for DLL unloading The locks variable is used to determine if the DLL can safely be unloaded. If we're in the middle of constructing a VCamFilter, we don't want something to unload us half-way through so incrementing locks and reference count should be the first thing we do. Clients can also get a reference to VCamFactory which had no lock tracking at all, so the DLL could potentially be unloaded while still having outstanding VCamFactory references, causing a crash the next time the VCamFactory was used. --- plugins/win-dshow/virtualcam-module/virtualcam-filter.cpp | 6 +++--- plugins/win-dshow/virtualcam-module/virtualcam-module.cpp | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/win-dshow/virtualcam-module/virtualcam-filter.cpp b/plugins/win-dshow/virtualcam-module/virtualcam-filter.cpp index b39a91be15f8f0..6b128736754c53 100644 --- a/plugins/win-dshow/virtualcam-module/virtualcam-filter.cpp +++ b/plugins/win-dshow/virtualcam-module/virtualcam-filter.cpp @@ -16,6 +16,9 @@ extern volatile long locks; VCamFilter::VCamFilter() : OutputFilter() { + os_atomic_inc_long(&locks); + AddRef(); + thread_start = CreateEvent(nullptr, true, false, nullptr); thread_stop = CreateEvent(nullptr, true, false, nullptr); @@ -94,9 +97,6 @@ VCamFilter::VCamFilter() : OutputFilter() /* ---------------------------------------- */ th = std::thread([this] { Thread(); }); - - AddRef(); - os_atomic_inc_long(&locks); } VCamFilter::~VCamFilter() diff --git a/plugins/win-dshow/virtualcam-module/virtualcam-module.cpp b/plugins/win-dshow/virtualcam-module/virtualcam-module.cpp index 23e0ee4240b7a4..5d6eac2ce9f2fb 100644 --- a/plugins/win-dshow/virtualcam-module/virtualcam-module.cpp +++ b/plugins/win-dshow/virtualcam-module/virtualcam-module.cpp @@ -17,7 +17,8 @@ class VCamFactory : public IClassFactory { CLSID cls; public: - inline VCamFactory(CLSID cls_) : cls(cls_) {} + inline VCamFactory(CLSID cls_) : cls(cls_) { os_atomic_inc_long(&locks); } + inline ~VCamFactory() { os_atomic_dec_long(&locks); } // IUnknown STDMETHODIMP QueryInterface(REFIID riid, void **p_ptr);