From 77010d96e42a7d36d0959b30d51771e22bf03195 Mon Sep 17 00:00:00 2001 From: Philip Rebohle Date: Mon, 2 Apr 2018 12:04:20 +0200 Subject: [PATCH] [dxgi/d3d11] Set returned pointers to nullptr before returning May solve issues with applications which check whether the returned pointer is null rather than checking a function's return value. --- src/d3d11/d3d11_class_linkage.cpp | 2 ++ src/d3d11/d3d11_context_imm.cpp | 2 ++ src/d3d11/d3d11_device.cpp | 52 ++++++++++++++++++++++++++++++- src/dxgi/dxgi_adapter.cpp | 4 +++ src/dxgi/dxgi_device.cpp | 2 ++ src/dxgi/dxgi_factory.cpp | 15 ++++++--- src/dxgi/dxgi_swapchain.cpp | 4 +++ src/util/com/com_object.h | 6 ++++ 8 files changed, 82 insertions(+), 5 deletions(-) diff --git a/src/d3d11/d3d11_class_linkage.cpp b/src/d3d11/d3d11_class_linkage.cpp index 7e13e660d..b45327eda 100644 --- a/src/d3d11/d3d11_class_linkage.cpp +++ b/src/d3d11/d3d11_class_linkage.cpp @@ -38,6 +38,8 @@ namespace dxvk { UINT TextureOffset, UINT SamplerOffset, ID3D11ClassInstance **ppInstance) { + InitReturnPtr(ppInstance); + Logger::err("D3D11ClassLinkage::CreateClassInstance: Not implemented yet"); return E_NOTIMPL; } diff --git a/src/d3d11/d3d11_context_imm.cpp b/src/d3d11/d3d11_context_imm.cpp index 3315c6c88..f899520f3 100644 --- a/src/d3d11/d3d11_context_imm.cpp +++ b/src/d3d11/d3d11_context_imm.cpp @@ -88,6 +88,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11ImmediateContext::FinishCommandList( BOOL RestoreDeferredContextState, ID3D11CommandList **ppCommandList) { + InitReturnPtr(ppCommandList); + Logger::err("D3D11: FinishCommandList called on immediate context"); return DXGI_ERROR_INVALID_CALL; } diff --git a/src/d3d11/d3d11_device.cpp b/src/d3d11/d3d11_device.cpp index 212267d90..84350db8c 100644 --- a/src/d3d11/d3d11_device.cpp +++ b/src/d3d11/d3d11_device.cpp @@ -126,6 +126,8 @@ namespace dxvk { const D3D11_BUFFER_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Buffer** ppBuffer) { + InitReturnPtr(ppBuffer); + if (ppBuffer == nullptr) return S_FALSE; @@ -147,6 +149,8 @@ namespace dxvk { const D3D11_TEXTURE1D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture1D** ppTexture1D) { + InitReturnPtr(ppTexture1D); + D3D11_COMMON_TEXTURE_DESC desc; desc.Width = pDesc->Width; desc.Height = 1; @@ -182,6 +186,8 @@ namespace dxvk { const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture2D** ppTexture2D) { + InitReturnPtr(ppTexture2D); + D3D11_COMMON_TEXTURE_DESC desc; desc.Width = pDesc->Width; desc.Height = pDesc->Height; @@ -217,6 +223,8 @@ namespace dxvk { const D3D11_TEXTURE3D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture3D** ppTexture3D) { + InitReturnPtr(ppTexture3D); + D3D11_COMMON_TEXTURE_DESC desc; desc.Width = pDesc->Width; desc.Height = pDesc->Height; @@ -252,6 +260,8 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_SHADER_RESOURCE_VIEW_DESC* pDesc, ID3D11ShaderResourceView** ppSRView) { + InitReturnPtr(ppSRView); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); @@ -457,6 +467,8 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_UNORDERED_ACCESS_VIEW_DESC* pDesc, ID3D11UnorderedAccessView** ppUAView) { + InitReturnPtr(ppUAView); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); @@ -623,6 +635,8 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_RENDER_TARGET_VIEW_DESC* pDesc, ID3D11RenderTargetView** ppRTView) { + InitReturnPtr(ppRTView); + // DXVK only supports render target views for image resources D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); @@ -745,6 +759,8 @@ namespace dxvk { ID3D11Resource* pResource, const D3D11_DEPTH_STENCIL_VIEW_DESC* pDesc, ID3D11DepthStencilView** ppDepthStencilView) { + InitReturnPtr(ppDepthStencilView); + D3D11_RESOURCE_DIMENSION resourceDim = D3D11_RESOURCE_DIMENSION_UNKNOWN; pResource->GetType(&resourceDim); @@ -855,6 +871,8 @@ namespace dxvk { const void* pShaderBytecodeWithInputSignature, SIZE_T BytecodeLength, ID3D11InputLayout** ppInputLayout) { + InitReturnPtr(ppInputLayout); + try { DxbcReader dxbcReader(reinterpret_cast( pShaderBytecodeWithInputSignature), BytecodeLength); @@ -983,6 +1001,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11VertexShader** ppVertexShader) { + InitReturnPtr(ppVertexShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1003,6 +1022,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11GeometryShader** ppGeometryShader) { + InitReturnPtr(ppGeometryShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1028,6 +1048,7 @@ namespace dxvk { UINT RasterizedStream, ID3D11ClassLinkage* pClassLinkage, ID3D11GeometryShader** ppGeometryShader) { + InitReturnPtr(ppGeometryShader); Logger::err("D3D11Device::CreateGeometryShaderWithStreamOutput: Not implemented"); return E_NOTIMPL; } @@ -1038,6 +1059,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11PixelShader** ppPixelShader) { + InitReturnPtr(ppPixelShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1058,6 +1080,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11HullShader** ppHullShader) { + InitReturnPtr(ppHullShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1078,6 +1101,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11DomainShader** ppDomainShader) { + InitReturnPtr(ppDomainShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1098,6 +1122,7 @@ namespace dxvk { SIZE_T BytecodeLength, ID3D11ClassLinkage* pClassLinkage, ID3D11ComputeShader** ppComputeShader) { + InitReturnPtr(ppComputeShader); D3D11ShaderModule module; if (FAILED(this->CreateShaderModule(&module, @@ -1122,6 +1147,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateBlendState( const D3D11_BLEND_DESC* pBlendStateDesc, ID3D11BlendState** ppBlendState) { + InitReturnPtr(ppBlendState); + D3D11_BLEND_DESC1 desc = pBlendStateDesc != nullptr ? D3D11BlendState::PromoteDesc(pBlendStateDesc) : D3D11BlendState::DefaultDesc(); @@ -1139,6 +1166,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateBlendState1( const D3D11_BLEND_DESC1* pBlendStateDesc, ID3D11BlendState1** ppBlendState) { + InitReturnPtr(ppBlendState); + D3D11_BLEND_DESC1 desc = pBlendStateDesc != nullptr ? *pBlendStateDesc : D3D11BlendState::DefaultDesc(); @@ -1156,6 +1185,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateDepthStencilState( const D3D11_DEPTH_STENCIL_DESC* pDepthStencilDesc, ID3D11DepthStencilState** ppDepthStencilState) { + InitReturnPtr(ppDepthStencilState); + D3D11_DEPTH_STENCIL_DESC desc = pDepthStencilDesc != nullptr ? *pDepthStencilDesc : D3D11DepthStencilState::DefaultDesc(); @@ -1173,6 +1204,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateRasterizerState( const D3D11_RASTERIZER_DESC* pRasterizerDesc, ID3D11RasterizerState** ppRasterizerState) { + InitReturnPtr(ppRasterizerState); + D3D11_RASTERIZER_DESC1 desc = pRasterizerDesc != nullptr ? D3D11RasterizerState::PromoteDesc(pRasterizerDesc) : D3D11RasterizerState::DefaultDesc(); @@ -1190,6 +1223,8 @@ namespace dxvk { HRESULT D3D11Device::CreateRasterizerState1( const D3D11_RASTERIZER_DESC1* pRasterizerDesc, ID3D11RasterizerState1** ppRasterizerState) { + InitReturnPtr(ppRasterizerState); + D3D11_RASTERIZER_DESC1 desc = pRasterizerDesc != nullptr ? *pRasterizerDesc : D3D11RasterizerState::DefaultDesc(); @@ -1207,6 +1242,7 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateSamplerState( const D3D11_SAMPLER_DESC* pSamplerDesc, ID3D11SamplerState** ppSamplerState) { + InitReturnPtr(ppSamplerState); D3D11_SAMPLER_DESC desc = *pSamplerDesc; if (FAILED(D3D11SamplerState::NormalizeDesc(&desc))) @@ -1228,6 +1264,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateQuery( const D3D11_QUERY_DESC* pQueryDesc, ID3D11Query** ppQuery) { + InitReturnPtr(ppQuery); + if (pQueryDesc->Query != D3D11_QUERY_EVENT && pQueryDesc->Query != D3D11_QUERY_OCCLUSION && pQueryDesc->Query != D3D11_QUERY_TIMESTAMP @@ -1254,6 +1292,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreatePredicate( const D3D11_QUERY_DESC* pPredicateDesc, ID3D11Predicate** ppPredicate) { + InitReturnPtr(ppPredicate); + if (pPredicateDesc->Query != D3D11_QUERY_OCCLUSION_PREDICATE) return E_INVALIDARG; @@ -1273,6 +1313,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE D3D11Device::CreateCounter( const D3D11_COUNTER_DESC* pCounterDesc, ID3D11Counter** ppCounter) { + InitReturnPtr(ppCounter); + Logger::err("D3D11Device::CreateCounter: Not implemented"); return E_NOTIMPL; } @@ -1300,6 +1342,8 @@ namespace dxvk { REFIID EmulatedInterface, D3D_FEATURE_LEVEL* pChosenFeatureLevel, ID3DDeviceContextState** ppContextState) { + InitReturnPtr(ppContextState); + Logger::err("D3D11Device::CreateDeviceContextState: Not implemented"); return E_NOTIMPL; } @@ -1308,6 +1352,8 @@ namespace dxvk { HANDLE hResource, REFIID ReturnedInterface, void** ppResource) { + InitReturnPtr(ppResource); + Logger::err("D3D11Device::OpenSharedResource: Not implemented"); return E_NOTIMPL; } @@ -1317,6 +1363,8 @@ namespace dxvk { HANDLE hResource, REFIID ReturnedInterface, void** ppResource) { + InitReturnPtr(ppResource); + Logger::err("D3D11Device::OpenSharedResource1: Not implemented"); return E_NOTIMPL; } @@ -1326,7 +1374,9 @@ namespace dxvk { LPCWSTR lpName, DWORD dwDesiredAccess, REFIID returnedInterface, - void ** ppResource) { + void** ppResource) { + InitReturnPtr(ppResource); + Logger::err("D3D11Device::OpenSharedResourceByName: Not implemented"); return E_NOTIMPL; } diff --git a/src/dxgi/dxgi_adapter.cpp b/src/dxgi/dxgi_adapter.cpp index 593e6b707..677d8c54a 100644 --- a/src/dxgi/dxgi_adapter.cpp +++ b/src/dxgi/dxgi_adapter.cpp @@ -54,6 +54,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiAdapter::EnumOutputs( UINT Output, IDXGIOutput **ppOutput) { + InitReturnPtr(ppOutput); + if (ppOutput == nullptr) return DXGI_ERROR_INVALID_CALL; @@ -154,6 +156,8 @@ namespace dxvk { IDXGIObject* pContainer, const VkPhysicalDeviceFeatures* pFeatures, IDXGIVkDevice** ppDevice) { + InitReturnPtr(ppDevice); + try { *ppDevice = new dxvk::DxgiDevice(pContainer, this, pFeatures); return S_OK; diff --git a/src/dxgi/dxgi_device.cpp b/src/dxgi/dxgi_device.cpp index 1d3e05a39..de01e20da 100644 --- a/src/dxgi/dxgi_device.cpp +++ b/src/dxgi/dxgi_device.cpp @@ -62,6 +62,8 @@ namespace dxvk { DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE* pSharedResource, IDXGISurface** ppSurface) { + InitReturnPtr(ppSurface); + Logger::err("DxgiDevice::CreateSurface: Not implemented"); return E_NOTIMPL; } diff --git a/src/dxgi/dxgi_factory.cpp b/src/dxgi/dxgi_factory.cpp index 37ca1f31a..0207ad387 100644 --- a/src/dxgi/dxgi_factory.cpp +++ b/src/dxgi/dxgi_factory.cpp @@ -33,6 +33,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiFactory::GetParent( REFIID riid, void** ppParent) { + InitReturnPtr(ppParent); + Logger::warn("DxgiFactory::GetParent: Unknown interface query"); return E_NOINTERFACE; } @@ -41,10 +43,11 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiFactory::CreateSoftwareAdapter( HMODULE Module, IDXGIAdapter** ppAdapter) { + InitReturnPtr(ppAdapter); + if (ppAdapter == nullptr) return DXGI_ERROR_INVALID_CALL; - *ppAdapter = nullptr; Logger::err("DxgiFactory::CreateSoftwareAdapter: Software adapters not supported"); return DXGI_ERROR_UNSUPPORTED; } @@ -54,6 +57,8 @@ namespace dxvk { IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain** ppSwapChain) { + InitReturnPtr(ppSwapChain); + if (ppSwapChain == nullptr || pDesc == nullptr || pDevice == NULL) return DXGI_ERROR_INVALID_CALL; @@ -73,6 +78,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiFactory::EnumAdapters( UINT Adapter, IDXGIAdapter** ppAdapter) { + InitReturnPtr(ppAdapter); + if (ppAdapter == nullptr) return DXGI_ERROR_INVALID_CALL; @@ -86,13 +93,13 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiFactory::EnumAdapters1( UINT Adapter, IDXGIAdapter1** ppAdapter) { + InitReturnPtr(ppAdapter); + if (ppAdapter == nullptr) return DXGI_ERROR_INVALID_CALL; - if (Adapter >= m_adapters.size()) { - *ppAdapter = nullptr; + if (Adapter >= m_adapters.size()) return DXGI_ERROR_NOT_FOUND; - } *ppAdapter = ref(new DxgiAdapter( this, m_adapters.at(Adapter))); diff --git a/src/dxgi/dxgi_swapchain.cpp b/src/dxgi/dxgi_swapchain.cpp index 2a7d0ac50..50b447a6b 100644 --- a/src/dxgi/dxgi_swapchain.cpp +++ b/src/dxgi/dxgi_swapchain.cpp @@ -82,6 +82,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface) { + InitReturnPtr(ppSurface); + std::lock_guard lock(m_mutex); if (Buffer > 0) { @@ -94,6 +96,8 @@ namespace dxvk { HRESULT STDMETHODCALLTYPE DxgiSwapChain::GetContainingOutput(IDXGIOutput** ppOutput) { + InitReturnPtr(ppOutput); + RECT windowRect = { 0, 0, 0, 0 }; ::GetWindowRect(m_desc.OutputWindow, &windowRect); diff --git a/src/util/com/com_object.h b/src/util/com/com_object.h index cfb3fe283..9781c6866 100644 --- a/src/util/com/com_object.h +++ b/src/util/com/com_object.h @@ -41,4 +41,10 @@ namespace dxvk { }; + template + inline void InitReturnPtr(T** ptr) { + if (ptr != nullptr) + *ptr = nullptr; + } + }