diff --git a/dll/win32/shell32/dialogs/item_prop.cpp b/dll/win32/shell32/dialogs/item_prop.cpp index bcc6473144d..75039293c3c 100644 --- a/dll/win32/shell32/dialogs/item_prop.cpp +++ b/dll/win32/shell32/dialogs/item_prop.cpp @@ -27,7 +27,7 @@ struct ShellPropSheetDialog HKEY *hKeys, UINT *cKeys); static HRESULT Show(const CLSID *pClsidDefault, IDataObject *pDO, - PFNINITIALIZE InitFunc, LPCWSTR InitString, HANDLE hEvent = NULL) + PFNINITIALIZE InitFunc, LPCWSTR InitString) { HRESULT hr; CRegKeyHandleArray keys; @@ -36,8 +36,6 @@ struct ShellPropSheetDialog WCHAR szCaption[MAX_PATH], *pszCaption = NULL; if (SUCCEEDED(SHELL_GetCaptionFromDataObject(pDO, szCaption, _countof(szCaption)))) pszCaption = szCaption; - if (hEvent) - SetEvent(hEvent); hr = SHOpenPropSheetW(pszCaption, keys, keys, pClsidDefault, pDO, NULL, NULL) ? S_OK : E_FAIL; return hr; } @@ -96,7 +94,8 @@ struct ShellPropSheetDialog if (hEvent) { DWORD index; - // Pump COM messages until InitFunc is done (for CORE-19933) + // Pump COM messages until the thread can create its own IDataObject (for CORE-19933). + // SHOpenPropSheetW is modal and we cannot wait for it to complete. CoWaitForMultipleHandles(COWAIT_DEFAULT, INFINITE, 1, &hEvent, &index); CloseHandle(hEvent); } @@ -111,10 +110,14 @@ struct ShellPropSheetDialog static DWORD CALLBACK ShowPropertiesThread(LPVOID Param) { DATA *pData = (DATA*)Param; - CComPtr pDO; + CComPtr pDO, pLocalDO; if (pData->pObjStream) CoGetInterfaceAndReleaseStream(pData->pObjStream, IID_PPV_ARG(IDataObject, &pDO)); - Show(pData->pClsidDefault, pDO, pData->InitFunc, pData->InitString, pData->hEvent); + if (pDO && SUCCEEDED(SHELL_CloneDataObject(pDO, &pLocalDO))) + pDO = pLocalDO; + if (pData->hEvent) + SetEvent(pData->hEvent); + Show(pData->pClsidDefault, pDO, pData->InitFunc, pData->InitString); FreeData(pData); return 0; } diff --git a/dll/win32/shell32/precomp.h b/dll/win32/shell32/precomp.h index 48c636fe9f1..6d65aeac056 100644 --- a/dll/win32/shell32/precomp.h +++ b/dll/win32/shell32/precomp.h @@ -297,6 +297,7 @@ HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl); PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index); PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UINT Index); +HRESULT SHELL_CloneDataObject(_In_ IDataObject *pDO, _Out_ IDataObject **ppDO); EXTERN_C HRESULT IUnknown_InitializeCommand( diff --git a/dll/win32/shell32/shldataobject.cpp b/dll/win32/shell32/shldataobject.cpp index 3a7d651424f..728cca0dbf3 100644 --- a/dll/win32/shell32/shldataobject.cpp +++ b/dll/win32/shell32/shldataobject.cpp @@ -111,3 +111,22 @@ PIDLIST_ABSOLUTE SHELL_DataObject_ILCloneFullItem(_In_ IDataObject *pDO, _In_ UI CDataObjectHIDA cida(pDO); return SUCCEEDED(cida.hr()) ? SHELL_CIDA_ILCloneFull(cida, Index) : NULL; } + +HRESULT SHELL_CloneDataObject(_In_ IDataObject *pDO, _Out_ IDataObject **ppDO) +{ + *ppDO = NULL; + CDataObjectHIDA cida(pDO); + HRESULT hr = cida.hr(); + if (SUCCEEDED(hr)) + { + PCUITEMID_CHILD items = HIDA_GetPIDLItem(cida, 0); + hr = SHCreateFileDataObject(HIDA_GetPIDLFolder(cida), cida->cidl, &items, NULL, ppDO); + if (SUCCEEDED(hr)) + { + POINT pt; + if (SUCCEEDED(DataObject_GetOffset(pDO, &pt))) + DataObject_SetOffset(*ppDO, &pt); + } + } + return hr; +}