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/Common/Language.xml | 1 + src/Format/Tcformat.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- src/Format/Tcformat.h | 2 +- 3 files changed, 44 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/Common/Language.xml b/src/Common/Language.xml index 9073dc1e..9c0e4fae 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1424,6 +1424,7 @@ Pasted text truncated because the password maximum length is 64 characters Password already reached its maximum length of 64 characters.\nNo additional character is allowed. Select the language to use during the installation: + ERROR: The size of the file container is larger than the available free space on disk. 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()) { diff --git a/src/Format/Tcformat.h b/src/Format/Tcformat.h index 183f17f6..caaf2c28 100644 --- a/src/Format/Tcformat.h +++ b/src/Format/Tcformat.h @@ -42,7 +42,7 @@ static void LoadPage ( HWND hwndDlg , int nPageNo ); __int64 PrintFreeSpace ( HWND hwndTextBox , wchar_t *lpszDrive , PLARGE_INTEGER lDiskFree ); void DisplaySizingErrorText ( HWND hwndTextBox ); void EnableDisableFileNext ( HWND hComboBox , HWND hMainButton ); -BOOL QueryFreeSpace ( HWND hwndDlg , HWND hwndTextBox , BOOL display ); +BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display, LONGLONG *pFreeSpaceValue, BOOL* pbIsSparseFilesSupported); static BOOL FinalPreTransformPrompts (void); void UpdateLastDialogId (void); void HandleOldAssignedDriveLetter (void); -- cgit v1.2.3