From 0bd933c28c69d1d6b21fbe7385dd7670dcb0632e Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Mon, 8 Jul 2024 23:11:02 +0900 Subject: [PATCH] [SHELL32] Drive Property Sheet: Run in another thread (#7107) The drive property sheet was modal, so it used to lock the main thread. This PR will unlock by using another thread. JIRA issue: CORE-4217 JIRA issue: CORE-11547 In dll/win32/shell32/dialogs/drive.cpp: - Add DRIVE_PROP_DATA structure. - Call SHCreateThread function in SH_ShowDriveProperties function. - Clean up the data when they should be released. --- dll/win32/shell32/dialogs/drive.cpp | 48 +++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/dll/win32/shell32/dialogs/drive.cpp b/dll/win32/shell32/dialogs/drive.cpp index ed57ccc9793..3bb5fe58c4f 100644 --- a/dll/win32/shell32/dialogs/drive.cpp +++ b/dll/win32/shell32/dialogs/drive.cpp @@ -166,9 +166,22 @@ typedef struct _DRIVE_PROP_PAGE UINT DriveType; } DRIVE_PROP_PAGE; -BOOL -SH_ShowDriveProperties(WCHAR *pwszDrive, IDataObject *pDataObj) +struct DRIVE_PROP_DATA { + PWSTR pwszDrive; + IStream *pStream; +}; + +static DWORD WINAPI +ShowDrivePropThreadProc(LPVOID pParam) +{ + CHeapPtr pPropData((DRIVE_PROP_DATA *)pParam); + CHeapPtr pwszDrive(pPropData->pwszDrive); + + // Unmarshall IDataObject from IStream + CComPtr pDataObj; + CoGetInterfaceAndReleaseStream(pPropData->pStream, IID_PPV_ARG(IDataObject, &pDataObj)); + HPSXA hpsx = NULL; HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE]; CComObject *pDrvDefExt = NULL; @@ -234,6 +247,37 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, IDataObject *pDataObj) return ret != -1; } +BOOL +SH_ShowDriveProperties(WCHAR *pwszDrive, IDataObject *pDataObj) +{ + HRESULT hr = SHStrDupW(pwszDrive, &pwszDrive); + if (FAILED_UNEXPECTEDLY(hr)) + return FALSE; + + // Prepare data for thread + DRIVE_PROP_DATA *pData = (DRIVE_PROP_DATA *)SHAlloc(sizeof(*pData)); + if (!pData) + { + SHFree(pwszDrive); + return FALSE; + } + pData->pwszDrive = pwszDrive; + + // Marshall IDataObject to IStream + hr = CoMarshalInterThreadInterfaceInStream(IID_IDataObject, pDataObj, &pData->pStream); + if (SUCCEEDED(hr)) + { + // Run a property sheet in another thread + if (SHCreateThread(ShowDrivePropThreadProc, pData, CTF_COINIT, NULL)) + return TRUE; // Success + + pData->pStream->Release(); + } + SHFree(pData); + SHFree(pwszDrive); + return FALSE; // Failed +} + static VOID InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext) {