1010 *****************************************************************************/
1111
1212#include " StdInc.h"
13+ #include " ComPtrValidation.h"
1314#include < dwmapi.h>
1415#include < resource.h>
1516
1617extern HINSTANCE g_hModule;
1718
1819namespace
1920{
20- template <typename T>
21- bool IsValidComInterfacePointer (T* pointer)
22- {
23- if (!pointer)
24- return true ;
25-
26- if (!SharedUtil::IsReadablePointer (pointer, sizeof (void *)))
27- return false ;
28-
29- void * const * vtablePtr = reinterpret_cast <void * const *>(pointer);
30- if (!vtablePtr)
31- return false ;
32-
33- void * const vtable = *vtablePtr;
34- if (!vtable)
35- return false ;
36-
37- constexpr size_t requiredBytes = sizeof (void *) * 3 ;
38- return SharedUtil::IsReadablePointer (vtable, requiredBytes);
39- }
40-
4121template <typename T>
4222void ReleaseInterface (T*& pointer, const char * context = nullptr )
4323{
4424 if (!pointer)
4525 return ;
4626
47- if (IsValidComInterfacePointer (pointer))
27+ T* heldPointer = pointer;
28+
29+ const bool valid = IsValidComInterfacePointer (pointer, ComPtrValidation::ValidationMode::ForceRefresh);
30+
31+ if (valid)
4832 {
49- pointer ->Release ();
33+ heldPointer ->Release ();
5034 }
5135 else
5236 {
53- SString label;
54- label = context ? context : " ReleaseInterface" ;
37+ SString label;
38+ label = context ? context : " ReleaseInterface" ;
5539 SString message;
56- message.Format (" %s: skipping Release on invalid COM pointer %p" , label.c_str (), pointer );
40+ message.Format (" %s: skipping Release on invalid COM pointer %p" , label.c_str (), heldPointer );
5741 AddReportLog (8752 , message, 5 );
42+ ComPtrValidation::Invalidate (heldPointer);
5843 }
5944
6045 pointer = nullptr ;
@@ -66,10 +51,10 @@ void ReplaceInterface(T*& destination, T* source, const char* context = nullptr)
6651 if (destination == source)
6752 return ;
6853
69- if (source && !IsValidComInterfacePointer (source))
54+ if (source && !IsValidComInterfacePointer (source, ComPtrValidation::ValidationMode::ForceRefresh ))
7055 {
71- SString label;
72- label = context ? context : " ReplaceInterface" ;
56+ SString label;
57+ label = context ? context : " ReplaceInterface" ;
7358 SString message;
7459 message.Format (" %s: rejected invalid COM pointer %p" , label.c_str (), source);
7560 AddReportLog (8753 , message, 5 );
@@ -87,18 +72,19 @@ IDirect3D9* GetFirstValidTrackedDirect3D(std::vector<IDirect3D9*>& trackedList)
8772 for (auto iter = trackedList.begin (); iter != trackedList.end ();)
8873 {
8974 IDirect3D9* candidate = *iter;
90- if (candidate && IsValidComInterfacePointer (candidate))
75+ if (candidate && IsValidComInterfacePointer (candidate, ComPtrValidation::ValidationMode::ForceRefresh ))
9176 return candidate;
9277
9378 SString message;
9479 message.Format (" CProxyDirect3D9: removing invalid tracked IDirect3D9 pointer %p" , candidate);
9580 AddReportLog (8756 , message, 5 );
81+ ComPtrValidation::Invalidate (candidate);
9682 iter = trackedList.erase (iter);
9783 }
9884
9985 return nullptr ;
10086}
101- } // namespace
87+ } // unnamed namespace
10288
10389HRESULT HandleCreateDeviceResult (HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
10490 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface);
@@ -113,7 +99,7 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
11399{
114100 WriteDebugEvent (SString (" CProxyDirect3D9::CProxyDirect3D9 %08x" , this ));
115101
116- if (!IsValidComInterfacePointer (pInterface))
102+ if (!IsValidComInterfacePointer (pInterface, ComPtrValidation::ValidationMode::ForceRefresh ))
117103 {
118104 SString message;
119105 message.Format (" CProxyDirect3D9 ctor: received invalid IDirect3D9 pointer %p" , pInterface);
@@ -128,7 +114,7 @@ CProxyDirect3D9::CProxyDirect3D9(IDirect3D9* pInterface)
128114
129115 if (m_pDevice)
130116 {
131- if (IsValidComInterfacePointer (m_pDevice))
117+ if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
132118 {
133119 ms_CreatedDirect3D9List.push_back (m_pDevice);
134120 }
@@ -151,11 +137,11 @@ CProxyDirect3D9::~CProxyDirect3D9()
151137/* ** IUnknown methods ***/
152138HRESULT CProxyDirect3D9::QueryInterface (REFIID riid, void ** ppvObj)
153139{
154- if (!m_pDevice || !IsValidComInterfacePointer (m_pDevice))
140+ if (!m_pDevice || !IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
155141 {
156- SString message;
157- message.Format (" CProxyDirect3D9::QueryInterface rejected invalid IDirect3D9 pointer %p" , m_pDevice);
158- AddReportLog (8752 , message, 5 );
142+ SString message;
143+ message.Format (" CProxyDirect3D9::QueryInterface rejected invalid IDirect3D9 pointer %p" , m_pDevice);
144+ AddReportLog (8752 , message, 5 );
159145 if (ppvObj)
160146 *ppvObj = nullptr ;
161147 return E_POINTER;
@@ -170,14 +156,14 @@ ULONG CProxyDirect3D9::AddRef()
170156
171157 if (m_pDevice)
172158 {
173- if (IsValidComInterfacePointer (m_pDevice))
159+ if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
174160 {
175161 m_pDevice->AddRef ();
176162 }
177163 else
178164 {
179165 SString message;
180- message.Format (" CProxyDirect3D9::AddRef skipped underlying AddRef; invalid pointer %p" , m_pDevice);
166+ message.Format (" CProxyDirect3D9::AddRef rejected invalid IDirect3D9 pointer %p" , m_pDevice);
181167 AddReportLog (8752 , message, 5 );
182168 }
183169 }
@@ -191,22 +177,22 @@ ULONG CProxyDirect3D9::Release()
191177
192178 if (lNewRefCount < 0 )
193179 {
194- SString message;
195- message.Format (" CProxyDirect3D9::Release detected reference count underflow for proxy %p" , this );
196- AddReportLog (8752 , message, 5 );
180+ SString message;
181+ message.Format (" CProxyDirect3D9::Release detected reference count underflow for proxy %p" , this );
182+ AddReportLog (8752 , message, 5 );
197183 lNewRefCount = 0 ;
198184 }
199185
200186 if (m_pDevice && lNewRefCount > 0 )
201187 {
202- if (IsValidComInterfacePointer (m_pDevice))
188+ if (IsValidComInterfacePointer (m_pDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
203189 {
204190 m_pDevice->Release ();
205191 }
206192 else
207193 {
208194 SString message;
209- message.Format (" CProxyDirect3D9::Release skipped underlying Release; invalid pointer %p" , m_pDevice);
195+ message.Format (" CProxyDirect3D9::Release rejected invalid IDirect3D9 pointer %p" , m_pDevice);
210196 AddReportLog (8752 , message, 5 );
211197 }
212198 }
@@ -393,7 +379,7 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
393379 AddReportLog (8755 , SStringX (" CProxyDirect3D9::CreateDevice - driver returned nullptr device" ), 5 );
394380 hResult = D3DERR_INVALIDDEVICE;
395381 }
396- else if (!IsValidComInterfacePointer (pCreatedDevice))
382+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
397383 {
398384 SString message;
399385 message.Format (" CProxyDirect3D9::CreateDevice - rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -428,7 +414,7 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
428414 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
429415 if (pOriginalDevice)
430416 {
431- if (IsValidComInterfacePointer (pOriginalDevice))
417+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
432418 {
433419 pOriginalDevice->Release ();
434420 }
@@ -607,7 +593,7 @@ HRESULT CreateDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3D9* pDirect3
607593 AddReportLog (8755 , SStringX (" CreateDeviceInsist: driver returned nullptr device" ), 5 );
608594 hResult = D3DERR_INVALIDDEVICE;
609595 }
610- else if (!IsValidComInterfacePointer (pCreatedDevice))
596+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
611597 {
612598 SString message;
613599 message.Format (" CreateDeviceInsist: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -829,15 +815,15 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
829815{
830816 HRESULT hr;
831817
832- if (!pDirect3D || !IsValidComInterfacePointer (pDirect3D))
818+ if (!pDirect3D || !IsValidComInterfacePointer (pDirect3D, ComPtrValidation::ValidationMode::ForceRefresh ))
833819 {
834820 SString message;
835821 message.Format (" AddCapsReport: invalid IDirect3D9 pointer %p" , pDirect3D);
836822 AddReportLog (8748 , message);
837823 return ;
838824 }
839825
840- if (!pD3DDevice9 || !IsValidComInterfacePointer (pD3DDevice9))
826+ if (!pD3DDevice9 || !IsValidComInterfacePointer (pD3DDevice9, ComPtrValidation::ValidationMode::ForceRefresh ))
841827 {
842828 SString message;
843829 message.Format (" AddCapsReport: invalid IDirect3DDevice9 pointer %p" , pD3DDevice9);
@@ -857,7 +843,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
857843 // Check device returns same D3D interface
858844 IDirect3D9* pDirect3DOther = NULL ;
859845 pD3DDevice9->GetDirect3D (&pDirect3DOther);
860- if (pDirect3DOther && !IsValidComInterfacePointer (pDirect3DOther))
846+ if (pDirect3DOther && !IsValidComInterfacePointer (pDirect3DOther, ComPtrValidation::ValidationMode::ForceRefresh ))
861847 {
862848 SString message;
863849 message.Format (" AddCapsReport: device returned invalid IDirect3D9 pointer %p" , pDirect3DOther);
@@ -1064,7 +1050,7 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad
10641050 AddReportLog (8755 , SStringX (" HandleCreateDeviceResult: DoCreateDevice returned nullptr device" ), 5 );
10651051 hResult = D3DERR_INVALIDDEVICE;
10661052 }
1067- else if (!IsValidComInterfacePointer (pCreatedDevice))
1053+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
10681054 {
10691055 SString message;
10701056 message.Format (" HandleCreateDeviceResult: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -1104,7 +1090,7 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad
11041090 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
11051091 if (pOriginalDevice)
11061092 {
1107- if (IsValidComInterfacePointer (pOriginalDevice))
1093+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
11081094 {
11091095 pOriginalDevice->Release ();
11101096 }
@@ -1264,7 +1250,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
12641250 return hResult;
12651251 }
12661252
1267- if (!IsValidComInterfacePointer (*ppReturnedDeviceInterface))
1253+ if (!IsValidComInterfacePointer (*ppReturnedDeviceInterface, ComPtrValidation::ValidationMode::ForceRefresh ))
12681254 {
12691255 SString message;
12701256 message.Format (" CCore::OnPostCreateDevice - invalid IDirect3DDevice9 pointer %p (via %p)" , *ppReturnedDeviceInterface, ppReturnedDeviceInterface);
@@ -1327,7 +1313,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
13271313 " CCore::OnPostCreateDevice: CreateDeviceInsist returned nullptr device" , 5 );
13281314 hResult = D3DERR_INVALIDDEVICE;
13291315 }
1330- else if (!IsValidComInterfacePointer (pCreatedDevice))
1316+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
13311317 {
13321318 AddReportLog (8755 ,
13331319 SString (" CCore::OnPostCreateDevice: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice), 5 );
@@ -1382,7 +1368,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
13821368 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
13831369 if (pOriginalDevice)
13841370 {
1385- if (IsValidComInterfacePointer (pOriginalDevice))
1371+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
13861372 {
13871373 pOriginalDevice->Release ();
13881374 }
0 commit comments