From 9376bc8f5147c892769bddfc738563b9790d4f07 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 22 Aug 2018 17:52:28 +0200 Subject: Windows: Add check on size of file container to ensure it's smaller than available free space on disk when this is required. --- src/Format/Tcformat.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'src/Format/Tcformat.c') diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index 2f8b9b2f..f2493b08 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -287,6 +287,9 @@ SYSENC_MULTIBOOT_CFG SysEncMultiBootCfg; wchar_t SysEncMultiBootCfgOutcome [4096] = {L'N',L'/',L'A',0}; volatile int NonSysInplaceEncStatus = NONSYS_INPLACE_ENC_STATUS_NONE; +LONGLONG nAvailableFreeSpace = -1; +BOOL bIsSparseFilesSupportedByHost = FALSE; + vector DeferredNonSysInPlaceEncDevices; // specific definitions and implementation for support of resume operation @@ -1538,6 +1541,12 @@ static void VerifySizeAndUpdate (HWND hwndDlg, BOOL bUpdate) { if (lTmp * i > (bHiddenVolHost ? TC_MAX_HIDDEN_VOLUME_HOST_SIZE : TC_MAX_VOLUME_SIZE)) bEnable = FALSE; + else if (!bDevice && (lTmp * i > nAvailableFreeSpace) && (!bIsSparseFilesSupportedByHost || bHiddenVolHost)) + { + // we check container size against available free space only when creating dynamic volume is not possible + // which is the case if filesystem doesn't allow sparce file or if we are creating outer volume of a hidden volume + bEnable = FALSE; + } } } @@ -3366,14 +3375,23 @@ BOOL GetFileVolSize (HWND hwndDlg, unsigned __int64 *size) } -BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) +BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display, LONGLONG *pFreeSpaceValue, BOOL* pbIsSparceFilesSupported) { + if (pFreeSpaceValue) + *pFreeSpaceValue = 0; + + if (pbIsSparceFilesSupported) + *pbIsSparceFilesSupported = FALSE; + if (bHiddenVol && !bHiddenVolHost) // If it's a hidden volume { LARGE_INTEGER lDiskFree; lDiskFree.QuadPart = nMaximumHiddenVolSize; + if (pFreeSpaceValue) + *pFreeSpaceValue = nMaximumHiddenVolSize; + if (display) PrintFreeSpace (hwndTextBox, NULL, &lDiskFree); @@ -3382,6 +3400,7 @@ BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) else if (bDevice == FALSE) { wchar_t root[TC_MAX_PATH]; + DWORD fileSystemFlags = 0; ULARGE_INTEGER free; if (!GetVolumePathName (szFileName, root, ARRAYSIZE (root))) @@ -3390,6 +3409,14 @@ BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) return FALSE; } + if ( pbIsSparceFilesSupported + && GetVolumeInformation (root, NULL, 0, NULL, NULL, &fileSystemFlags, NULL, 0) + && (fileSystemFlags & FILE_SUPPORTS_SPARSE_FILES) + ) + { + *pbIsSparceFilesSupported = TRUE; + } + if (!GetDiskFreeSpaceEx (root, &free, 0, 0)) { if (display) @@ -3402,6 +3429,9 @@ BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) LARGE_INTEGER lDiskFree; lDiskFree.QuadPart = free.QuadPart; + if (pFreeSpaceValue) + *pFreeSpaceValue = free.QuadPart; + if (display) PrintFreeSpace (hwndTextBox, root, &lDiskFree); @@ -3463,6 +3493,9 @@ BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) nVolumeSize = lDiskFree.QuadPart; + if (pFreeSpaceValue) + *pFreeSpaceValue = lDiskFree.QuadPart; + if (display) nMultiplier = PrintFreeSpace (hwndTextBox, szDiskFile, &lDiskFree); @@ -4169,7 +4202,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa SendMessage (GetDlgItem (hwndDlg, IDC_SPACE_LEFT), WM_SETFONT, (WPARAM) hBoldFont, (LPARAM) TRUE); SendMessage (GetDlgItem (hwndDlg, IDC_SIZEBOX), EM_LIMITTEXT, 12, 0); - if(!QueryFreeSpace (hwndDlg, GetDlgItem (hwndDlg, IDC_SPACE_LEFT), TRUE)) + if(!QueryFreeSpace (hwndDlg, GetDlgItem (hwndDlg, IDC_SPACE_LEFT), TRUE, &nAvailableFreeSpace, &bIsSparseFilesSupportedByHost)) { nUIVolumeSize=0; nVolumeSize=0; @@ -7348,7 +7381,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (bDevice) { - if(!QueryFreeSpace (hwndDlg, GetDlgItem (hwndDlg, IDC_SPACE_LEFT), FALSE)) + if(!QueryFreeSpace (hwndDlg, GetDlgItem (hwndDlg, IDC_SPACE_LEFT), FALSE, NULL, NULL)) { MessageBoxW (hwndDlg, GetString ("CANT_GET_VOLSIZE"), lpszTitle, ICON_HAND); NormalCursor (); @@ -8315,6 +8348,12 @@ retryCDDriveCheck: quickFormat = IsButtonChecked (GetDlgItem (hCurPage, IDC_QUICKFORMAT)); + if (!quickFormat && !bDevice && !(bHiddenVol && !bHiddenVolHost) && (nVolumeSize > (ULONGLONG) nAvailableFreeSpace)) + { + Error("VOLUME_TOO_LARGE_FOR_HOST", hwndDlg); + bVolTransformThreadToRun = FALSE; + return 1; + } if (!bHiddenVol && IsHiddenOSRunning()) { -- cgit v1.2.3