[SHELL32] Don't show error when closing disk prop sheet (#144)
[reactos.git] / dll / win32 / shell32 / dialogs / drive.cpp
index 5c99f25..3afbe80 100644 (file)
@@ -2,6 +2,7 @@
  *                 Shell Library Functions
  *
  * Copyright 2005 Johannes Anderwald
+ * Copyright 2017 Katayama Hirofumi MZ
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -91,6 +92,16 @@ GetDefaultClusterSize(LPWSTR szFs, PDWORD pClusterSize, PULARGE_INTEGER TotalNum
         else
             ClusterSize = 2048;
     }
+    else if (!wcsicmp(szFs, L"EXT2"))
+    {
+        // auto block size calculation
+        ClusterSize = 0;
+    }
+    else if (!wcsicmp(szFs, L"BtrFS"))
+    {
+        // auto block size calculation
+        ClusterSize = 0;
+    }
     else
         return FALSE;
 
@@ -117,14 +128,15 @@ typedef struct _DRIVE_PROP_PAGE
     UINT DriveType;
 } DRIVE_PROP_PAGE;
 
-BOOL
-SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST *apidl)
+HRESULT
+SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, PCUITEMID_CHILD_ARRAY apidl)
 {
     HPSXA hpsx = NULL;
     HPROPSHEETPAGE hpsp[MAX_PROPERTY_SHEET_PAGE];
     PROPSHEETHEADERW psh;
     CComObject<CDrvDefExt> *pDrvDefExt = NULL;
-    
+    WCHAR wszName[256];
+
     ZeroMemory(&psh, sizeof(PROPSHEETHEADERW));
     psh.dwSize = sizeof(PROPSHEETHEADERW);
     psh.dwFlags = 0; // FIXME: make it modeless
@@ -132,18 +144,17 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST
     psh.nStartPage = 0;
     psh.phpage = hpsp;
 
-    WCHAR wszName[256];
-    if (GetVolumeInformationW(pwszDrive, wszName, sizeof(wszName) / sizeof(WCHAR), NULL, NULL, NULL, NULL, 0))
+    LPITEMIDLIST completePidl = ILCombine(pidlFolder, apidl[0]);
+    if (!completePidl)
+        return E_OUTOFMEMORY;
+
+    if (ILGetDisplayNameExW(NULL, completePidl, wszName, ILGDN_NORMAL))
     {
         psh.pszCaption = wszName;
         psh.dwFlags |= PSH_PROPTITLE;
-        if (wszName[0] == UNICODE_NULL)
-        {
-            /* FIXME: check if disk is a really a local hdd */
-            UINT i = LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, wszName, sizeof(wszName) / sizeof(WCHAR) - 6);
-            StringCchPrintf(wszName + i, sizeof(wszName) / sizeof(WCHAR) - i, L" (%s)", pwszDrive);
-        }
     }
+    
+    ILFree(completePidl);
 
     CComPtr<IDataObject> pDataObj;
     HRESULT hr = SHCreateDataObject(pidlFolder, 1, apidl, NULL, IID_PPV_ARG(IDataObject, &pDataObj));
@@ -169,16 +180,19 @@ SH_ShowDriveProperties(WCHAR *pwszDrive, LPCITEMIDLIST pidlFolder, LPCITEMIDLIST
             SHAddFromPropSheetExtArray(hpsx, (LPFNADDPROPSHEETPAGE)AddPropSheetPageCallback, (LPARAM)&psh);
     }
 
-    HWND hwnd = (HWND)PropertySheetW(&psh);
+    // NOTE: Currently property sheet is modal. If we make it modeless, then it returns HWND.
+    INT_PTR ret = PropertySheetW(&psh);
 
     if (hpsx)
         SHDestroyPropSheetExtArray(hpsx);
     if (pDrvDefExt)
         pDrvDefExt->Release();
 
-    if (!hwnd)
-        return FALSE;
-    return TRUE;
+    if (ret > 0)
+        return S_OK;
+    if (ret == 0)
+        return S_FALSE;
+    return E_FAIL;
 }
 
 static VOID
@@ -200,7 +214,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
     if (SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)wszBuf) == CB_ERR)
         return;
 
-    szDrive[0] = pContext->Drive + 'A';
+    szDrive[0] = pContext->Drive + L'A';
 
     if (!GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
         return;
@@ -215,7 +229,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
             return;
         }
 
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, sizeof(wszBuf) / sizeof(WCHAR)))
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
         {
             hDlgCtrl = GetDlgItem(hwndDlg, 28680);
             SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
@@ -224,6 +238,9 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
                 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
             SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
         }
