Roman Pišl : ole32: Avoid calling QueryContinueDrag recursively.
Alexandre Julliard
julliard at winehq.org
Tue Jun 2 08:11:17 CDT 2020
Module: wine
Branch: stable
Commit: 0d85e007b9b1676052a61836195fab00471fb9c7
URL: https://source.winehq.org/git/wine.git/?a=commit;h=0d85e007b9b1676052a61836195fab00471fb9c7
Author: Roman Pišl <rpisl at seznam.cz>
Date: Mon Feb 17 23:59:38 2020 +0100
ole32: Avoid calling QueryContinueDrag recursively.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48569
Signed-off-by: Roman Pišl <rpisl at seznam.cz>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
(cherry picked from commit 808d8b87a040e4de44e2691d3a9e29f871616ca0)
Signed-off-by: Michael Stefaniuc <mstefani at winehq.org>
---
dlls/ole32/ole2.c | 11 ++++++++++
dlls/ole32/tests/dragdrop.c | 53 +++++++++++++++++++++++++++++++++++----------
2 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/dlls/ole32/ole2.c b/dlls/ole32/ole2.c
index 757458ad20..6653fac342 100644
--- a/dlls/ole32/ole2.c
+++ b/dlls/ole32/ole2.c
@@ -62,6 +62,7 @@ typedef struct tagTrackerWindowInfo
DWORD dwOKEffect;
DWORD* pdwEffect;
BOOL trackingDone;
+ BOOL inTrackCall;
HRESULT returnValue;
BOOL escPressed;
@@ -766,6 +767,7 @@ HRESULT WINAPI DoDragDrop (
trackerInfo.dwOKEffect = dwOKEffect;
trackerInfo.pdwEffect = pdwEffect;
trackerInfo.trackingDone = FALSE;
+ trackerInfo.inTrackCall = FALSE;
trackerInfo.escPressed = FALSE;
trackerInfo.curTargetHWND = 0;
trackerInfo.curDragTarget = 0;
@@ -2284,6 +2286,13 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
HWND hwndNewTarget = 0;
POINT pt;
+ /*
+ * This method may be called from QueryContinueDrag again,
+ * (i.e. by running message loop) so avoid recursive call chain.
+ */
+ if (trackerInfo->inTrackCall) return;
+ trackerInfo->inTrackCall = TRUE;
+
/*
* Get the handle of the window under the mouse
*/
@@ -2329,6 +2338,8 @@ static void OLEDD_TrackStateChange(TrackerWindowInfo* trackerInfo)
}
else
drag_end( trackerInfo );
+
+ trackerInfo->inTrackCall = FALSE;
}
/***
diff --git a/dlls/ole32/tests/dragdrop.c b/dlls/ole32/tests/dragdrop.c
index 77e47d723d..62ac15d8fc 100644
--- a/dlls/ole32/tests/dragdrop.c
+++ b/dlls/ole32/tests/dragdrop.c
@@ -260,6 +260,7 @@ struct method_call call_lists[][30] =
};
static int droptarget_refs;
+static int test_reentrance;
/* helper macros to make tests a bit leaner */
#define ok_ole_success(hr, func) ok(hr == S_OK, func " failed with error 0x%08x\n", hr)
@@ -359,7 +360,34 @@ static HRESULT WINAPI DropSource_QueryContinueDrag(
BOOL fEscapePressed,
DWORD grfKeyState)
{
- return check_expect(DS_QueryContinueDrag, 0, NULL);
+ HRESULT hr = check_expect(DS_QueryContinueDrag, 0, NULL);
+ if (test_reentrance)
+ {
+ MSG msg;
+ BOOL r;
+ int num = 0;
+
+ HWND hwnd = GetCapture();
+ ok(hwnd != 0, "Expected capture window\n");
+
+ /* send some fake events that should be ignored */
+ r = PostMessageA(hwnd, WM_MOUSEMOVE, 0, 0);
+ r &= PostMessageA(hwnd, WM_LBUTTONDOWN, 0, 0);
+ r &= PostMessageA(hwnd, WM_LBUTTONUP, 0, 0);
+ r &= PostMessageA(hwnd, WM_KEYDOWN, VK_ESCAPE, 0);
+ ok(r, "Unable to post messages\n");
+
+ /* run the message loop for this thread */
+ while (PeekMessageA(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ TranslateMessage(&msg);
+ DispatchMessageA(&msg);
+ num++;
+ }
+
+ ok(num >= 4, "Expected at least 4 messages but %d were processed\n", num);
+ }
+ return hr;
}
static HRESULT WINAPI DropSource_GiveFeedback(
@@ -701,17 +729,20 @@ static void test_DoDragDrop(void)
GetWindowRect(hwnd, &rect);
ok(SetCursorPos(rect.left+50, rect.top+50), "SetCursorPos failed\n");
- for (seq = 0; seq < ARRAY_SIZE(call_lists); seq++)
+ for (test_reentrance = 0; test_reentrance < 2; test_reentrance++)
{
- DWORD effect_in;
- trace("%d\n", seq);
- call_ptr = call_lists[seq];
- effect_in = call_ptr->set_param;
- call_ptr++;
-
- hr = DoDragDrop(&DataObject, &DropSource, effect_in, &effect);
- check_expect(DoDragDrop_ret, hr, NULL);
- check_expect(DoDragDrop_effect_out, effect, NULL);
+ for (seq = 0; seq < ARRAY_SIZE(call_lists); seq++)
+ {
+ DWORD effect_in;
+ trace("%d\n", seq);
+ call_ptr = call_lists[seq];
+ effect_in = call_ptr->set_param;
+ call_ptr++;
+
+ hr = DoDragDrop(&DataObject, &DropSource, effect_in, &effect);
+ check_expect(DoDragDrop_ret, hr, NULL);
+ check_expect(DoDragDrop_effect_out, effect, NULL);
+ }
}
OleUninitialize();
More information about the wine-cvs
mailing list