From d1cd6658c9668306fae3cc03ad3c6b6fd333b677 Mon Sep 17 00:00:00 2001 From: narzoul Date: Mon, 26 Aug 2019 22:58:00 +0200 Subject: [PATCH] Fixed deadlock in VirtualScreen::createSurface --- DDrawCompat/Common/ScopedCriticalSection.h | 14 ++-------- DDrawCompat/DDraw/RealPrimarySurface.cpp | 1 + .../DDraw/Surfaces/PrimarySurfaceImpl.cpp | 26 ++++++++++--------- DDrawCompat/Gdi/DcFunctions.cpp | 2 ++ DDrawCompat/Gdi/VirtualScreen.cpp | 1 + 5 files changed, 20 insertions(+), 24 deletions(-) diff --git a/DDrawCompat/Common/ScopedCriticalSection.h b/DDrawCompat/Common/ScopedCriticalSection.h index b31418a..2de93f9 100644 --- a/DDrawCompat/Common/ScopedCriticalSection.h +++ b/DDrawCompat/Common/ScopedCriticalSection.h @@ -24,27 +24,17 @@ namespace Compat { public: ScopedCriticalSection(CRITICAL_SECTION& cs) - : m_cs(cs), m_isLocked(true) + : m_cs(cs) { EnterCriticalSection(&m_cs); } ~ScopedCriticalSection() { - unlock(); - } - - void unlock() - { - if (m_isLocked) - { - LeaveCriticalSection(&m_cs); - m_isLocked = false; - } + LeaveCriticalSection(&m_cs); } private: CRITICAL_SECTION& m_cs; - bool m_isLocked; }; }; diff --git a/DDrawCompat/DDraw/RealPrimarySurface.cpp b/DDrawCompat/DDraw/RealPrimarySurface.cpp index 5a1ae9e..bd06e9d 100644 --- a/DDrawCompat/DDraw/RealPrimarySurface.cpp +++ b/DDrawCompat/DDraw/RealPrimarySurface.cpp @@ -62,6 +62,7 @@ namespace void bltToWindowViaGdi(Gdi::Region* primaryRegion) { + D3dDdi::ScopedCriticalSection lock; std::unique_ptr virtualScreenDc(nullptr, &Gdi::VirtualScreen::deleteDc); RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds(); diff --git a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp index a3fd69c..4b8a61e 100644 --- a/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/PrimarySurfaceImpl.cpp @@ -1,15 +1,16 @@ -#include "Common/CompatPtr.h" -#include "D3dDdi/KernelModeThunks.h" -#include "DDraw/DirectDrawClipper.h" -#include "DDraw/DirectDrawPalette.h" -#include "DDraw/DirectDrawSurface.h" -#include "DDraw/RealPrimarySurface.h" -#include "DDraw/Surfaces/PrimarySurface.h" -#include "DDraw/Surfaces/PrimarySurfaceImpl.h" -#include "Dll/Procs.h" -#include "Gdi/Gdi.h" -#include "Gdi/Region.h" -#include "Gdi/VirtualScreen.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include namespace { @@ -29,6 +30,7 @@ namespace return; } + D3dDdi::ScopedCriticalSection lock; Gdi::Region clipRgn(DDraw::DirectDrawClipper::getClipRgn(*clipper)); RECT monitorRect = D3dDdi::KernelModeThunks::getMonitorRect(); RECT virtualScreenBounds = Gdi::VirtualScreen::getBounds(); diff --git a/DDrawCompat/Gdi/DcFunctions.cpp b/DDrawCompat/Gdi/DcFunctions.cpp index 5e1355e..d710575 100644 --- a/DDrawCompat/Gdi/DcFunctions.cpp +++ b/DDrawCompat/Gdi/DcFunctions.cpp @@ -104,6 +104,7 @@ namespace if (hasDisplayDcArg(params...)) { + D3dDdi::ScopedCriticalSection lock; const bool isReadOnlyAccess = !hasDisplayDcArg(getDestinationDc(params...)); Gdi::AccessGuard accessGuard(isReadOnlyAccess ? Gdi::ACCESS_READ : Gdi::ACCESS_WRITE); return LOG_RESULT(Compat::getOrigFuncPtr()(replaceDc(params)...)); @@ -140,6 +141,7 @@ namespace } else { + D3dDdi::ScopedCriticalSection lock; Gdi::AccessGuard accessGuard(Gdi::ACCESS_WRITE); return LOG_RESULT(CALL_ORIG_FUNC(ExtTextOutW)(replaceDc(hdc), x, y, options, lprect, lpString, c, lpDx)); } diff --git a/DDrawCompat/Gdi/VirtualScreen.cpp b/DDrawCompat/Gdi/VirtualScreen.cpp index 6ad05c2..b952f15 100644 --- a/DDrawCompat/Gdi/VirtualScreen.cpp +++ b/DDrawCompat/Gdi/VirtualScreen.cpp @@ -121,6 +121,7 @@ namespace Gdi CompatPtr createSurface(const RECT& rect) { DDraw::ScopedThreadLock ddLock; + D3dDdi::ScopedCriticalSection driverLock; Compat::ScopedCriticalSection lock(g_cs); auto desc = getSurfaceDesc(rect);