From c4e4647ca59b211850cd609c1ad156f5cf5abe0c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Stefan=20D=C3=B6singer?= Date: Wed, 26 Aug 2015 21:50:55 +0200 Subject: [PATCH] d3d9: Validate swap effect and backbuffer count. --- dlls/d3d9/device.c | 42 +++++++++++++++++++++++++++++++++++++----- dlls/wined3d/swapchain.c | 7 ------- include/wine/wined3d.h | 1 - 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c index 0b1a77aa34e..95d1e02910a 100644 --- a/dlls/d3d9/device.c +++ b/dlls/d3d9/device.c @@ -208,9 +208,25 @@ void present_parameters_from_wined3d_swapchain_desc(D3DPRESENT_PARAMETERS *prese present_parameters->PresentationInterval = swapchain_desc->swap_interval; } -static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, - const D3DPRESENT_PARAMETERS *present_parameters) +static BOOL wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapchain_desc *swapchain_desc, + const D3DPRESENT_PARAMETERS *present_parameters, BOOL extended) { + D3DSWAPEFFECT highest_swapeffect = extended ? D3DSWAPEFFECT_FLIPEX : D3DSWAPEFFECT_COPY; + UINT highest_bb_count = extended ? 30 : 3; + + if (!present_parameters->SwapEffect || present_parameters->SwapEffect > highest_swapeffect) + { + WARN("Invalid swap effect %u passed.\n", present_parameters->SwapEffect); + return FALSE; + } + if (present_parameters->BackBufferCount > highest_bb_count + || (present_parameters->SwapEffect == D3DSWAPEFFECT_COPY + && present_parameters->BackBufferCount > 1)) + { + WARN("Invalid backbuffer count %u.\n", present_parameters->BackBufferCount); + return FALSE; + } + swapchain_desc->backbuffer_width = present_parameters->BackBufferWidth; swapchain_desc->backbuffer_height = present_parameters->BackBufferHeight; swapchain_desc->backbuffer_format = wined3dformat_from_d3dformat(present_parameters->BackBufferFormat); @@ -227,6 +243,8 @@ static void wined3d_swapchain_desc_from_present_parameters(struct wined3d_swapch swapchain_desc->refresh_rate = present_parameters->FullScreen_RefreshRateInHz; swapchain_desc->swap_interval = present_parameters->PresentationInterval; swapchain_desc->auto_restore_display_mode = TRUE; + + return TRUE; } static HRESULT WINAPI d3d9_device_QueryInterface(IDirect3DDevice9Ex *iface, REFIID riid, void **out) @@ -533,7 +551,9 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_device_CreateAdditionalSwapChain(ID } wined3d_mutex_unlock(); - wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters); + if (!wined3d_swapchain_desc_from_present_parameters(&desc, present_parameters, + device->d3d_parent->extended)) + return D3DERR_INVALIDCALL; if (SUCCEEDED(hr = d3d9_swapchain_create(device, &desc, &object))) *swapchain = (IDirect3DSwapChain9 *)&object->IDirect3DSwapChain9Ex_iface; present_parameters_from_wined3d_swapchain_desc(present_parameters, &desc); @@ -648,6 +668,10 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, wined3d_mode.scanline_ordering = mode->ScanLineOrdering; } + if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters, + device->d3d_parent->extended)) + return D3DERR_INVALIDCALL; + wined3d_mutex_lock(); if (device->vertex_buffer) @@ -664,7 +688,6 @@ static HRESULT d3d9_device_reset(struct d3d9_device *device, device->index_buffer_size = 0; } - wined3d_swapchain_desc_from_present_parameters(&swapchain_desc, present_parameters); if (SUCCEEDED(hr = wined3d_device_reset(device->wined3d_device, &swapchain_desc, mode ? &wined3d_mode : NULL, reset_enum_callback, !device->d3d_parent->extended))) { @@ -3683,6 +3706,7 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine if (!swapchain_desc) { ERR("Failed to allocate wined3d parameters.\n"); + wined3d_device_release_focus_window(device->wined3d_device); wined3d_device_decref(device->wined3d_device); wined3d_mutex_unlock(); return E_OUTOFMEMORY; @@ -3690,7 +3714,15 @@ HRESULT device_init(struct d3d9_device *device, struct d3d9 *parent, struct wine for (i = 0; i < count; ++i) { - wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], ¶meters[i]); + if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], ¶meters[i], + parent->extended)) + { + wined3d_device_release_focus_window(device->wined3d_device); + wined3d_device_decref(device->wined3d_device); + HeapFree(GetProcessHeap(), 0, swapchain_desc); + wined3d_mutex_unlock(); + return D3DERR_INVALIDCALL; + } } hr = wined3d_device_init_3d(device->wined3d_device, swapchain_desc); diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c index 280121560f6..70f5d5c1247 100644 --- a/dlls/wined3d/swapchain.c +++ b/dlls/wined3d/swapchain.c @@ -780,13 +780,6 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, struct wined3 HRESULT hr; UINT i; - if (desc->backbuffer_count > WINED3DPRESENT_BACK_BUFFER_MAX) - { - FIXME("The application requested %u back buffers, this is not supported.\n", - desc->backbuffer_count); - return WINED3DERR_INVALIDCALL; - } - if (desc->backbuffer_count > 1) { FIXME("The application requested more than one back buffer, this is not properly supported.\n" diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h index 4d28baba391..8970cd5a8ac 100644 --- a/include/wine/wined3d.h +++ b/include/wine/wined3d.h @@ -804,7 +804,6 @@ enum wined3d_display_rotation #define WINED3DADAPTER_DEFAULT 0 #define WINED3DENUM_NO_WHQL_LEVEL 2 -#define WINED3DPRESENT_BACK_BUFFER_MAX 3 #define WINED3DTSS_TCI_PASSTHRU 0x00000 #define WINED3DTSS_TCI_CAMERASPACENORMAL 0x10000 -- 2.11.4.GIT