Workaround to fix crash in applications with invalid use of DXGI.

This commit is contained in:
s.makeev_local
2017-06-06 17:04:38 +03:00
committed by baldurk
parent ba61697adf
commit 410d3b2c02
2 changed files with 313 additions and 7 deletions
+113 -3
View File
@@ -204,7 +204,7 @@ HRESULT RefCountDXGIObject::WrapQueryInterface(IUnknown *real, REFIID riid, void
}
WrappedIDXGISwapChain4::WrappedIDXGISwapChain4(IDXGISwapChain *real, HWND wnd, ID3DDevice *device)
: RefCountDXGIObject(real), m_pReal(real), m_pDevice(device), m_iRefcount(1), m_Wnd(wnd)
: RefCountDXGIObject(real), m_pReal(real), m_pDevice(device), m_Wnd(wnd)
{
DXGI_SWAP_CHAIN_DESC desc;
real->GetDesc(&desc);
@@ -532,8 +532,118 @@ HRESULT WrappedIDXGISwapChain4::Present1(UINT SyncInterval, UINT Flags,
return m_pReal1->Present1(SyncInterval, Flags, pPresentParameters);
}
WrappedIDXGIOutput5::WrappedIDXGIOutput5(RefCountDXGIObject *owner, IDXGIOutput *real)
: RefCountDXGIObject(real), m_Owner(owner), m_pReal(real)
{
SAFE_ADDREF(m_Owner);
m_pReal1 = NULL;
real->QueryInterface(__uuidof(IDXGIOutput1), (void **)&m_pReal1);
m_pReal2 = NULL;
real->QueryInterface(__uuidof(IDXGIOutput2), (void **)&m_pReal2);
m_pReal3 = NULL;
real->QueryInterface(__uuidof(IDXGIOutput3), (void **)&m_pReal3);
m_pReal4 = NULL;
real->QueryInterface(__uuidof(IDXGIOutput4), (void **)&m_pReal4);
m_pReal5 = NULL;
real->QueryInterface(__uuidof(IDXGIOutput5), (void **)&m_pReal5);
}
WrappedIDXGIOutput5::~WrappedIDXGIOutput5()
{
SAFE_RELEASE(m_pReal1);
SAFE_RELEASE(m_pReal2);
SAFE_RELEASE(m_pReal3);
SAFE_RELEASE(m_pReal4);
SAFE_RELEASE(m_pReal5);
SAFE_RELEASE(m_pReal);
SAFE_RELEASE(m_Owner);
}
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput5::QueryInterface(REFIID riid, void **ppvObject)
{
if(riid == __uuidof(IDXGIOutput))
{
AddRef();
*ppvObject = (IDXGIOutput *)this;
return S_OK;
}
else if(riid == __uuidof(IDXGIOutput1))
{
if(m_pReal1)
{
AddRef();
*ppvObject = (IDXGIOutput1 *)this;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else if(riid == __uuidof(IDXGIOutput2))
{
if(m_pReal2)
{
AddRef();
*ppvObject = (IDXGIOutput2 *)this;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else if(riid == __uuidof(IDXGIOutput3))
{
if(m_pReal3)
{
AddRef();
*ppvObject = (IDXGIOutput3 *)this;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else if(riid == __uuidof(IDXGIOutput4))
{
if(m_pReal3)
{
AddRef();
*ppvObject = (IDXGIOutput4 *)this;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else if(riid == __uuidof(IDXGIOutput5))
{
if(m_pReal3)
{
AddRef();
*ppvObject = (IDXGIOutput5 *)this;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else
{
string guid = ToStr::Get(riid);
RDCWARN("Querying IDXGIOutput for interface: %s", guid.c_str());
}
return RefCountDXGIObject::QueryInterface(riid, ppvObject);
}
WrappedIDXGIAdapter3::WrappedIDXGIAdapter3(IDXGIAdapter *real)
: RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1)
: RefCountDXGIObject(real), m_pReal(real)
{
m_pReal1 = NULL;
real->QueryInterface(__uuidof(IDXGIAdapter1), (void **)&m_pReal1);
@@ -708,7 +818,7 @@ HRESULT STDMETHODCALLTYPE WrappedIDXGIDevice4::QueryInterface(REFIID riid, void
}
WrappedIDXGIFactory5::WrappedIDXGIFactory5(IDXGIFactory *real)
: RefCountDXGIObject(real), m_pReal(real), m_iRefcount(1)
: RefCountDXGIObject(real), m_pReal(real)
{
m_pReal1 = NULL;
real->QueryInterface(__uuidof(IDXGIFactory1), (void **)&m_pReal1);
+200 -4
View File
@@ -548,7 +548,6 @@ class WrappedIDXGISwapChain4 : public IDXGISwapChain4, public RefCountDXGIObject
IDXGISwapChain3 *m_pReal3;
IDXGISwapChain4 *m_pReal4;
ID3DDevice *m_pDevice;
unsigned int m_iRefcount;
static std::vector<D3DDeviceCallback> m_D3DCallbacks;
@@ -844,13 +843,206 @@ public:
}
};
class WrappedIDXGIOutput5 : public IDXGIOutput5, public RefCountDXGIObject
{
RefCountDXGIObject *m_Owner;
IDXGIOutput *m_pReal;
IDXGIOutput1 *m_pReal1;
IDXGIOutput2 *m_pReal2;
IDXGIOutput3 *m_pReal3;
IDXGIOutput4 *m_pReal4;
IDXGIOutput5 *m_pReal5;
public:
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
WrappedIDXGIOutput5(RefCountDXGIObject *owner, IDXGIOutput *real);
~WrappedIDXGIOutput5();
//////////////////////////////
// implement IDXGIOutput
virtual HRESULT STDMETHODCALLTYPE GetDesc(
/* [annotation][out] */
_Out_ DXGI_OUTPUT_DESC *pDesc)
{
return m_pReal->GetDesc(pDesc);
}
virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList(
/* [in] */ DXGI_FORMAT EnumFormat,
/* [in] */ UINT Flags,
/* [annotation][out][in] */
_Inout_ UINT *pNumModes,
/* [annotation][out] */
_Out_writes_to_opt_(*pNumModes, *pNumModes) DXGI_MODE_DESC *pDesc)
{
return m_pReal->GetDisplayModeList(EnumFormat, Flags, pNumModes, pDesc);
}
virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode(
/* [annotation][in] */
_In_ const DXGI_MODE_DESC *pModeToMatch,
/* [annotation][out] */
_Out_ DXGI_MODE_DESC *pClosestMatch,
/* [annotation][in] */
_In_opt_ IUnknown *pConcernedDevice)
{
return m_pReal->FindClosestMatchingMode(pModeToMatch, pClosestMatch, pConcernedDevice);
}
virtual HRESULT STDMETHODCALLTYPE WaitForVBlank(void) { return m_pReal->WaitForVBlank(); }
virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
/* [annotation][in] */
_In_ IUnknown *pDevice, BOOL Exclusive)
{
return m_pReal->TakeOwnership(pDevice, Exclusive);
}
virtual void STDMETHODCALLTYPE ReleaseOwnership(void) { return m_pReal->ReleaseOwnership(); }
virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
/* [annotation][out] */
_Out_ DXGI_GAMMA_CONTROL_CAPABILITIES *pGammaCaps)
{
return m_pReal->GetGammaControlCapabilities(pGammaCaps);
}
virtual HRESULT STDMETHODCALLTYPE SetGammaControl(
/* [annotation][in] */
_In_ const DXGI_GAMMA_CONTROL *pArray)
{
return m_pReal->SetGammaControl(pArray);
}
virtual HRESULT STDMETHODCALLTYPE GetGammaControl(
/* [annotation][out] */
_Out_ DXGI_GAMMA_CONTROL *pArray)
{
return m_pReal->GetGammaControl(pArray);
}
virtual HRESULT STDMETHODCALLTYPE SetDisplaySurface(
/* [annotation][in] */
_In_ IDXGISurface *pScanoutSurface)
{
return m_pReal->SetDisplaySurface(pScanoutSurface);
}
virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData(
/* [annotation][in] */
_In_ IDXGISurface *pDestination)
{
return m_pReal->GetDisplaySurfaceData(pDestination);
}
virtual HRESULT STDMETHODCALLTYPE GetFrameStatistics(
/* [annotation][out] */
_Out_ DXGI_FRAME_STATISTICS *pStats)
{
return m_pReal->GetFrameStatistics(pStats);
}
//////////////////////////////
// implement IDXGIOutput1
virtual HRESULT STDMETHODCALLTYPE GetDisplayModeList1(
/* [in] */ DXGI_FORMAT EnumFormat,
/* [in] */ UINT Flags,
/* [annotation][out][in] */
_Inout_ UINT *pNumModes,
/* [annotation][out] */
_Out_writes_to_opt_(*pNumModes, *pNumModes) DXGI_MODE_DESC1 *pDesc)
{
return m_pReal1->GetDisplayModeList1(EnumFormat, Flags, pNumModes, pDesc);
}
virtual HRESULT STDMETHODCALLTYPE FindClosestMatchingMode1(
/* [annotation][in] */
_In_ const DXGI_MODE_DESC1 *pModeToMatch,
/* [annotation][out] */
_Out_ DXGI_MODE_DESC1 *pClosestMatch,
/* [annotation][in] */
_In_opt_ IUnknown *pConcernedDevice)
{
return m_pReal1->FindClosestMatchingMode1(pModeToMatch, pClosestMatch, pConcernedDevice);
}
virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData1(
/* [annotation][in] */
_In_ IDXGIResource *pDestination)
{
return m_pReal1->GetDisplaySurfaceData1(pDestination);
}
virtual HRESULT STDMETHODCALLTYPE DuplicateOutput(
/* [annotation][in] */
_In_ IUnknown *pDevice,
/* [annotation][out] */
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication)
{
return m_pReal1->DuplicateOutput(pDevice, ppOutputDuplication);
}
//////////////////////////////
// implement IDXGIOutput2
virtual BOOL STDMETHODCALLTYPE SupportsOverlays(void) { return m_pReal2->SupportsOverlays(); }
//////////////////////////////
// implement IDXGIOutput3
virtual HRESULT STDMETHODCALLTYPE CheckOverlaySupport(
/* [annotation][in] */
_In_ DXGI_FORMAT EnumFormat,
/* [annotation][out] */
_In_ IUnknown *pConcernedDevice,
/* [annotation][out] */
_Out_ UINT *pFlags)
{
return m_pReal3->CheckOverlaySupport(EnumFormat, pConcernedDevice, pFlags);
}
//////////////////////////////
// implement IDXGIOutput4
virtual HRESULT STDMETHODCALLTYPE CheckOverlayColorSpaceSupport(
/* [annotation][in] */
_In_ DXGI_FORMAT Format,
/* [annotation][in] */
_In_ DXGI_COLOR_SPACE_TYPE ColorSpace,
/* [annotation][in] */
_In_ IUnknown *pConcernedDevice,
/* [annotation][out] */
_Out_ UINT *pFlags)
{
return m_pReal4->CheckOverlayColorSpaceSupport(Format, ColorSpace, pConcernedDevice, pFlags);
}
//////////////////////////////
// implement IDXGIOutput5
virtual HRESULT STDMETHODCALLTYPE DuplicateOutput1(
/* [annotation][in] */
_In_ IUnknown *pDevice,
/* [in] */ UINT Flags,
/* [annotation][in] */
_In_ UINT SupportedFormatsCount,
/* [annotation][in] */
_In_reads_(SupportedFormatsCount) const DXGI_FORMAT *pSupportedFormats,
/* [annotation][out] */
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication)
{
return m_pReal5->DuplicateOutput1(pDevice, Flags, SupportedFormatsCount, pSupportedFormats,
ppOutputDuplication);
}
};
class WrappedIDXGIAdapter3 : public IDXGIAdapter3, public RefCountDXGIObject
{
IDXGIAdapter *m_pReal;
IDXGIAdapter1 *m_pReal1;
IDXGIAdapter2 *m_pReal2;
IDXGIAdapter3 *m_pReal3;
unsigned int m_iRefcount;
public:
WrappedIDXGIAdapter3(IDXGIAdapter *real);
@@ -867,7 +1059,12 @@ public:
/* [annotation][out][in] */
__out IDXGIOutput **ppOutput)
{
return m_pReal->EnumOutputs(Output, ppOutput);
HRESULT ret = m_pReal->EnumOutputs(Output, ppOutput);
if(SUCCEEDED(ret))
*ppOutput = (IDXGIOutput *)(new WrappedIDXGIOutput5(this, *ppOutput));
return ret;
}
virtual HRESULT STDMETHODCALLTYPE GetDesc(
@@ -1120,7 +1317,6 @@ class WrappedIDXGIFactory5 : public IDXGIFactory5, public RefCountDXGIObject
IDXGIFactory3 *m_pReal3;
IDXGIFactory4 *m_pReal4;
IDXGIFactory5 *m_pReal5;
unsigned int m_iRefcount;
public:
WrappedIDXGIFactory5(IDXGIFactory *real);