[SHELL32] Make SHFormatDrive multi-thread (#2080)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Tue, 26 Nov 2019 09:26:25 +0000 (18:26 +0900)
committerGitHub <noreply@github.com>
Tue, 26 Nov 2019 09:26:25 +0000 (18:26 +0900)
CORE-12756

dll/win32/shell32/dialogs/drive.cpp

index 4742c50..674e81c 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "precomp.h"
+#include <process.h>
 
 WINE_DEFAULT_DEBUG_CHANNEL(shell);
 
@@ -28,6 +29,7 @@ typedef struct
     WCHAR   Drive;
     UINT    Options;
     UINT Result;
+    BOOL bFormattingNow;
 } FORMAT_DRIVE_CONTEXT, *PFORMAT_DRIVE_CONTEXT;
 
 EXTERN_C HPSXA WINAPI SHCreatePropSheetExtArrayEx(HKEY hKey, LPCWSTR pszSubKey, UINT max_iface, IDataObject *pDataObj);
@@ -577,6 +579,36 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
     }
 }
 
+struct FORMAT_DRIVE_PARAMS
+{
+    HWND hwndDlg;
+    PFORMAT_DRIVE_CONTEXT pContext;
+};
+
+static unsigned __stdcall DoFormatDrive(void *args)
+{
+    FORMAT_DRIVE_PARAMS *pParams = reinterpret_cast<FORMAT_DRIVE_PARAMS *>(args);
+    HWND hwndDlg = pParams->hwndDlg;
+    PFORMAT_DRIVE_CONTEXT pContext = pParams->pContext;
+
+    HMENU hSysMenu = GetSystemMenu(hwndDlg, FALSE);
+    EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
+    EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE);
+    EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), FALSE);
+    EnableWindow(GetDlgItem(hwndDlg, 28677), FALSE);
+
+    FormatDrive(hwndDlg, pContext);
+
+    EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
+    EnableWindow(GetDlgItem(hwndDlg, IDCANCEL), TRUE);
+    EnableWindow(GetDlgItem(hwndDlg, 28677), TRUE);
+    EnableMenuItem(hSysMenu, SC_CLOSE, MF_BYCOMMAND | MF_ENABLED);
+    pContext->bFormattingNow = FALSE;
+
+    delete pParams;
+    return 0;
+}
+
 static INT_PTR CALLBACK
 FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
@@ -592,20 +624,40 @@ FormatDriveDlg(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
             switch(LOWORD(wParam))
             {
                 case IDOK:
-                    if (ShellMessageBoxW(shell32_hInstance, hwndDlg, MAKEINTRESOURCEW(IDS_FORMAT_WARNING), MAKEINTRESOURCEW(IDS_FORMAT_TITLE), MB_OKCANCEL | MB_ICONWARNING) == IDOK)
+                    pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                    if (pContext->bFormattingNow)
+                        break;
+
+                    if (ShellMessageBoxW(shell32_hInstance, hwndDlg,
+                                         MAKEINTRESOURCEW(IDS_FORMAT_WARNING),
+                                         MAKEINTRESOURCEW(IDS_FORMAT_TITLE),
+                                         MB_OKCANCEL | MB_ICONWARNING) == IDOK)
                     {
-                        pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
-                        FormatDrive(hwndDlg, pContext);
+                        pContext->bFormattingNow = TRUE;
+
+                        FORMAT_DRIVE_PARAMS *pParams = new FORMAT_DRIVE_PARAMS;
+                        pParams->hwndDlg = hwndDlg;
+                        pParams->pContext = pContext;
+
+                        unsigned tid;
+                        HANDLE hThread = (HANDLE)_beginthreadex(NULL, 0, DoFormatDrive, pParams, 0, &tid);
+                        CloseHandle(hThread);
                     }
                     break;
                 case IDCANCEL:
                     pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                    if (pContext->bFormattingNow)
+                        break;
+
                     EndDialog(hwndDlg, pContext->Result);
                     break;
                 case 28677: // filesystem combo
                     if (HIWORD(wParam) == CBN_SELENDOK)
                     {
                         pContext = (PFORMAT_DRIVE_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER);
+                        if (pContext->bFormattingNow)
+                            break;
+
                         InsertDefaultClusterSizeForFs(hwndDlg, pContext);
                     }
                     break;
@@ -629,10 +681,10 @@ SHFormatDrive(HWND hwnd, UINT drive, UINT fmtID, UINT options)
 
     Context.Drive = drive;
     Context.Options = options;
+    Context.Result = FALSE;
+    Context.bFormattingNow = FALSE;
 
     result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(IDD_FORMAT_DRIVE), hwnd, FormatDriveDlg, (LPARAM)&Context);
 
     return result;
 }
-
-