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 }
@@ -406,7 +392,7 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
406392 AddReportLog (8755 , SStringX (" CProxyDirect3D9::CreateDevice - driver returned nullptr device" ), 5 );
407393 hResult = D3DERR_INVALIDDEVICE;
408394 }
409- else if (!IsValidComInterfacePointer (pCreatedDevice))
395+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
410396 {
411397 SString message;
412398 message.Format (" CProxyDirect3D9::CreateDevice - rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -441,7 +427,7 @@ HRESULT CProxyDirect3D9::CreateDevice(UINT Adapter, D3DDEVTYPE DeviceType, HWND
441427 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
442428 if (pOriginalDevice)
443429 {
444- if (IsValidComInterfacePointer (pOriginalDevice))
430+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
445431 {
446432 pOriginalDevice->Release ();
447433 }
@@ -620,7 +606,7 @@ HRESULT CreateDeviceInsist(uint uiMinTries, uint uiTimeout, IDirect3D9* pDirect3
620606 AddReportLog (8755 , SStringX (" CreateDeviceInsist: driver returned nullptr device" ), 5 );
621607 hResult = D3DERR_INVALIDDEVICE;
622608 }
623- else if (!IsValidComInterfacePointer (pCreatedDevice))
609+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
624610 {
625611 SString message;
626612 message.Format (" CreateDeviceInsist: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -842,15 +828,15 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
842828{
843829 HRESULT hr;
844830
845- if (!pDirect3D || !IsValidComInterfacePointer (pDirect3D))
831+ if (!pDirect3D || !IsValidComInterfacePointer (pDirect3D, ComPtrValidation::ValidationMode::ForceRefresh ))
846832 {
847833 SString message;
848834 message.Format (" AddCapsReport: invalid IDirect3D9 pointer %p" , pDirect3D);
849835 AddReportLog (8748 , message);
850836 return ;
851837 }
852838
853- if (!pD3DDevice9 || !IsValidComInterfacePointer (pD3DDevice9))
839+ if (!pD3DDevice9 || !IsValidComInterfacePointer (pD3DDevice9, ComPtrValidation::ValidationMode::ForceRefresh ))
854840 {
855841 SString message;
856842 message.Format (" AddCapsReport: invalid IDirect3DDevice9 pointer %p" , pD3DDevice9);
@@ -870,7 +856,7 @@ void AddCapsReport(UINT Adapter, IDirect3D9* pDirect3D, IDirect3DDevice9* pD3DDe
870856 // Check device returns same D3D interface
871857 IDirect3D9* pDirect3DOther = NULL ;
872858 pD3DDevice9->GetDirect3D (&pDirect3DOther);
873- if (pDirect3DOther && !IsValidComInterfacePointer (pDirect3DOther))
859+ if (pDirect3DOther && !IsValidComInterfacePointer (pDirect3DOther, ComPtrValidation::ValidationMode::ForceRefresh ))
874860 {
875861 SString message;
876862 message.Format (" AddCapsReport: device returned invalid IDirect3D9 pointer %p" , pDirect3DOther);
@@ -1077,7 +1063,7 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad
10771063 AddReportLog (8755 , SStringX (" HandleCreateDeviceResult: DoCreateDevice returned nullptr device" ), 5 );
10781064 hResult = D3DERR_INVALIDDEVICE;
10791065 }
1080- else if (!IsValidComInterfacePointer (pCreatedDevice))
1066+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
10811067 {
10821068 SString message;
10831069 message.Format (" HandleCreateDeviceResult: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice);
@@ -1117,7 +1103,7 @@ HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Ad
11171103 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
11181104 if (pOriginalDevice)
11191105 {
1120- if (IsValidComInterfacePointer (pOriginalDevice))
1106+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
11211107 {
11221108 pOriginalDevice->Release ();
11231109 }
@@ -1270,7 +1256,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
12701256 return hResult;
12711257 }
12721258
1273- if (!IsValidComInterfacePointer (*ppReturnedDeviceInterface))
1259+ if (!IsValidComInterfacePointer (*ppReturnedDeviceInterface, ComPtrValidation::ValidationMode::ForceRefresh ))
12741260 {
12751261 SString message;
12761262 message.Format (" CCore::OnPostCreateDevice - invalid IDirect3DDevice9 pointer %p (via %p)" , *ppReturnedDeviceInterface, ppReturnedDeviceInterface);
@@ -1333,7 +1319,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
13331319 " CCore::OnPostCreateDevice: CreateDeviceInsist returned nullptr device" , 5 );
13341320 hResult = D3DERR_INVALIDDEVICE;
13351321 }
1336- else if (!IsValidComInterfacePointer (pCreatedDevice))
1322+ else if (!IsValidComInterfacePointer (pCreatedDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
13371323 {
13381324 AddReportLog (8755 ,
13391325 SString (" CCore::OnPostCreateDevice: rejected invalid IDirect3DDevice9 pointer %p" , pCreatedDevice), 5 );
@@ -1388,7 +1374,7 @@ HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT A
13881374 *ppReturnedDeviceInterface = new CProxyDirect3DDevice9 (pOriginalDevice);
13891375 if (pOriginalDevice)
13901376 {
1391- if (IsValidComInterfacePointer (pOriginalDevice))
1377+ if (IsValidComInterfacePointer (pOriginalDevice, ComPtrValidation::ValidationMode::ForceRefresh ))
13921378 {
13931379 pOriginalDevice->Release ();
13941380 }
0 commit comments