[PATCH] d3dx9: Improve argument validation in CloneEffect()

Nikolay Sivov nsivov at codeweavers.com
Thu Mar 1 06:14:35 CST 2018


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/d3dx9_36/effect.c       |  9 +++++
 dlls/d3dx9_36/tests/effect.c | 86 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 95 insertions(+)

diff --git a/dlls/d3dx9_36/effect.c b/dlls/d3dx9_36/effect.c
index f8c480303c..a98495e555 100644
--- a/dlls/d3dx9_36/effect.c
+++ b/dlls/d3dx9_36/effect.c
@@ -4367,6 +4367,15 @@ static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
 
     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
 
+    if (!effect)
+        return D3DERR_INVALIDCALL;
+
+    if (This->base_effect.flags & D3DXFX_NOT_CLONEABLE)
+        return E_FAIL;
+
+    if (!device)
+        return D3DERR_INVALIDCALL;
+
     return E_NOTIMPL;
 }
 
diff --git a/dlls/d3dx9_36/tests/effect.c b/dlls/d3dx9_36/tests/effect.c
index 1900f3eac1..28dcf47cd3 100644
--- a/dlls/d3dx9_36/tests/effect.c
+++ b/dlls/d3dx9_36/tests/effect.c
@@ -7294,6 +7294,91 @@ static void test_effect_null_shader(void)
     DestroyWindow(window);
 }
 
+static void test_effect_clone(IDirect3DDevice9 *device)
+{
+    D3DPRESENT_PARAMETERS present_parameters;
+    ID3DXEffect *effect, *cloned;
+    IDirect3DDevice9 *device2;
+    IDirect3D9 *d3d;
+    HWND window;
+    HRESULT hr;
+
+    /* D3DXFX_NOT_CLONEABLE */
+    hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+            NULL, NULL, D3DXFX_NOT_CLONEABLE, NULL, &effect, NULL);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+    hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL);
+    ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+    cloned = (void *)0xdeadbeef;
+    hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned);
+    ok(hr == E_FAIL, "Got result %#x.\n", hr);
+    ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+    hr = effect->lpVtbl->CloneEffect(effect, device, NULL);
+    ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+    cloned = (void *)0xdeadbeef;
+    hr = effect->lpVtbl->CloneEffect(effect, device, &cloned);
+    ok(hr == E_FAIL, "Got result %#x.\n", hr);
+    ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+    effect->lpVtbl->Release(effect);
+
+    hr = D3DXCreateEffect(device, test_effect_preshader_effect_blob, sizeof(test_effect_preshader_effect_blob),
+            NULL, NULL, 0, NULL, &effect, NULL);
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
+
+    hr = effect->lpVtbl->CloneEffect(effect, NULL, NULL);
+    ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+    cloned = (void *)0xdeadbeef;
+    hr = effect->lpVtbl->CloneEffect(effect, NULL, &cloned);
+    ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+    ok(cloned == (void *)0xdeadbeef, "Unexpected effect pointer.\n");
+
+    hr = effect->lpVtbl->CloneEffect(effect, device, NULL);
+    ok(hr == D3DERR_INVALIDCALL, "Got result %#x.\n", hr);
+
+    hr = effect->lpVtbl->CloneEffect(effect, device, &cloned);
+todo_wine
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
+if (hr == D3D_OK)
+{
+    ok(cloned != effect, "Expected new effect instance.\n");
+    cloned->lpVtbl->Release(cloned);
+}
+    /* Try with different device. */
+    hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
+    ok(hr == D3D_OK, "Failed to get IDirect3D9 pointer.\n");
+
+    window = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0,
+            640, 480, NULL, NULL, NULL, NULL);
+    ok(!!window, "Failed to create a test window.\n");
+
+    memset(&present_parameters, 0, sizeof(present_parameters));
+    present_parameters.Windowed = TRUE;
+    present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+    hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window,
+            D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device2);
+    ok(SUCCEEDED(hr), "Failed to create IDirect3DDevice9 object, hr %#x\n", hr);
+
+    hr = effect->lpVtbl->CloneEffect(effect, device2, &cloned);
+todo_wine
+    ok(hr == D3D_OK, "Got result %#x.\n", hr);
+if (hr == D3D_OK)
+{
+    ok(cloned != effect, "Expected new effect instance.\n");
+    cloned->lpVtbl->Release(cloned);
+}
+    IDirect3DDevice9_Release(device2);
+    IDirect3D9_Release(d3d);
+    DestroyWindow(window);
+
+    effect->lpVtbl->Release(effect);
+}
+
 START_TEST(effect)
 {
     HWND wnd;
@@ -7346,6 +7431,7 @@ START_TEST(effect)
     test_effect_large_address_aware_flag(device);
     test_effect_get_pass_desc(device);
     test_effect_skip_constants(device);
+    test_effect_clone(device);
 
     refcount = IDirect3DDevice9_Release(device);
     ok(!refcount, "Device has %u references left.\n", refcount);
-- 
2.16.1




More information about the wine-devel mailing list