Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Pazderski2019-08-11 16:24:20 +0000
committerPaul Pazderski2019-08-15 17:43:25 +0000
commit72476dd4c1385c8df23092b19d585fecc8f575f4 (patch)
tree4fd88c77535decd64640bcc318a28927fa5c16e7
parent1d0010bad752650b9e59e8f4bdc76ba758e9a108 (diff)
downloadeclipse.platform.swt-72476dd4c1385c8df23092b19d585fecc8f575f4.tar.gz
eclipse.platform.swt-72476dd4c1385c8df23092b19d585fecc8f575f4.tar.xz
eclipse.platform.swt-72476dd4c1385c8df23092b19d585fecc8f575f4.zip
Bug 549661 - [Win32][DND] FileTransfer can not drop on Portable Device
First problem: dropping on Portable Device does not like the fake PIDLs which were used before. Second problem: dropping on Portable Device query for the data after the drag and drop operation is finished. Change-Id: Ic5f17e12c070759fb957d5010cd8cec5165fc8ff Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java25
-rw-r--r--bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_custom.cpp13
2 files changed, 34 insertions, 4 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
index c4c4e09894..3615995c1a 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT Drag and Drop/win32/org/eclipse/swt/dnd/DragSource.java
@@ -391,6 +391,31 @@ private void drag(Event dragEvent) {
}
}
+ /*
+ * Bug 549643: a proper drag&drop operation is finished when the DoDragDrop loop/function returns.
+ * Unfortunately the Windows Explorer is ignoring this fact while showing a Portable Device
+ * (e.g. Smartphone attached through MTP). I.e. dropping a file on Windows Explorer in this
+ * situation will query the iDataObject at least once for its data _after_ DoDragDrop finished.
+ * Revoking this getData request will fail the drop.
+ *
+ * This behavior can succeeds because most applications store the actual data to transfer in
+ * the IDataObject and since its lifetime is managed through ref counting it can return the data
+ * even after the drag&drop finished. In SWT the data to transfer is not stored in the IDataObject
+ * but instead obtained on demand through a DND.DragSetData event. Additional some clients release
+ * the data to drag in the DragEnd event and therefore do not like to get such events after DragEnd.
+ *
+ * That's why the next few lines exist. In case the DropTarget has not yet released the IDataObject
+ * (which is the case for the faulty Windows Explorer described above) we delay the DragEnd event in
+ * case an additional DragSetData is triggered. Since the DropTarget can be any (faulty or malicious)
+ * application maybe never releasing the object wait is combined with a tight timeout.
+ */
+ final long start = System.currentTimeMillis();
+ while (refCount > 0 && System.currentTimeMillis() - start < 1000) {
+ if (!display.readAndDispatch()) {
+ try { Thread.sleep(10); }
+ catch (InterruptedException e) { break; }
+ }
+ }
disposeCOMInterfaces();
event = new DNDEvent();
diff --git a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_custom.cpp b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_custom.cpp
index e4509e4c94..791d8df1be 100644
--- a/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_custom.cpp
+++ b/bundles/org.eclipse.swt/Eclipse SWT PI/win32/library/com_custom.cpp
@@ -71,13 +71,18 @@ private:
};
/*
- * An extended version of SHParseDisplayName which ignores the attribute query part
- * and use bind context to support creation of simple PIDLs for non existing paths.
+ * An extended version of SHParseDisplayName which use bind context to support
+ * creation of simple PIDLs in case the normal PIDL creation failed.
+ * (most likley due to non existing file/directory)
*/
extern "C" HRESULT PathToPIDL(PCWSTR pszName, PIDLIST_ABSOLUTE *ppidl)
{
if (!ppidl) return E_FAIL;
*ppidl = nullptr;
+
+ SFGAOF sfgao = 0;
+ HRESULT hr = SHParseDisplayName(pszName, nullptr, ppidl, sfgao, &sfgao);
+ if (hr == S_OK) return hr;
IFileSystemBindData *pfsbd = new CFileSysBindData();
if (!pfsbd) return E_OUTOFMEMORY;
@@ -87,7 +92,7 @@ extern "C" HRESULT PathToPIDL(PCWSTR pszName, PIDLIST_ABSOLUTE *ppidl)
IBindCtx* pbc;
- HRESULT hr = CreateBindCtx(0, &pbc);
+ hr = CreateBindCtx(0, &pbc);
if (hr == S_OK)
{
BIND_OPTS bo = { sizeof(bo), 0, STGM_CREATE, 0 };
@@ -97,7 +102,7 @@ extern "C" HRESULT PathToPIDL(PCWSTR pszName, PIDLIST_ABSOLUTE *ppidl)
hr = pbc->RegisterObjectParam(STR_FILE_SYS_BIND_DATA, pfsbd);
if (hr == S_OK)
{
- SFGAOF sfgao = 0;
+ sfgao = 0;
hr = SHParseDisplayName(pszName, pbc, ppidl, sfgao, &sfgao);
}
}

Back to the top