[PATCH 8/8] ddraw/tests: Test destroying ddraw in WM_KILLFOCUS.
Stefan Dösinger
stefan at codeweavers.com
Sat Oct 13 18:13:57 CDT 2018
Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>
---
The ddraw object is actually freed and not kept alive by some hidden
refcount. I checked this by HeapAlloc'ing memory and zeroing it until
the address space is full. The memory killfocus_ddraw points to is
overwritten by this.
---
dlls/ddraw/tests/ddraw1.c | 54 +++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw2.c | 54 +++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw4.c | 54 +++++++++++++++++++++++++++++++++++++++
dlls/ddraw/tests/ddraw7.c | 54 +++++++++++++++++++++++++++++++++++++++
4 files changed, 216 insertions(+)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c
index aad7bbff1f4..1f93a97329e 100644
--- a/dlls/ddraw/tests/ddraw1.c
+++ b/dlls/ddraw/tests/ddraw1.c
@@ -11875,6 +11875,59 @@ static void test_find_device(void)
IDirectDraw_Release(ddraw);
}
+static IDirectDraw *killfocus_ddraw;
+static IDirectDrawSurface *killfocus_surface;
+
+static LRESULT CALLBACK killfocus_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ ULONG ref;
+
+ if (message == WM_KILLFOCUS)
+ {
+ ref = IDirectDrawSurface_Release(killfocus_surface);
+ ok(!ref, "Unexpected surface refcount %u.\n", ref);
+ ref = IDirectDraw_Release(killfocus_ddraw);
+ ok(!ref, "Unexpected ddraw refcount %u.\n", ref);
+ killfocus_ddraw = NULL;
+ }
+
+ return DefWindowProcA(window, message, wparam, lparam);
+}
+
+static void test_killfocus(void)
+{
+ DDSURFACEDESC surface_desc;
+ HRESULT hr;
+ HWND window;
+ WNDCLASSA wc = {0};
+
+ wc.lpfnWndProc = killfocus_proc;
+ wc.lpszClassName = "ddraw_killfocus_wndproc_wc";
+ ok(RegisterClassA(&wc), "Failed to register window class.\n");
+
+ window = CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+
+ killfocus_ddraw = create_ddraw();
+ ok(!!killfocus_ddraw, "Failed to create a ddraw object.\n");
+
+ hr = IDirectDraw_SetCooperativeLevel(killfocus_ddraw, window, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ SetForegroundWindow(GetDesktopWindow());
+ ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
+
+ DestroyWindow(window);
+ UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL));
+}
+
START_TEST(ddraw1)
{
DDDEVICEIDENTIFIER identifier;
@@ -11980,4 +12033,5 @@ START_TEST(ddraw1)
test_execute_data();
test_viewport();
test_find_device();
+ test_killfocus();
}
diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c
index 29c3c845cb1..95cdf8bd82d 100644
--- a/dlls/ddraw/tests/ddraw2.c
+++ b/dlls/ddraw/tests/ddraw2.c
@@ -13157,6 +13157,59 @@ static void test_find_device(void)
IDirectDraw2_Release(ddraw);
}
+static IDirectDraw2 *killfocus_ddraw;
+static IDirectDrawSurface *killfocus_surface;
+
+static LRESULT CALLBACK killfocus_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ ULONG ref;
+
+ if (message == WM_KILLFOCUS)
+ {
+ ref = IDirectDrawSurface_Release(killfocus_surface);
+ ok(!ref, "Unexpected surface refcount %u.\n", ref);
+ ref = IDirectDraw2_Release(killfocus_ddraw);
+ ok(!ref, "Unexpected ddraw refcount %u.\n", ref);
+ killfocus_ddraw = NULL;
+ }
+
+ return DefWindowProcA(window, message, wparam, lparam);
+}
+
+static void test_killfocus(void)
+{
+ DDSURFACEDESC surface_desc;
+ HRESULT hr;
+ HWND window;
+ WNDCLASSA wc = {0};
+
+ wc.lpfnWndProc = killfocus_proc;
+ wc.lpszClassName = "ddraw_killfocus_wndproc_wc";
+ ok(RegisterClassA(&wc), "Failed to register window class.\n");
+
+ window = CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+
+ killfocus_ddraw = create_ddraw();
+ ok(!!killfocus_ddraw, "Failed to create a ddraw object.\n");
+
+ hr = IDirectDraw2_SetCooperativeLevel(killfocus_ddraw, window, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ SetForegroundWindow(GetDesktopWindow());
+ ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
+
+ DestroyWindow(window);
+ UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL));
+}
+
START_TEST(ddraw2)
{
DDDEVICEIDENTIFIER identifier;
@@ -13270,4 +13323,5 @@ START_TEST(ddraw2)
test_enum_surfaces();
test_viewport();
test_find_device();
+ test_killfocus();
}
diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c
index 3aae42554f2..a62aaf0f30e 100644
--- a/dlls/ddraw/tests/ddraw4.c
+++ b/dlls/ddraw/tests/ddraw4.c
@@ -15265,6 +15265,59 @@ static void test_find_device(void)
IDirectDraw4_Release(ddraw);
}
+static IDirectDraw4 *killfocus_ddraw;
+static IDirectDrawSurface4 *killfocus_surface;
+
+static LRESULT CALLBACK killfocus_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ ULONG ref;
+
+ if (message == WM_KILLFOCUS)
+ {
+ ref = IDirectDrawSurface4_Release(killfocus_surface);
+ ok(!ref, "Unexpected surface refcount %u.\n", ref);
+ ref = IDirectDraw4_Release(killfocus_ddraw);
+ ok(!ref, "Unexpected ddraw refcount %u.\n", ref);
+ killfocus_ddraw = NULL;
+ }
+
+ return DefWindowProcA(window, message, wparam, lparam);
+}
+
+static void test_killfocus(void)
+{
+ DDSURFACEDESC2 surface_desc;
+ HRESULT hr;
+ HWND window;
+ WNDCLASSA wc = {0};
+
+ wc.lpfnWndProc = killfocus_proc;
+ wc.lpszClassName = "ddraw_killfocus_wndproc_wc";
+ ok(RegisterClassA(&wc), "Failed to register window class.\n");
+
+ window = CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+
+ killfocus_ddraw = create_ddraw();
+ ok(!!killfocus_ddraw, "Failed to create a ddraw object.\n");
+
+ hr = IDirectDraw4_SetCooperativeLevel(killfocus_ddraw, window, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw7_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ SetForegroundWindow(GetDesktopWindow());
+ ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
+
+ DestroyWindow(window);
+ UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL));
+}
+
START_TEST(ddraw4)
{
DDDEVICEIDENTIFIER identifier;
@@ -15392,4 +15445,5 @@ START_TEST(ddraw4)
test_enum_surfaces();
test_viewport();
test_find_device();
+ test_killfocus();
}
diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c
index 4691135186b..05151b06510 100644
--- a/dlls/ddraw/tests/ddraw7.c
+++ b/dlls/ddraw/tests/ddraw7.c
@@ -15035,6 +15035,59 @@ static void test_color_vertex(void)
DestroyWindow(window);
}
+static IDirectDraw7 *killfocus_ddraw;
+static IDirectDrawSurface7 *killfocus_surface;
+
+static LRESULT CALLBACK killfocus_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
+{
+ ULONG ref;
+
+ if (message == WM_KILLFOCUS)
+ {
+ ref = IDirectDrawSurface7_Release(killfocus_surface);
+ ok(!ref, "Unexpected surface refcount %u.\n", ref);
+ ref = IDirectDraw7_Release(killfocus_ddraw);
+ ok(!ref, "Unexpected ddraw refcount %u.\n", ref);
+ killfocus_ddraw = NULL;
+ }
+
+ return DefWindowProcA(window, message, wparam, lparam);
+}
+
+static void test_killfocus(void)
+{
+ DDSURFACEDESC2 surface_desc;
+ HRESULT hr;
+ HWND window;
+ WNDCLASSA wc = {0};
+
+ wc.lpfnWndProc = killfocus_proc;
+ wc.lpszClassName = "ddraw_killfocus_wndproc_wc";
+ ok(RegisterClassA(&wc), "Failed to register window class.\n");
+
+ window = CreateWindowA("ddraw_killfocus_wndproc_wc", "d3d7_test", WS_OVERLAPPEDWINDOW,
+ 0, 0, 640, 480, 0, 0, 0, 0);
+
+ killfocus_ddraw = create_ddraw();
+ ok(!!killfocus_ddraw, "Failed to create a ddraw object.\n");
+
+ hr = IDirectDraw7_SetCooperativeLevel(killfocus_ddraw, window, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE);
+ ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#x.\n", hr);
+
+ memset(&surface_desc, 0, sizeof(surface_desc));
+ surface_desc.dwSize = sizeof(surface_desc);
+ surface_desc.dwFlags = DDSD_CAPS;
+ surface_desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
+ hr = IDirectDraw7_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL);
+ ok(SUCCEEDED(hr), "Failed to create surface, hr %#x.\n", hr);
+
+ SetForegroundWindow(GetDesktopWindow());
+ ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
+
+ DestroyWindow(window);
+ UnregisterClassA("ddraw_killfocus_wndproc_wc", GetModuleHandleA(NULL));
+}
+
START_TEST(ddraw7)
{
DDDEVICEIDENTIFIER2 identifier;
@@ -15173,4 +15226,5 @@ START_TEST(ddraw7)
test_viewport();
test_device_load();
test_color_vertex();
+ test_killfocus();
}
--
2.18.1
More information about the wine-devel
mailing list