VeraCrypt
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMounir IDRASSI <mounir.idrassi@idrix.fr>2023-08-13 00:56:49 +0200
committerMounir IDRASSI <mounir.idrassi@idrix.fr>2023-08-13 00:56:49 +0200
commit8c7962bda7ea260049226fe99a351675fd0780a2 (patch)
tree388930f0c2f6ae19ea673b1b0faeedc9f4c805d0
parenteb2f5f33c96840efef46e97d994182a25540bb17 (diff)
downloadVeraCrypt-8c7962bda7ea260049226fe99a351675fd0780a2.tar.gz
VeraCrypt-8c7962bda7ea260049226fe99a351675fd0780a2.zip
Windows: Better way to enable required privileges for FastCreate Options
If we can set required privilege, we ask the user using UAC to enable them.
-rw-r--r--src/Common/BaseCom.cpp5
-rw-r--r--src/Common/BaseCom.h1
-rw-r--r--src/Common/Dlgcode.c85
-rw-r--r--src/Common/Dlgcode.h2
-rw-r--r--src/Common/Format.c59
-rw-r--r--src/Format/FormatCom.cpp31
-rw-r--r--src/Format/FormatCom.h1
-rw-r--r--src/Format/FormatCom.idl1
-rw-r--r--src/Mount/MainCom.cpp5
-rw-r--r--src/Mount/MainCom.idl1
10 files changed, 183 insertions, 8 deletions
diff --git a/src/Common/BaseCom.cpp b/src/Common/BaseCom.cpp
index dde4b55d..3eaaf809 100644
--- a/src/Common/BaseCom.cpp
+++ b/src/Common/BaseCom.cpp
@@ -497,3 +497,8 @@ DWORD BaseCom::NotifyService(DWORD dwNotifyCode)
{
return SendServiceNotification(dwNotifyCode);
}
+
+DWORD BaseCom::FastFileResize (BSTR filePath, __int64 fileSize)
+{
+ return ::FastResizeFile (filePath, fileSize);
+}
diff --git a/src/Common/BaseCom.h b/src/Common/BaseCom.h
index 937e37ec..431b0257 100644
--- a/src/Common/BaseCom.h
+++ b/src/Common/BaseCom.h
@@ -120,6 +120,7 @@ public:
static DWORD UpdateSetupConfigFile (BOOL bForInstall);
static DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
static DWORD NotifyService (DWORD dwNotifyCode);
+ static DWORD FastFileResize (BSTR filePath, __int64 fileSize);
};
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index b137c57b..6739a7a3 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -13977,6 +13977,41 @@ BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable)
return bRet;
}
+BOOL IsPrivilegeEnabled (LPTSTR szPrivilegeName)
+{
+ HANDLE hToken;
+ TOKEN_PRIVILEGES tkp;
+ BOOL bRet = FALSE;
+ DWORD dwLastError = 0;
+
+ if (OpenProcessToken(GetCurrentProcess(),
+ TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
+ &hToken))
+ {
+ if (LookupPrivilegeValue(NULL, szPrivilegeName,
+ &tkp.Privileges[0].Luid))
+ {
+ DWORD dwSize = sizeof (tkp);
+ if (GetTokenInformation (hToken, TokenPrivileges, &tkp, dwSize, &dwSize))
+ {
+ bRet = (tkp.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) != 0;
+ }
+ else
+ dwLastError = GetLastError ();
+ }
+ else
+ dwLastError = GetLastError ();
+
+ CloseHandle(hToken);
+ }
+ else
+ dwLastError = GetLastError ();
+
+ SetLastError (dwLastError);
+
+ return bRet;
+}
+
BOOL DeleteDirectory (const wchar_t* szDirName)
{
BOOL bStatus = RemoveDirectory (szDirName);
@@ -15743,4 +15778,54 @@ DWORD SendServiceNotification (DWORD dwNotificationCmd)
return dwRet;
}
+
+DWORD FastResizeFile (const wchar_t* filePath, __int64 fileSize)
+{
+ DWORD dwRet = ERROR_INVALID_PARAMETER;
+ if (filePath && fileSize > 0)
+ {
+ // we set required privileges to speedup file creation before we create the file so that the file handle inherits the privileges
+ BOOL bPrivilegesSet = IsPrivilegeEnabled (SE_MANAGE_VOLUME_NAME);
+ if (!bPrivilegesSet && !SetPrivilege(SE_MANAGE_VOLUME_NAME, TRUE))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ HANDLE dev = CreateFile (filePath, GENERIC_WRITE | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (dev != INVALID_HANDLE_VALUE)
+ {
+ LARGE_INTEGER liSize;
+ liSize.QuadPart = fileSize;
+ // Preallocate the file with desired size
+ if (!SetFilePointerEx (dev, liSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ if (!SetFileValidData (dev, fileSize))
+ {
+ dwRet = GetLastError ();
+ }
+ else
+ {
+ dwRet = ERROR_SUCCESS;
+ }
+ }
+
+ FlushFileBuffers (dev);
+ CloseHandle (dev);
+ }
+ else
+ dwRet = GetLastError ();
+
+ if (!bPrivilegesSet)
+ SetPrivilege(SE_MANAGE_VOLUME_NAME, FALSE);
+ }
+ }
+
+ return dwRet;
+}
#endif // VC_COMREG \ No newline at end of file
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 4a7e40c7..92901b28 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -577,6 +577,7 @@ BOOL CopyTextToClipboard (const wchar_t* txtValue);
BOOL LaunchElevatedProcess (HWND hwndDlg, const wchar_t* szModPath, const wchar_t* args);
BOOL GetFreeDriveLetter(WCHAR* pCh);
BOOL SetPrivilege(LPTSTR szPrivilegeName, BOOL bEnable);
+BOOL IsPrivilegeEnabled (LPTSTR szPrivilegeName);
BOOL DeleteDirectory (const wchar_t* szDirName);
BOOL IsThreadInSecureDesktop(DWORD dwThreadID);
INT_PTR SecureDesktopDialogBoxParam (HINSTANCE, LPCWSTR, HWND, DLGPROC, LPARAM);
@@ -589,6 +590,7 @@ void SafeOpenURL (LPCWSTR szUrl);
BitLockerEncryptionStatus GetBitLockerEncryptionStatus(WCHAR driveLetter);
BOOL IsTestSigningModeEnabled ();
DWORD SendServiceNotification (DWORD dwNotificationCmd);
+DWORD FastResizeFile (const wchar_t* filePath, __int64 fileSize);
#ifdef _WIN64
void GetAppRandomSeed (unsigned char* pbRandSeed, size_t cbRandSeed);
#endif
diff --git a/src/Common/Format.c b/src/Common/Format.c
index 6c3e2fff..334bff3d 100644
--- a/src/Common/Format.c
+++ b/src/Common/Format.c
@@ -345,6 +345,7 @@ begin_format:
{
/* File-hosted volume */
BOOL speedupFileCreation = FALSE;
+ BOOL delayedSpeedupFileCreation = FALSE;
// speedup for file creation only makes sens when using quick format for non hidden volumes
if (!volParams->hiddenVol && !bInstantRetryOtherFilesys && volParams->quickFormat && volParams->fastCreateFile)
{
@@ -352,7 +353,12 @@ begin_format:
if (!SetPrivilege(SE_MANAGE_VOLUME_NAME, TRUE))
{
DWORD dwLastError = GetLastError();
- if (Silent || (MessageBoxW(hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_MANAGE_VOLUME"), lpszTitle, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDNO))
+ if (!IsAdmin () && IsUacSupported ())
+ {
+ speedupFileCreation = TRUE;
+ delayedSpeedupFileCreation = TRUE;
+ }
+ else if (Silent || (MessageBoxW(hwndDlg, GetString ("ADMIN_PRIVILEGES_WARN_MANAGE_VOLUME"), lpszTitle, MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2) == IDNO))
{
SetLastError(dwLastError);
nStatus = ERR_OS_ERROR;
@@ -406,12 +412,15 @@ begin_format:
}
}
- // Preallocate the file
- if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
- || !SetEndOfFile (dev))
+ if (!delayedSpeedupFileCreation)
{
- nStatus = ERR_OS_ERROR;
- goto error;
+ // Preallocate the file
+ if (!SetFilePointerEx (dev, volumeSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
}
if (speedupFileCreation)
@@ -420,8 +429,42 @@ begin_format:
// this has security issues since it will put existing disk content into file container
// We use this mechanism only when switch /fastCreateFile specific and when quick format
// also specified and which is documented to have security issues.
- // we don't check returned status because failure is not issue for us
- if (!SetFileValidData (dev, volumeSize.QuadPart))
+ if (delayedSpeedupFileCreation)
+ {
+ // in case of delayed speedup we need to set the file size to a minimal value before performing the real preallocation through UAC
+ LARGE_INTEGER minimalSize;
+ DWORD dwOpStatus;
+ // 16K
+ minimalSize.QuadPart = 16 * 1024;
+ if (!SetFilePointerEx (dev, minimalSize, NULL, FILE_BEGIN)
+ || !SetEndOfFile (dev))
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
+ FlushFileBuffers (dev);
+ CloseHandle (dev);
+ dev = INVALID_HANDLE_VALUE;
+
+ dwOpStatus = UacFastFileCreation (volParams->hwndDlg, volParams->volumePath, volumeSize.QuadPart);
+ if (dwOpStatus != 0)
+ {
+ SetLastError(dwOpStatus);
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+
+ // open again the file now that it was created
+ dev = CreateFile (volParams->volumePath, GENERIC_READ | GENERIC_WRITE,
+ 0, NULL, OPEN_EXISTING, 0, NULL);
+ if (dev == INVALID_HANDLE_VALUE)
+ {
+ nStatus = ERR_OS_ERROR;
+ goto error;
+ }
+ }
+ else if (!SetFileValidData (dev, volumeSize.QuadPart))
{
nStatus = ERR_OS_ERROR;
goto error;
diff --git a/src/Format/FormatCom.cpp b/src/Format/FormatCom.cpp
index 18653761..d696f00f 100644
--- a/src/Format/FormatCom.cpp
+++ b/src/Format/FormatCom.cpp
@@ -187,6 +187,11 @@ public:
return BaseCom::NotifyService (dwNotifyCode);
}
+ virtual DWORD STDMETHODCALLTYPE FastFileResize (BSTR filePath, __int64 fileSize)
+ {
+ return BaseCom::FastFileResize (filePath, fileSize);
+ }
+
protected:
DWORD MessageThreadId;
LONG RefCount;
@@ -335,3 +340,29 @@ extern "C" BOOL UacWriteLocalMachineRegistryDword (HWND hwndDlg, wchar_t *keyPat
}
}
+extern "C" DWORD UacFastFileCreation (HWND hWnd, wchar_t* filePath, __int64 fileSize)
+{
+ CComPtr<ITrueCryptFormatCom> tc;
+ DWORD r;
+
+ CoInitialize (NULL);
+
+ if (ComGetInstance (hWnd, &tc))
+ {
+ CComBSTR filePathBstr;
+ BSTR bstr = W2BSTR(filePath);
+ if (bstr)
+ {
+ filePathBstr.Attach (bstr);
+ r = tc->FastFileResize (filePathBstr, fileSize);
+ }
+ else
+ r = ERROR_OUTOFMEMORY;
+ }
+ else
+ r = GetLastError();
+
+ CoUninitialize ();
+
+ return r;
+}
diff --git a/src/Format/FormatCom.h b/src/Format/FormatCom.h
index 5ab6bd52..e474608d 100644
--- a/src/Format/FormatCom.h
+++ b/src/Format/FormatCom.h
@@ -30,6 +30,7 @@ int UacAnalyzeHiddenVolumeHost (HWND hwndDlg, int *driveNo, __int64 hiddenVolHos
int UacFormatVolume (char *cvolumePath , BOOL bDevice , unsigned __int64 size , unsigned __int64 hiddenVolHostSize , Password *password , int cipher , int pkcs5 , BOOL quickFormat, BOOL sparseFileSwitch, int fileSystem , int clusterSize, HWND hwndDlg , BOOL hiddenVol , int *realClusterSize);
BOOL UacUpdateProgressBar (__int64 nSecNo, BOOL *bVolTransformThreadCancel);
BOOL UacWriteLocalMachineRegistryDword (HWND hwndDlg, wchar_t *keyPath, wchar_t *valueName, DWORD value);
+DWORD UacFastFileCreation (HWND hWnd, wchar_t* filePath, __int64 fileSize);
#ifdef __cplusplus
}
diff --git a/src/Format/FormatCom.idl b/src/Format/FormatCom.idl
index cae4e155..7276de81 100644
--- a/src/Format/FormatCom.idl
+++ b/src/Format/FormatCom.idl
@@ -50,6 +50,7 @@ library TrueCryptFormatCom
DWORD UpdateSetupConfigFile (BOOL bForInstall);
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
DWORD NotifyService (DWORD dwNotifyCode);
+ DWORD FastFileResize (BSTR filePath, __int64 fileSize);
};
[
diff --git a/src/Mount/MainCom.cpp b/src/Mount/MainCom.cpp
index 9226e15b..aa628f57 100644
--- a/src/Mount/MainCom.cpp
+++ b/src/Mount/MainCom.cpp
@@ -208,6 +208,11 @@ public:
return BaseCom::NotifyService (dwNotifyCode);
}
+ virtual DWORD STDMETHODCALLTYPE FastFileResize (BSTR filePath, __int64 fileSize)
+ {
+ return BaseCom::FastFileResize (filePath, fileSize);
+ }
+
protected:
DWORD MessageThreadId;
LONG RefCount;
diff --git a/src/Mount/MainCom.idl b/src/Mount/MainCom.idl
index 6ad9dd1b..06c2e48f 100644
--- a/src/Mount/MainCom.idl
+++ b/src/Mount/MainCom.idl
@@ -54,6 +54,7 @@ library TrueCryptMainCom
DWORD UpdateSetupConfigFile (BOOL bForInstall);
DWORD GetSecureBootConfig (BOOL* pSecureBootEnabled, BOOL *pVeraCryptKeysLoaded);
DWORD NotifyService (DWORD dwNotifyCode);
+ DWORD FastFileResize (BSTR filePath, __int64 fileSize);
};
[