+
+        SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0);
+        EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE);
     }
     else if (!wcsicmp(wszBuf, L"FAT32"))
     {
@@ -234,7 +251,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
             return;
         }
 
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, sizeof(wszBuf) / sizeof(WCHAR)))
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
         {
             hDlgCtrl = GetDlgItem(hwndDlg, 28680);
             SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
@@ -243,6 +260,9 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
                 SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
             SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
         }
+
+        SendMessageW(GetDlgItem(hwndDlg, 28675), BM_SETCHECK, BST_UNCHECKED, 0);
+        EnableWindow(GetDlgItem(hwndDlg, 28675), FALSE);
     }
     else if (!wcsicmp(wszBuf, L"NTFS"))
     {
@@ -254,7 +274,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
         }
 
         hDlgCtrl = GetDlgItem(hwndDlg, 28680);
-        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, sizeof(wszBuf) / sizeof(WCHAR)))
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
         {
             SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
             lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
@@ -266,7 +286,7 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
         for (lIndex = 0; lIndex < 4; lIndex++)
         {
             TotalNumberOfBytes.QuadPart = ClusterSize;
-            if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, sizeof(wszBuf) / sizeof(WCHAR)))
+            if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, wszBuf, _countof(wszBuf)))
             {
                 lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
                 if (lIndex != CB_ERR)
@@ -274,6 +294,50 @@ InsertDefaultClusterSizeForFs(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
             }
             ClusterSize *= 2;
         }
+
+        EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
+    }
+    else if (!wcsicmp(wszBuf, L"EXT2"))
+    {
+        if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
+        {
+            TRACE("EXT2 is not supported on hdd larger than 32T current %lu\n", TotalNumberOfBytes.QuadPart);
+            SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
+            return;
+        }
+
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
+        {
+            hDlgCtrl = GetDlgItem(hwndDlg, 28680);
+            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
+            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
+            if (lIndex != CB_ERR)
+                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
+        }
+
+        EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
+    }
+    else if (!wcsicmp(wszBuf, L"BtrFS"))
+    {
+        if (!GetDefaultClusterSize(wszBuf, &ClusterSize, &TotalNumberOfBytes))
+        {
+            TRACE("BtrFS is not supported on hdd larger than 16E current %lu\n", TotalNumberOfBytes.QuadPart);
+            SendMessageW(hDlgCtrl, CB_DELETESTRING, iSelIndex, 0);
+            return;
+        }
+
+        if (LoadStringW(shell32_hInstance, IDS_DEFAULT_CLUSTER_SIZE, wszBuf, _countof(wszBuf)))
+        {
+            hDlgCtrl = GetDlgItem(hwndDlg, 28680);
+            SendMessageW(hDlgCtrl, CB_RESETCONTENT, 0, 0);
+            lIndex = SendMessageW(hDlgCtrl, CB_ADDSTRING, 0, (LPARAM)wszBuf);
+            if (lIndex != CB_ERR)
+                SendMessageW(hDlgCtrl, CB_SETITEMDATA, lIndex, (LPARAM)ClusterSize);
+            SendMessageW(hDlgCtrl, CB_SETCURSEL, 0, 0);
+        }
+
+        EnableWindow(GetDlgItem(hwndDlg, 28675), TRUE);
     }
     else
     {
@@ -296,17 +360,17 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
     BOOLEAN Latest;
     HWND hwndFileSystems;
 
-    cchText = GetWindowTextW(hwndDlg, szText, sizeof(szText) / sizeof(WCHAR) - 1);
+    cchText = GetWindowTextW(hwndDlg, szText, _countof(szText) - 1);
     if (cchText < 0)
         cchText = 0;
     szText[cchText++] = L' ';
     szDrive[0] = pContext->Drive + L'A';
-    if (GetVolumeInformationW(szDrive, &szText[cchText], (sizeof(szText) / sizeof(WCHAR)) - cchText, NULL, NULL, NULL, szFs, sizeof(szFs) / sizeof(WCHAR)))
+    if (GetVolumeInformationW(szDrive, &szText[cchText], _countof(szText) - cchText, NULL, NULL, NULL, szFs, _countof(szFs)))
     {
         if (szText[cchText] == UNICODE_NULL)
         {
             /* load default volume label */
-            cchText += LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchText], (sizeof(szText) / sizeof(WCHAR)) - cchText);
+            cchText += LoadStringW(shell32_hInstance, IDS_DRIVE_FIXED, &szText[cchText], _countof(szText) - cchText);
         }
         else
         {
@@ -316,14 +380,14 @@ InitializeFormatDriveDlg(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
         }
     }
 
