[PATCH 0/1] MR11413: user32: Release drop target at the end of drag_drop_drop and drag_drop_leave.
Change-Id: I81fe6705abca29b1d18213dcb7033420b7ceb0ed The drop_target reference obtained from get_droptarget_pointer() was not released on every path where it was acquired: - In drag_drop_drop, IDropTarget_Release() was only called in the DragLeave branch (effect == DROPEFFECT_NONE). When IDropTarget::Drop was called instead (effect != DROPEFFECT_NONE), the marshalled DropTargetWrapper was leaked on both the Drop success and Drop failure paths. - In drag_drop_leave, drop_target was never released at all, leaking the DropTargetWrapper and skipping IDropTarget::DragLeave when the DnD operation was cancelled while a target was entered. Move the release into a single cleanup at the end of each function, so the target is released exactly once on every path where it was acquired, and call IDropTarget::DragLeave() from drag_drop_leave before releasing to keep the DropTarget state consistent with the DragEnter that was issued during the drag. Regular tests cannot cover this path (or behave identically before/after the fix), so I wrote a demo to verify: (1) second drag-enter fails, (2) re-entry fails after drag cancellation. [drop_receiver.exe](/uploads/eab9455bd3b1ed81096152484b489611/drop_receiver.exe) [drop_receiver.c](/uploads/02a330b75895a6d6610a8c24f54a4128/drop_receiver.c) -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11413
From: zhangzhou <zhangzhou@uniontech.com> Change-Id: I81fe6705abca29b1d18213dcb7033420b7ceb0ed --- dlls/user32/clipboard.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/dlls/user32/clipboard.c b/dlls/user32/clipboard.c index 3c3ba7c584c..4a05d40dc1e 100644 --- a/dlls/user32/clipboard.c +++ b/dlls/user32/clipboard.c @@ -1158,7 +1158,14 @@ void drag_drop_leave(void) TRACE("DND Operation canceled\n"); - if ((object = get_data_object( TRUE ))) IDataObject_Release( &object->IDataObject_iface ); + if (!(object = get_data_object( TRUE ))) return; + if (object->drop_target) + { + IDropTarget_DragLeave( object->drop_target ); + IDropTarget_Release( object->drop_target ); + object->drop_target = NULL; + } + IDataObject_Release( &object->IDataObject_iface ); } DWORD drag_drop_drag( HWND hwnd, POINT point, DWORD effect ) @@ -1276,8 +1283,6 @@ DWORD drag_drop_drop( HWND hwnd ) { HRESULT hr = IDropTarget_DragLeave( object->drop_target ); if (FAILED(hr)) WARN( "IDropTarget_DragLeave returned %#lx\n", hr ); - IDropTarget_Release( object->drop_target ); - object->drop_target = NULL; } if (drop_file) @@ -1306,6 +1311,12 @@ DWORD drag_drop_drop( HWND hwnd ) } } + if (object->drop_target) + { + IDropTarget_Release( object->drop_target ); + object->drop_target = NULL; + } + TRACE("effectRequested(0x%lx) accept(%d) performed(0x%lx) at x(%ld),y(%ld)\n", object->target_effect, accept, effect, object->target_pos.x, object->target_pos.y); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11413
participants (2)
-
zhangzhou -
zhou zhang (@zhouzhang)