[PATCH 1/5] d3d9: Validate swap effect and backbuffer count.

Stefan Dösinger stefan at codeweavers.com
Wed Aug 26 14:50:55 CDT 2015


---
 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 0b1a77a..95d1e02 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], &parameters[i]);
+        if (!wined3d_swapchain_desc_from_present_parameters(&swapchain_desc[i], &parameters[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 2801215..70f5d5c 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 4d28bab..8970cd5 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.4.6




More information about the wine-patches mailing list