-    StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c)", szDrive[0]);
+    StringCchPrintfW(szText + cchText, _countof(szText) - cchText, L" (%c:)", szDrive[0]);
 
     /* set window text */
     SetWindowTextW(hwndDlg, szText);
 
     if (GetDiskFreeSpaceExW(szDrive, &FreeBytesAvailableUser, &TotalNumberOfBytes, NULL))
     {
-        if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, sizeof(szText) / sizeof(WCHAR)))
+        if (StrFormatByteSizeW(TotalNumberOfBytes.QuadPart, szText, _countof(szText)))
         {
             /* add drive capacity */
             SendDlgItemMessageW(hwndDlg, 28673, CB_ADDSTRING, 0, (LPARAM)szText);
@@ -413,9 +477,11 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
     HWND hDlgCtrl;
     BOOL QuickFormat;
     DWORD ClusterSize;
+    DWORD DriveType;
+    FMIFS_MEDIA_FLAG MediaFlag = FMIFS_HARDDISK;
 
     /* set volume path */
-    szDrive[0] = pContext->Drive;
+    szDrive[0] = pContext->Drive + L'A';
 
     /* get filesystem */
     hDlgCtrl = GetDlgItem(hwndDlg, 28677);
@@ -426,7 +492,7 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
         return;
     }
     Length = SendMessageW(hDlgCtrl, CB_GETLBTEXTLEN, iSelIndex, 0);
-    if ((int)Length == CB_ERR || Length + 1 > sizeof(szFileSys) / sizeof(WCHAR))
+    if ((int)Length == CB_ERR || Length + 1 > _countof(szFileSys))
     {
         FIXME("\n");
         return;
@@ -434,17 +500,17 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
 
     /* retrieve the file system */
     SendMessageW(hDlgCtrl, CB_GETLBTEXT, iSelIndex, (LPARAM)szFileSys);
-    szFileSys[(sizeof(szFileSys)/sizeof(WCHAR))-1] = L'\0';
+    szFileSys[_countof(szFileSys)-1] = L'\0';
 
     /* retrieve the volume label */
     hDlgCtrl = GetWindow(hwndDlg, 28679);
     Length = SendMessageW(hDlgCtrl, WM_GETTEXTLENGTH, 0, 0);
-    if (Length + 1 > sizeof(szLabel) / sizeof(WCHAR))
+    if (Length + 1 > _countof(szLabel))
     {
         FIXME("\n");
         return;
     }
-    SendMessageW(hDlgCtrl, WM_GETTEXT, sizeof(szLabel) / sizeof(WCHAR), (LPARAM)szLabel);
+    SendMessageW(hDlgCtrl, WM_GETTEXT, _countof(szLabel), (LPARAM)szLabel);
     szLabel[(sizeof(szLabel)/sizeof(WCHAR))-1] = L'\0';
 
     /* check for quickformat */
@@ -479,8 +545,32 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
      */
     FormatDrvDialog = hwndDlg;
 
+    /* See if the drive is removable or not */
+    DriveType = GetDriveTypeW(szDrive);
+    switch (DriveType)
+    {
+        case DRIVE_UNKNOWN:
+        case DRIVE_REMOTE:
+        case DRIVE_CDROM:
+        case DRIVE_NO_ROOT_DIR:
+        {
+            FIXME("\n");
+            return;
+        }
+
+        case DRIVE_REMOVABLE:
+            MediaFlag = FMIFS_FLOPPY;
+            break;
+
+        case DRIVE_FIXED:
+        case DRIVE_RAMDISK:
+            MediaFlag = FMIFS_HARDDISK;
+            break;
+    }
+
+    /* Format the drive */
     FormatEx(szDrive,
-             FMIFS_HARDDISK, /* FIXME */
+             MediaFlag,
              szFileSys,
              szLabel,
              QuickFormat,
@@ -499,7 +589,7 @@ FormatDrive(HWND hwndDlg, PFORMAT_DRIVE_CONTEXT pContext)
     }
     else
     {
-        pContext->Result =  FALSE;
+        pContext->Result = FALSE;
     }
 }