From 4d7dc3ba25f562bea4be8898f11a97e911c48b99 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Tue, 25 Aug 2015 11:42:01 +0200 Subject: Windows: first implementation of CLI support for creating volumes. --- src/Common/Crypto.c | 4 +- src/Common/Format.c | 24 ++- src/Common/Format.h | 4 +- src/Common/Language.xml | 11 +- src/Common/Password.c | 6 +- src/Common/Password.h | 2 +- src/Format/Tcformat.c | 442 ++++++++++++++++++++++++++++++++++++++++++++---- src/Format/Tcformat.h | 2 +- src/Mount/Mount.c | 2 +- 9 files changed, 443 insertions(+), 54 deletions(-) (limited to 'src') diff --git a/src/Common/Crypto.c b/src/Common/Crypto.c index 0c4d59d1..ead091db 100644 --- a/src/Common/Crypto.c +++ b/src/Common/Crypto.c @@ -450,8 +450,8 @@ int EAGetByName (char *name) do { - EAGetName (n, ea, 0); - if (strcmp (n, name) == 0) + EAGetName (n, ea, 1); + if (_stricmp (n, name) == 0) return ea; } while (ea = EAGetNext (ea)); diff --git a/src/Common/Format.c b/src/Common/Format.c index fe1f271f..3fede6d5 100644 --- a/src/Common/Format.c +++ b/src/Common/Format.c @@ -284,7 +284,7 @@ begin_format: dev = CreateFile (devName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (dev != INVALID_HANDLE_VALUE) { - if (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)) + if (!volParams->bForceOperation && (Silent || (IDNO == MessageBoxW (volParams->hwndDlg, GetString ("DEVICE_IN_USE_FORMAT"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2)))) { nStatus = ERR_DONT_REPORT; goto error; @@ -381,7 +381,7 @@ begin_format: bTimeStampValid = TRUE; } - KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW); + if (volParams->hwndDlg && volParams->bGuiMode) KillTimer (volParams->hwndDlg, TIMER_ID_RANDVIEW); /* Volume header */ @@ -618,8 +618,11 @@ error: if (driveNo == -1) { - MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); - MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + if (!Silent) + { + MessageBoxW (volParams->hwndDlg, GetString ("NO_FREE_DRIVES"), lpszTitle, ICON_HAND); + MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + } nStatus = ERR_NO_FREE_DRIVES; goto fv_end; @@ -634,20 +637,23 @@ error: if (MountVolume (volParams->hwndDlg, driveNo, volParams->volumePath, volParams->password, volParams->pkcs5, volParams->pim, FALSE, FALSE, TRUE, &mountOptions, FALSE, TRUE) < 1) { - MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); - MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + if (!Silent) + { + MessageBoxW (volParams->hwndDlg, GetString ("CANT_MOUNT_VOLUME"), lpszTitle, ICON_HAND); + MessageBoxW (volParams->hwndDlg, GetString ("FORMAT_NTFS_STOP"), lpszTitle, ICON_HAND); + } nStatus = ERR_VOL_MOUNT_FAILED; goto fv_end; } - if (!IsAdmin () && IsUacSupported ()) + if (!Silent && !IsAdmin () && IsUacSupported ()) retCode = UacFormatNtfs (volParams->hwndDlg, driveNo, volParams->clusterSize); else retCode = FormatNtfs (driveNo, volParams->clusterSize); if (retCode != TRUE) { - if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo)) + if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); if (dataAreaSize <= TC_MAX_FAT_SECTOR_COUNT * FormatSectorSize) @@ -669,7 +675,7 @@ error: goto fv_end; } - if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo)) + if (!UnmountVolumeAfterFormatExCall (volParams->hwndDlg, driveNo) && !Silent) MessageBoxW (volParams->hwndDlg, GetString ("CANT_DISMOUNT_VOLUME"), lpszTitle, ICON_HAND); } diff --git a/src/Common/Format.h b/src/Common/Format.h index 20346876..3c39bec4 100644 --- a/src/Common/Format.h +++ b/src/Common/Format.h @@ -38,11 +38,13 @@ typedef struct unsigned int clusterSize; BOOL sparseFileSwitch; BOOL quickFormat; - int sectorSize; + DWORD sectorSize; int *realClusterSize; Password *password; int pim; HWND hwndDlg; + BOOL bForceOperation; + BOOL bGuiMode; } FORMAT_VOL_PARAMETERS; diff --git a/src/Common/Language.xml b/src/Common/Language.xml index df2890e4..27d7874e 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -540,7 +540,16 @@ Note: If you need to securely transfer files from the decoy system to the hidden system, follow these steps:\n1) Start the decoy system.\n2) Save the files to an unencrypted volume or to an outer/normal VeraCrypt volume.\n3) Start the hidden system.\n4) If you saved the files to a VeraCrypt volume, mount it (it will be automatically mounted as read-only).\n5) Copy the files to the hidden system partition or to another hidden volume. Your computer must be restarted.\n\nDo you want to restart it now? An error occurred when obtaining the system encryption status. - Cannot initialize application components for system encryption. + No password specified in the command line. The volume can't be created. + No volume size specified in the command line. The volume can't be created. + The volume file size specified in the command line is incompatible with selected NTFS filesystem. + The volume file size specified in the command line is incompatible with selected FAT32 filesystem. + The filesystem on the target drive doesn't support creating sparse files which is required for dynamic volumes. + Only container files can be created through the command line. + The container file size specified in the command line is greater than the available disk free space. Volume can't be created. + The volume size specified in the command line is too small. The volume can't be created. + The volume size specified in the command line is too big. The volume can't be created. + Cannot initialize application components for system encryption. Failed to initialize the random number generator!\n\n\n(If you report a bug in connection with this, please include the following technical information in the bug report:\n%hs, Last Error = 0x%.8X) Windows Crypto API failed!\n\n\n(If you report a bug in connection with this, please include the following technical information in the bug report:\n%hs, Last Error = 0x%.8X) Unable to initialize the application. Failed to register the Dialog class. diff --git a/src/Common/Password.c b/src/Common/Password.c index 2dfd5373..8b44e7d5 100644 --- a/src/Common/Password.c +++ b/src/Common/Password.c @@ -113,7 +113,7 @@ BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw) } -BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning) +BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning, BOOL bSkipPimWarning) { BOOL bCustomPimSmall = ((pim != 0) && (pim < (bForBoot? 98 : 485)))? TRUE : FALSE; if (passwordLength < PASSWORD_LEN_WARNING) @@ -132,7 +132,7 @@ BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim #ifndef _DEBUG else if (bCustomPimSmall) { - if (MessageBoxW (hwndDlg, GetString ("PIM_SMALL_WARNING"), lpszTitle, MB_YESNO|MB_ICONWARNING|MB_DEFBUTTON2) != IDYES) + if (!bSkipPimWarning && AskWarnNoYes ("PIM_SMALL_WARNING", hwndDlg) != IDYES) return FALSE; } #endif @@ -140,7 +140,7 @@ BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim if ((pim != 0) && (pim > (bForBoot? 98 : 485))) { // warn that mount/boot will take more time - MessageBoxW (hwndDlg, GetString ("PIM_LARGE_WARNING"), lpszTitle, MB_OK|MB_ICONWARNING); + Warning ("PIM_LARGE_WARNING", hwndDlg); } return TRUE; diff --git a/src/Common/Password.h b/src/Common/Password.h index 04221c48..6523e88d 100644 --- a/src/Common/Password.h +++ b/src/Common/Password.h @@ -38,7 +38,7 @@ typedef struct #if defined(_WIN32) && !defined(TC_WINDOWS_DRIVER) void VerifyPasswordAndUpdate ( HWND hwndDlg , HWND hButton , HWND hPassword , HWND hVerify , unsigned char *szPassword , char *szVerify, BOOL keyFilesEnabled ); -BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning); +BOOL CheckPasswordLength (HWND hwndDlg, unsigned __int32 passwordLength, int pim, BOOL bForBoot, BOOL bSkipPasswordWarning, BOOL bSkipPimWarning); BOOL CheckPasswordCharEncoding (HWND hPassword, Password *ptrPw); int ChangePwd (const char *lpszVolume, Password *oldPassword, int old_pkcs5, int old_pim, BOOL truecryptMode, Password *newPassword, int pkcs5, int pim, int wipePassCount, HWND hwndDlg); diff --git a/src/Format/Tcformat.c b/src/Format/Tcformat.c index d520a635..7dd34196 100644 --- a/src/Format/Tcformat.c +++ b/src/Format/Tcformat.c @@ -156,6 +156,8 @@ BOOL DirectNonSysInplaceDecStartMode = FALSE; BOOL DirectNonSysInplaceEncResumeMode = FALSE; BOOL DirectNonSysInplaceDecResumeMode = FALSE; BOOL DirectPromptNonSysInplaceEncResumeMode = FALSE; +BOOL DirectCreationMode = FALSE; + volatile BOOL bInPlaceEncNonSys = FALSE; /* If TRUE, existing data on a non-system partition/volume are to be encrypted (or decrypted if bInPlaceDecNonSys is TRUE) in place (for system encryption, this flag is ignored) */ volatile BOOL bInPlaceDecNonSys = FALSE; /* If TRUE, existing data on a non-system partition/volume are to be decrypted in place (for system encryption, this flag is ignored) */ volatile BOOL bInPlaceEncNonSysResumed = FALSE; /* If TRUE, the wizard is supposed to resume (or has resumed) process of non-system in-place encryption/decryption. */ @@ -236,6 +238,21 @@ int volumePim = 0; BOOL bHistoryCmdLine = FALSE; /* History control is always disabled */ BOOL ComServerMode = FALSE; + +Password CmdVolumePassword = {0}; /* Password passed from command line */ +int CmdVolumeEA = 0; +int CmdVolumePkcs5 = 0; +int CmdVolumePim = 0; +int CmdVolumeFilesystem = FILESYS_NONE; +unsigned __int64 CmdVolumeFileSize = 0; +BOOL CmdSparseFileSwitch = FALSE; + +BOOL bForceOperation = FALSE; + +BOOL bOperationSuccess = FALSE; + +BOOL bGuiMode = TRUE; + int nPbar = 0; /* Control ID of progress bar:- for format code */ char HeaderKeyGUIView [KEY_GUI_VIEW_SIZE]; @@ -385,6 +402,8 @@ static void WipePasswordsAndKeyfiles (void) burn (&volumePassword, sizeof (volumePassword)); burn (&szRawPassword[0], sizeof (szRawPassword)); burn (&volumePim, sizeof (volumePim)); + burn (&CmdVolumePassword, sizeof (CmdVolumePassword)); + burn (&CmdVolumePim, sizeof (CmdVolumePim)); SetWindowText (hPasswordInputField, ""); SetWindowText (hVerifyPasswordInputField, ""); @@ -1458,7 +1477,7 @@ static void VerifySizeAndUpdate (HWND hwndDlg, BOOL bUpdate) i = nMultiplier; lTmp = _atoi64 (szTmp); - int sectorSize = GetFormatSectorSize(); + DWORD sectorSize = GetFormatSectorSize(); uint32 sectorSizeRem = (lTmp * nMultiplier) % sectorSize; if (sectorSizeRem != 0) @@ -2452,7 +2471,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) int nStatus; DWORD dwWin32FormatError; BOOL bHidden; - HWND hwndDlg = (HWND) hwndDlgArg; + HWND hwndDlg = (HWND) hwndDlgArg; volatile FORMAT_VOL_PARAMETERS *volParams = (FORMAT_VOL_PARAMETERS *) malloc (sizeof(FORMAT_VOL_PARAMETERS)); if (volParams == NULL) @@ -2460,20 +2479,25 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) VirtualLock ((LPVOID) volParams, sizeof(FORMAT_VOL_PARAMETERS)); - bVolTransformThreadRunning = TRUE; - bVolTransformThreadToRun = FALSE; + bOperationSuccess = FALSE; + + if (bGuiMode) + { + bVolTransformThreadRunning = TRUE; + bVolTransformThreadToRun = FALSE; + } // Check administrator privileges if (!IsAdmin () && !IsUacSupported ()) { if (fileSystem == FILESYS_NTFS) { - if (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_NTFS"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL) + if (Silent || (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_NTFS"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL)) goto cancel; } if (bDevice) { - if (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_DEVICES"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL) + if (Silent || (MessageBoxW (hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_DEVICES"), lpszTitle, MB_OKCANCEL|MB_ICONWARNING|MB_DEFBUTTON2) == IDCANCEL)) goto cancel; } } @@ -2487,13 +2511,13 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) { wchar_t szTmp[512]; - if (! ((bHiddenVol && !bHiddenVolHost) && errno != EACCES)) // Only ask ask for permission to overwrite an existing volume if we're not creating a hidden volume + if (!bForceOperation && !((bHiddenVol && !bHiddenVolHost) && errno != EACCES)) // Only ask ask for permission to overwrite an existing volume if we're not creating a hidden volume { StringCbPrintfW (szTmp, sizeof szTmp, GetString (errno == EACCES ? "READONLYPROMPT" : "OVERWRITEPROMPT"), szDiskFile); - x = MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2); + x = Silent? IDNO : MessageBoxW (hwndDlg, szTmp, lpszTitle, YES_NO|MB_ICONWARNING|MB_DEFBUTTON2); if (x != IDYES) goto cancel; @@ -2506,7 +2530,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) { if (_chmod (szDiskFile, _S_IREAD | _S_IWRITE) != 0) { - MessageBoxW (hwndDlg, GetString ("ACCESSMODEFAIL"), lpszTitle, ICON_HAND); + if (!Silent) MessageBoxW (hwndDlg, GetString ("ACCESSMODEFAIL"), lpszTitle, ICON_HAND); goto cancel; } } @@ -2544,6 +2568,8 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) volParams->password = &volumePassword; volParams->pim = volumePim; volParams->hwndDlg = hwndDlg; + volParams->bForceOperation = bForceOperation; + volParams->bGuiMode = bGuiMode; if (bInPlaceDecNonSys) { @@ -2587,7 +2613,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) { // Format-encryption - InitProgressBar (GetVolumeDataAreaSize (bHidden, nVolumeSize), 0, FALSE, FALSE, FALSE, TRUE); + if (hwndDlg && bGuiMode) InitProgressBar (GetVolumeDataAreaSize (bHidden, nVolumeSize), 0, FALSE, FALSE, FALSE, TRUE); nStatus = TCFormatVolume (volParams); } @@ -2611,19 +2637,19 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) dwWin32FormatError = GetLastError (); - if (bHiddenVolHost && !bVolTransformThreadCancel && nStatus == 0) + if (bHiddenVolHost && (!bGuiMode || !bVolTransformThreadCancel) && nStatus == 0) { /* Auto mount the newly created hidden volume host */ switch (MountHiddenVolHost (hwndDlg, szDiskFile, &hiddenVolHostDriveNo, &volumePassword, hash_algo, volumePim, FALSE)) { case ERR_NO_FREE_DRIVES: - MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVE_FOR_OUTER_VOL"), lpszTitle, ICON_HAND); - bVolTransformThreadCancel = TRUE; + if (!Silent) MessageBoxW (hwndDlg, GetString ("NO_FREE_DRIVE_FOR_OUTER_VOL"), lpszTitle, ICON_HAND); + if (bGuiMode) bVolTransformThreadCancel = TRUE; break; case ERR_VOL_MOUNT_FAILED: case ERR_PASSWORD_WRONG: - MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_OUTER_VOL"), lpszTitle, ICON_HAND); - bVolTransformThreadCancel = TRUE; + if (!Silent) MessageBoxW (hwndDlg, GetString ("CANT_MOUNT_OUTER_VOL"), lpszTitle, ICON_HAND); + if (bGuiMode) bVolTransformThreadCancel = TRUE; break; } } @@ -2668,7 +2694,7 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) ShowInPlaceEncErrMsgWAltSteps (hwndDlg, "INPLACE_ENC_GENERIC_ERR_ALT_STEPS", TRUE); } } - else if (!(bHiddenVolHost && hiddenVolHostDriveNo < 0)) // If the error was not that the hidden volume host could not be mounted (this error has already been reported to the user) + else if (!Silent && !(bHiddenVolHost && hiddenVolHostDriveNo < 0)) // If the error was not that the hidden volume host could not be mounted (this error has already been reported to the user) { StringCbPrintfW (szMsg, sizeof(szMsg), GetString ("CREATE_FAILED"), szDiskFile); MessageBoxW (hwndDlg, szMsg, lpszTitle, ICON_HAND); @@ -2689,6 +2715,8 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) PimEnable = FALSE; + bOperationSuccess = TRUE; + if (bDevice && !bInPlaceEncNonSys) { // Handle assigned drive letter (if any) @@ -2738,10 +2766,10 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) burn(&szVerify[0], sizeof (szVerify)); burn(&szRawPassword[0], sizeof (szRawPassword)); - MessageBeep (MB_OK); + if (!Silent) MessageBeep (MB_OK); } - if (!bInPlaceEncNonSys) + if (!bInPlaceEncNonSys && hwndDlg && bGuiMode) SetTimer (hwndDlg, TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL); @@ -2751,13 +2779,16 @@ static void __cdecl volTransformThreadFunction (void *hwndDlgArg) free ((LPVOID) volParams); volParams = NULL; - bVolTransformThreadRunning = FALSE; - bVolTransformThreadCancel = FALSE; + if (bGuiMode) + { + bVolTransformThreadRunning = FALSE; + bVolTransformThreadCancel = FALSE; + } - PostMessage (hwndDlg, bInPlaceEncNonSys ? TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED : TC_APPMSG_FORMAT_FINISHED, 0, 0); + if (hwndDlg && bGuiMode) PostMessage (hwndDlg, bInPlaceEncNonSys ? TC_APPMSG_NONSYS_INPLACE_ENC_FINISHED : TC_APPMSG_FORMAT_FINISHED, 0, 0); LastDialogId = "FORMAT_FINISHED"; - _endthread (); + if (bGuiMode) _endthread (); } } @@ -2765,7 +2796,7 @@ cancel: LastDialogId = (bInPlaceEncNonSys ? "NONSYS_INPLACE_ENC_CANCELED" : "FORMAT_CANCELED"); - if (!bInPlaceEncNonSys) + if (!bInPlaceEncNonSys && hwndDlg && bGuiMode) SetTimer (hwndDlg, TIMER_ID_RANDVIEW, TIMER_INTERVAL_RANDVIEW, NULL); if (volParams != NULL) @@ -2776,18 +2807,21 @@ cancel: volParams = NULL; } - bVolTransformThreadRunning = FALSE; - bVolTransformThreadCancel = FALSE; + if (bGuiMode) + { + bVolTransformThreadRunning = FALSE; + bVolTransformThreadCancel = FALSE; + } // Allow the OS to enter Sleep mode when idle SetThreadExecutionState (ES_CONTINUOUS); - PostMessage (hwndDlg, TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED, 0, 0); + if (hwndDlg) PostMessage (hwndDlg, TC_APPMSG_VOL_TRANSFORM_THREAD_ENDED, 0, 0); if (bHiddenVolHost && hiddenVolHostDriveNo < -1 && !bVolTransformThreadCancel) // If hidden volume host could not be mounted AbortProcessSilent (); - _endthread (); + if (bGuiMode) _endthread (); } static void LoadPage (HWND hwndDlg, int nPageNo) @@ -3321,7 +3355,7 @@ BOOL QueryFreeSpace (HWND hwndDlg, HWND hwndTextBox, BOOL display) return FALSE; } - int sectorSize = GetFormatSectorSize(); + DWORD sectorSize = GetFormatSectorSize(); if (sectorSize < TC_MIN_VOLUME_SECTOR_SIZE || sectorSize > TC_MAX_VOLUME_SECTOR_SIZE @@ -3381,7 +3415,7 @@ static BOOL FinalPreTransformPrompts (void) driveNo = GetDiskDeviceDriveLetter (deviceName); - if (!(bHiddenVol && !bHiddenVolHost)) // Do not ask for permission to overwrite an existing volume if we're creating a hidden volume within it + if (!bForceOperation && !(bHiddenVol && !bHiddenVolHost)) // Do not ask for permission to overwrite an existing volume if we're creating a hidden volume within it { wchar_t drive[128]; wchar_t volumeLabel[128]; @@ -3408,8 +3442,11 @@ static BOOL FinalPreTransformPrompts (void) else StringCbPrintfW (szTmp, sizeof(szTmp), GetString (bInPlaceEncNonSys ? (bInPlaceDecNonSys ? "NONSYS_INPLACE_DEC_CONFIRM" : "NONSYS_INPLACE_ENC_CONFIRM") : "OVERWRITEPROMPT_DEVICE"), type, szFileName, drive); + if (bInPlaceEncNonSys) + x = AskWarnYesNoString (szTmp, MainDlg); + else + x = AskWarnNoYesString (szTmp, MainDlg); - x = MessageBoxW (MainDlg, szTmp, lpszTitle, YES_NO | MB_ICONWARNING | (bInPlaceEncNonSys ? MB_DEFBUTTON1 : MB_DEFBUTTON2)); if (x != IDYES) return FALSE; @@ -3495,7 +3532,7 @@ void HandleOldAssignedDriveLetter (void) ToUNICODE ((char *)deviceName, sizeof(deviceName)); driveLetter = GetDiskDeviceDriveLetter (deviceName); - if (!bHiddenVolHost + if (!Silent && !bHiddenVolHost && !bHiddenOS && driveLetter > 1) // If a drive letter is assigned to the device, but not A: or B: { @@ -4748,7 +4785,7 @@ BOOL CALLBACK PageDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa for (int i = 1; i <= 128; i *= 2) { wstringstream s; - int size = GetFormatSectorSize() * i; + DWORD size = GetFormatSectorSize() * i; if (size > TC_MAX_FAT_CLUSTER_SIZE) break; @@ -5851,6 +5888,167 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa exit (0); } + if (DirectCreationMode) + { + char root[TC_MAX_PATH]; + DWORD fileSystemFlags = 0; + uint64 dataAreaSize; + char szFileSystemNameBuffer[256]; + ULARGE_INTEGER free; + + showKeys = FALSE; + bGuiMode = FALSE; + + if (CmdVolumePassword.Length == 0) + AbortProcess ("ERR_PASSWORD_MISSING"); + + if (CmdVolumeFileSize == 0) + AbortProcess ("ERR_SIZE_MISSING"); + + CreateFullVolumePath (szDiskFile, sizeof(szDiskFile), szFileName, &bDevice); + + if (bDevice) + AbortProcess ("ERR_DEVICE_CLI_CREATE_NOT_SUPPORTED"); + + volumePassword = CmdVolumePassword; + volumePim = CmdVolumePim; + + if (CmdVolumeEA > 0) + nVolumeEA = CmdVolumeEA; + + if (CmdVolumePkcs5 > 0) + hash_algo = CmdVolumePkcs5; + + if (CmdVolumeFilesystem > 0) + fileSystem = CmdVolumeFilesystem; + else + fileSystem = FILESYS_NTFS; + + nVolumeSize = CmdVolumeFileSize; + + // correct volume size to be multiple of sector size + if (bDevice && !(bHiddenVol && !bHiddenVolHost)) // If raw device but not a hidden volume + { + // do nothing. no correction is needed + } + else + { + unsigned __int64 sectorSize = (unsigned __int64) GetFormatSectorSize(); + unsigned __int64 sectorSizeRem = nVolumeSize % sectorSize; + + if (sectorSizeRem != 0) + nVolumeSize = nVolumeSize + (sectorSize - sectorSizeRem); + } + + if (nVolumeSize < (bHiddenVolHost ? TC_MIN_HIDDEN_VOLUME_HOST_SIZE : (bHiddenVol ? TC_MIN_HIDDEN_VOLUME_SIZE : TC_MIN_VOLUME_SIZE))) + AbortProcess ("ERR_VOLUME_SIZE_TOO_SMALL"); + + if ( ((!bHiddenVolHost && bHiddenVol) && (nVolumeSize > nMaximumHiddenVolSize)) + || (nVolumeSize > (bHiddenVolHost ? TC_MAX_HIDDEN_VOLUME_HOST_SIZE : TC_MAX_VOLUME_SIZE)) + ) + { + AbortProcess ("ERR_VOLUME_SIZE_TOO_BIG"); + } + + if (!GetVolumePathName (szFileName, root, sizeof (root))) + { + handleWin32Error (hwndDlg, SRC_POS); + exit (1); + } + + if (CmdSparseFileSwitch) + { + /* Check if the host file system supports sparse files */ + GetVolumeInformation (root, NULL, 0, NULL, NULL, &fileSystemFlags, NULL, 0); + bSparseFileSwitch = fileSystemFlags & FILE_SUPPORTS_SPARSE_FILES; + + if (!bSparseFileSwitch) + { + AbortProcess ("ERR_DYNAMIC_NOT_SUPPORTED"); + } + } + + quickFormat = TRUE; + + if (!GetDiskFreeSpaceEx (root, &free, 0, 0)) + { + wchar_t szTmp[1024]; + + if (translateWin32Error (szTmp, sizeof (szTmp) / sizeof(szTmp[0]))) + { + wchar_t szTmp2[1024]; + StringCbPrintfW (szTmp2, sizeof(szTmp2), L"%s\n%s", GetString ("CANNOT_CALC_SPACE"), szTmp); + AbortProcessDirect (szTmp2); + } + else + { + handleWin32Error (hwndDlg, SRC_POS); + } + + exit (1); + } + else + { + if (!bSparseFileSwitch && (nVolumeSize > free.QuadPart)) + { + AbortProcess ("ERR_CONTAINER_SIZE_TOO_BIG"); + } + } + + dataAreaSize = GetVolumeDataAreaSize (bHiddenVol && !bHiddenVolHost, nVolumeSize); + + if ( (fileSystem == FILESYS_NTFS) && + (dataAreaSize < TC_MIN_NTFS_FS_SIZE || dataAreaSize > TC_MAX_NTFS_FS_SIZE) + ) + { + AbortProcess ("ERR_NTFS_INVALID_VOLUME_SIZE"); + } + + if ( (fileSystem == FILESYS_FAT) && + (dataAreaSize < TC_MIN_FAT_FS_SIZE || dataAreaSize > (TC_MAX_FAT_SECTOR_COUNT * GetFormatSectorSize())) + ) + { + AbortProcess ("ERR_FAT_INVALID_VOLUME_SIZE"); + } + + /* Verify that the volume would not be too large for the host file system */ + if (GetVolumePathName (szDiskFile, root, sizeof (root)) + && GetVolumeInformation (root, NULL, 0, NULL, NULL, NULL, szFileSystemNameBuffer, sizeof(szFileSystemNameBuffer)) + && !strncmp (szFileSystemNameBuffer, "FAT32", 5)) + { + // The host file system is FAT32 + if (nVolumeSize >= 4 * BYTES_PER_GB) + { + AbortProcess ("VOLUME_TOO_LARGE_FOR_FAT32"); + } + } + + /* Verify that the volume would not be too large for the operating system */ + if (!IsOSAtLeast (WIN_VISTA) + && nVolumeSize > 2 * BYTES_PER_TB) + { + AbortProcess ("VOLUME_TOO_LARGE_FOR_WINXP"); + } + + if (volumePassword.Length > 0) + { + // Password character encoding + if (!CheckPasswordCharEncoding (NULL, &volumePassword)) + { + AbortProcess ("UNSUPPORTED_CHARS_IN_PWD"); + } + // Check password length (check also done for outer volume which is not the case in TrueCrypt). + else if (!CheckPasswordLength (NULL, volumePassword.Length, volumePim, FALSE, Silent, Silent)) + { + exit (1); + } + } + + volTransformThreadFunction (hwndDlg); + + exit (bOperationSuccess? 0 : 1); + } + SHGetFolderPath (NULL, CSIDL_MYDOCUMENTS, NULL, 0, szRescueDiskISO); StringCbCatA (szRescueDiskISO, sizeof(szRescueDiskISO), "\\VeraCrypt Rescue Disk.iso"); @@ -7102,7 +7300,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa return 1; } // Check password length (check also done for outer volume which is not the case in TrueCrypt). - else if (!CheckPasswordLength (hwndDlg, volumePassword.Length, 0, SysEncInEffect(), FALSE)) + else if (!CheckPasswordLength (hwndDlg, volumePassword.Length, 0, SysEncInEffect(), FALSE, FALSE)) { return 1; } @@ -7181,7 +7379,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa return 1; } // Check password length (check also done for outer volume which is not the case in TrueCrypt). - else if (!CheckPasswordLength (hwndDlg, volumePassword.Length, volumePim, SysEncInEffect(), TRUE)) + else if (!CheckPasswordLength (hwndDlg, volumePassword.Length, volumePim, SysEncInEffect(), TRUE, FALSE)) { return 1; } @@ -8458,6 +8656,16 @@ void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine) CommandInplaceDec, CommandResumeInplaceDec, CommandResumeInplace, + OptionEncryption, + OptionFilesystem, + OptionPkcs5, + OptionPassword, + OptionPim, + OptionSize, + OptionCreate, + OptionSilent, + OptionDynamic, + OptionForce, }; argument args[]= @@ -8467,6 +8675,16 @@ void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine) { OptionNoIsoCheck, "/noisocheck", "/n", FALSE }, { OptionTokenLib, "/tokenlib", NULL, FALSE }, { OptionQuit, "/quit", "/q", FALSE }, + { OptionEncryption, "/encryption", NULL , FALSE }, + { OptionFilesystem, "/filesystem", NULL , FALSE }, + { OptionPkcs5, "/hash", NULL , FALSE }, + { OptionPassword, "/password", NULL, FALSE }, + { OptionPim, "/pim", NULL, FALSE }, + { OptionSize, "/size", NULL, FALSE }, + { OptionCreate, "/create", NULL, FALSE }, + { OptionSilent, "/silent", NULL, FALSE }, + { OptionDynamic, "/dynamic", NULL, FALSE }, + { OptionForce, "/force", NULL, FALSE }, // Internal { CommandResumeSysEncLogOn, "/acsysenc", "/a", TRUE }, @@ -8496,6 +8714,160 @@ void ExtractCommandLine (HWND hwndDlg, char *lpszCommandLine) switch (x) { + case OptionCreate: + { + DirectCreationMode = TRUE; + + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + szFileName, sizeof (szFileName))) + { + RelativePath2Absolute (szFileName); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + case OptionEncryption: + { + char szTmp[64] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + CmdVolumeEA = EAGetByName (szTmp); + if (CmdVolumeEA == 0) + AbortProcess ("COMMAND_LINE_ERROR"); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + case OptionFilesystem: + { + char szTmp[8] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + if (_stricmp(szTmp, "NONE") == 0) + CmdVolumeFilesystem = FILESYS_NONE; + else if (_stricmp(szTmp, "FAT32") == 0 || _stricmp(szTmp, "FAT") == 0) + CmdVolumeFilesystem = FILESYS_FAT; + else if (_stricmp(szTmp, "NTFS") == 0) + CmdVolumeFilesystem = FILESYS_NTFS; + else + { + AbortProcess ("COMMAND_LINE_ERROR"); + } + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + case OptionPassword: + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, &i, nNoCommandLineArgs, + (char *) CmdVolumePassword.Text, sizeof (CmdVolumePassword.Text))) + { + CmdVolumePassword.Length = (unsigned __int32) strlen ((char *) CmdVolumePassword.Text); + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + break; + case OptionPkcs5: + { + char szTmp[32] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + if (_stricmp(szTmp, "sha512") == 0 || _stricmp(szTmp, "sha-512") == 0) + CmdVolumePkcs5 = SHA512; + else if (_stricmp(szTmp, "whirlpool") == 0) + CmdVolumePkcs5 = WHIRLPOOL; + else if (_stricmp(szTmp, "sha256") == 0 || _stricmp(szTmp, "sha-256") == 0) + CmdVolumePkcs5 = SHA256; + else if (_stricmp(szTmp, "ripemd160") == 0 || _stricmp(szTmp, "ripemd-160") == 0) + CmdVolumePkcs5 = RIPEMD160; + else + { + CmdVolumePkcs5 = 0; + AbortProcess ("COMMAND_LINE_ERROR"); + } + + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + + case OptionPim: + { + char szTmp[32] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, sizeof (szTmp))) + { + char* endPtr = NULL; + CmdVolumePim = (int) strtol(szTmp, &endPtr, 0); + if (CmdVolumePim < 0 || endPtr == szTmp || *endPtr != '\0') + { + CmdVolumePim = 0; + AbortProcess ("COMMAND_LINE_ERROR"); + } + + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; + case OptionSilent: + Silent = TRUE; + break; + case OptionDynamic: + CmdSparseFileSwitch = TRUE; + break; + case OptionForce: + bForceOperation = TRUE; + break; + case OptionSize: + { + char szTmp[32] = {0}; + if (HAS_ARGUMENT == GetArgumentValue (lpszCommandLineArgs, + &i, nNoCommandLineArgs, szTmp, sizeof (szTmp)) + && (strlen (szTmp) >= 2) + ) + { + /* size can be expressed in bytes or with suffixes K, M,G or T + * to indicate the unit to use + */ + unsigned __int64 multiplier; + char* endPtr = NULL; + char lastChar = szTmp [strlen (szTmp) - 1]; + if (lastChar >= '0' && lastChar <= '9') + multiplier = 1; + else if (lastChar == 'K' || lastChar == 'k') + multiplier = BYTES_PER_KB; + else if (lastChar == 'M' || lastChar == 'm') + multiplier = BYTES_PER_MB; + else if (lastChar == 'G' || lastChar == 'g') + multiplier = BYTES_PER_GB; + else if (lastChar == 'T' || lastChar == 't') + multiplier = BYTES_PER_TB; + else + AbortProcess ("COMMAND_LINE_ERROR"); + + if (multiplier != 1) + szTmp [strlen (szTmp) - 1] = 0; + + CmdVolumeFileSize = _strtoui64(szTmp, &endPtr, 0); + if (CmdVolumeFileSize == 0 || CmdVolumeFileSize == _UI64_MAX + || endPtr == szTmp || *endPtr != '\0') + { + AbortProcess ("COMMAND_LINE_ERROR"); + } + + CmdVolumeFileSize *= multiplier; + } + else + AbortProcess ("COMMAND_LINE_ERROR"); + } + break; case CommandSysEnc: // Encrypt system partition/drive (passed by Mount if system encryption hasn't started or to reverse decryption) @@ -9693,7 +10065,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char *lpszComm } -static int GetFormatSectorSize () +static DWORD GetFormatSectorSize () { if (!bDevice) return TC_SECTOR_SIZE_FILE_HOSTED_VOLUME; diff --git a/src/Format/Tcformat.h b/src/Format/Tcformat.h index d6d3ac4b..7e94782a 100644 --- a/src/Format/Tcformat.h +++ b/src/Format/Tcformat.h @@ -78,7 +78,7 @@ static void WipeAbort (void); static void UpdateWipeProgressBar (void); static void InitWipeProgressBar (void); static void UpdateWipeControls (void); -static int GetFormatSectorSize (); +static DWORD GetFormatSectorSize (); extern BOOL showKeys; extern volatile HWND hMasterKey; diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index e67c9018..834ed198 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -2457,7 +2457,7 @@ BOOL CALLBACK PasswordChangeDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPAR else if (!(newKeyFilesParam.EnableKeyFiles && newKeyFilesParam.FirstKeyFile != NULL) && pwdChangeDlgMode == PCDM_CHANGE_PASSWORD) { - if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, FALSE)) + if (!CheckPasswordLength (hwndDlg, GetWindowTextLength(GetDlgItem (hwndDlg, IDC_PASSWORD)), pim, bSysEncPwdChangeDlgMode, FALSE, FALSE)) return 1; } -- cgit v1.2.3