VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/Apidrvr.h5
-rw-r--r--src/Common/BootEncryption.cpp44
-rw-r--r--src/Common/BootEncryption.h4
-rw-r--r--src/Common/Common.h2
-rw-r--r--src/Common/Common.rc34
-rw-r--r--src/Common/Dlgcode.c337
-rw-r--r--src/Common/Dlgcode.h13
-rw-r--r--src/Common/Language.xml8
-rw-r--r--src/Common/Volumes.c7
9 files changed, 400 insertions, 54 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index 2cfa369f..f584582e 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -128,6 +128,7 @@ typedef struct
unsigned __int32 ulMountedDrives; /* Bitfield of all mounted drive letters */
wchar_t wszVolume[26][TC_MAX_PATH]; /* Volume names of mounted volumes */
wchar_t wszLabel[26][33]; /* Labels of mounted volumes */
+ wchar_t volumeID[26][VOLUME_ID_SIZE]; /* IDs of mounted volumes */
unsigned __int64 diskLength[26];
int ea[26];
int volumeType[26]; /* Volume type (e.g. PROP_VOL_TYPE_OUTER, PROP_VOL_TYPE_OUTER_VOL_WRITE_PREVENTED, etc.) */
@@ -156,6 +157,7 @@ typedef struct
int volumePim;
wchar_t wszLabel[33];
BOOL bDriverSetLabel;
+ unsigned char volumeID[VOLUME_ID_SIZE];
} VOLUME_PROPERTIES_STRUCT;
typedef struct
@@ -194,6 +196,9 @@ typedef struct
BOOL TCBootLoaderDetected;
BOOL DetectFilesystem;
BOOL FilesystemDetected;
+ BOOL bMatchVolumeID;
+ unsigned char volumeID[VOLUME_ID_SIZE];
+ BOOL VolumeIDMatched;
} OPEN_TEST_STRUCT;
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index 07eb9a99..851d7622 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -1300,7 +1300,7 @@ namespace VeraCrypt
}
- void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage)
+ void BootEncryption::WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim)
{
Device device (GetSystemDriveConfiguration().DevicePath);
device.CheckOpened (SRC_POS);
@@ -1326,6 +1326,15 @@ namespace VeraCrypt
memcpy (mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, customUserMessage.c_str(), customUserMessage.size());
}
+
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ // PIM for pre-boot authentication can be encoded on two bytes since its maximum
+ // value is 65535 (0xFFFF)
+ memcpy (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ memset (mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, 0, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
device.SeekAt (0);
device.Write (mbr, sizeof (mbr));
@@ -1494,7 +1503,7 @@ namespace VeraCrypt
InstallBootLoader (device, preserveUserConfig, hiddenOSCreation);
}
- void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation)
+ void BootEncryption::InstallBootLoader (Device& device, bool preserveUserConfig, bool hiddenOSCreation, int pim)
{
byte bootLoaderBuf[TC_BOOT_LOADER_AREA_SIZE - TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE] = {0};
CreateBootLoaderInMemory (bootLoaderBuf, sizeof (bootLoaderBuf), false, hiddenOSCreation);
@@ -1512,6 +1521,16 @@ namespace VeraCrypt
{
bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] = mbr[TC_BOOT_SECTOR_USER_CONFIG_OFFSET];
memcpy (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, mbr + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET, TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH);
+
+ if (bootLoaderBuf[TC_BOOT_SECTOR_USER_CONFIG_OFFSET] & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ {
+ if (pim >= 0)
+ {
+ memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &pim, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
+ else
+ memcpy (bootLoaderBuf + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, mbr + TC_BOOT_SECTOR_PIM_VALUE_OFFSET, TC_BOOT_SECTOR_PIM_VALUE_SIZE);
+ }
}
}
@@ -2499,17 +2518,32 @@ namespace VeraCrypt
if (headerUpdated)
{
+ bool storedPimUpdateNeeded = false;
ReopenBootVolumeHeaderRequest reopenRequest;
reopenRequest.VolumePassword = *newPassword;
reopenRequest.pkcs5_prf = cryptoInfo->pkcs5;
reopenRequest.pim = pim;
finally_do_arg (ReopenBootVolumeHeaderRequest*, &reopenRequest, { burn (finally_arg, sizeof (*finally_arg)); });
+ if (old_pim != pim)
+ {
+ try
+ {
+ // check if PIM is stored in MBR
+ byte userConfig;
+ ReadBootSectorConfig (nullptr, 0, &userConfig);
+ if (userConfig & TC_BOOT_USER_CFG_FLAG_DISABLE_PIM)
+ storedPimUpdateNeeded = true;
+ }
+ catch (...)
+ {}
+ }
+
try
{
- // force update of bootloader if fingerprint doesn't match
- if (!CheckBootloaderFingerprint (true))
- InstallBootLoader (device, true);
+ // force update of bootloader if fingerprint doesn't match or if the stored PIM changed
+ if (storedPimUpdateNeeded || !CheckBootloaderFingerprint (true))
+ InstallBootLoader (device, true, false, pim);
}
catch (...)
{}
diff --git a/src/Common/BootEncryption.h b/src/Common/BootEncryption.h
index 8aad6708..a922d1fa 100644
--- a/src/Common/BootEncryption.h
+++ b/src/Common/BootEncryption.h
@@ -169,7 +169,7 @@ namespace VeraCrypt
void GetVolumeProperties (VOLUME_PROPERTIES_STRUCT *properties);
SystemDriveConfiguration GetSystemDriveConfiguration ();
void Install (bool hiddenSystem);
- void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false);
+ void InstallBootLoader (Device& device, bool preserveUserConfig = false, bool hiddenOSCreation = false, int pim = -1);
void InstallBootLoader (bool preserveUserConfig = false, bool hiddenOSCreation = false);
bool CheckBootloaderFingerprint (bool bSilent = false);
void InvalidateCachedSysDriveProperties ();
@@ -206,7 +206,7 @@ namespace VeraCrypt
void WipeHiddenOSCreationConfig ();
void WriteBootDriveSector (uint64 offset, byte *data);
void WriteBootSectorConfig (const byte newConfig[]);
- void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage);
+ void WriteBootSectorUserConfig (byte userConfig, const string &customUserMessage, int pim);
void WriteLocalMachineRegistryDwordValue (wchar_t *keyPath, wchar_t *valueName, DWORD value);
protected:
diff --git a/src/Common/Common.h b/src/Common/Common.h
index 3780cfe1..180cbffb 100644
--- a/src/Common/Common.h
+++ b/src/Common/Common.h
@@ -21,6 +21,8 @@
#define MAX_HOST_DRIVE_NUMBER 64
#define MAX_HOST_PARTITION_NUMBER 32
+#define VOLUME_ID_SIZE SHA256_DIGESTSIZE
+
typedef enum
{
// IMPORTANT: If you add a new item here, update IsOSVersionAtLeast().
diff --git a/src/Common/Common.rc b/src/Common/Common.rc
index 1abd1bbd..a0dbd612 100644
--- a/src/Common/Common.rc
+++ b/src/Common/Common.rc
@@ -98,28 +98,28 @@ BEGIN
LTEXT "Volume Label in Windows:",IDT_VOLUME_LABEL,12,70,95,8
END
-IDD_KEYFILES DIALOGEX 0, 0, 345, 251
+IDD_KEYFILES DIALOGEX 0, 0, 363, 251
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "VeraCrypt - Keyfiles"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
- CONTROL "",IDC_KEYLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,8,263,118
+ CONTROL "",IDC_KEYLIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,7,8,275,118
PUSHBUTTON "Add &Files...",IDC_KEYADD,7,132,61,14
- PUSHBUTTON "Add &Path...",IDC_ADD_KEYFILE_PATH,73,132,61,14
- PUSHBUTTON "Add &Token Files...",IDC_TOKEN_FILES_ADD,139,132,65,14
- PUSHBUTTON "&Remove",IDC_KEYREMOVE,209,132,61,14
- PUSHBUTTON "Remove &All",IDC_KEYREMOVEALL,275,132,61,14
- CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,232,83,11
- PUSHBUTTON "&Generate Random Keyfile...",IDC_GENERATE_KEYFILE,213,230,123,14
- DEFPUSHBUTTON "OK",IDOK,279,8,59,14
- PUSHBUTTON "Cancel",IDCANCEL,279,25,59,14
- LTEXT "",IDT_KEYFILES_NOTE,10,161,324,41,0,WS_EX_TRANSPARENT
- LTEXT "WARNING: If you lose a keyfile or if any bit of its first 1024 kilobytes changes, it will be impossible to mount volumes that use the keyfile!",IDT_KEYFILE_WARNING,279,44,58,85,0,WS_EX_TRANSPARENT
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,154,343,1,WS_EX_STATICEDGE
- CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,209,343,1,WS_EX_STATICEDGE
- LTEXT "More information on keyfiles",IDC_LINK_KEYFILES_INFO,96,233,108,10,SS_NOTIFY
+ PUSHBUTTON "Add &Path...",IDC_ADD_KEYFILE_PATH,79,132,61,14
+ PUSHBUTTON "Add &Token Files...",IDC_TOKEN_FILES_ADD,151,132,65,14
+ PUSHBUTTON "&Remove",IDC_KEYREMOVE,227,132,61,14
+ PUSHBUTTON "Remove &All",IDC_KEYREMOVEALL,299,132,61,14
+ CONTROL "U&se keyfiles",IDC_KEYFILES_ENABLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,232,105,11
+ PUSHBUTTON "&Generate Random Keyfile...",IDC_GENERATE_KEYFILE,237,230,123,14
+ DEFPUSHBUTTON "OK",IDOK,290,8,70,14
+ PUSHBUTTON "Cancel",IDCANCEL,290,25,70,14
+ LTEXT "",IDT_KEYFILES_NOTE,10,161,346,41,0,WS_EX_TRANSPARENT
+ LTEXT "WARNING: If you lose a keyfile or if any bit of its first 1024 kilobytes changes, it will be impossible to mount volumes that use the keyfile!",IDT_KEYFILE_WARNING,290,44,69,85,0,WS_EX_TRANSPARENT
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,154,361,1,WS_EX_STATICEDGE
+ CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,2,209,361,1,WS_EX_STATICEDGE
+ LTEXT "More information on keyfiles",IDC_LINK_KEYFILES_INFO,119,233,113,10,SS_NOTIFY
CONTROL "Try first to mount with an empty password",IDC_KEYFILES_TRY_EMPTY_PASSWORD,
- "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,7,217,205,10
+ "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,7,217,310,10
END
IDD_LANGUAGE DIALOGEX 0, 0, 209, 183
@@ -366,7 +366,7 @@ BEGIN
IDD_KEYFILES, DIALOG
BEGIN
LEFTMARGIN, 7
- RIGHTMARGIN, 330
+ RIGHTMARGIN, 345
TOPMARGIN, 7
BOTTOMMARGIN, 244
END
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 2cf5bb8e..6958afe9 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -248,6 +248,9 @@ typedef LSTATUS (STDAPICALLTYPE *SHDeleteKeyWPtr)(HKEY hkey, LPCWSTR pszSubKey);
typedef HRESULT (STDAPICALLTYPE *SHStrDupWPtr)(LPCWSTR psz, LPWSTR *ppwsz);
+// ChangeWindowMessageFilter
+typedef BOOL (WINAPI *ChangeWindowMessageFilterPtr) (UINT, DWORD);
+
ImageList_CreatePtr ImageList_CreateFn = NULL;
ImageList_AddPtr ImageList_AddFn = NULL;
@@ -257,6 +260,7 @@ SetupInstallFromInfSectionWPtr SetupInstallFromInfSectionWFn = NULL;
SetupOpenInfFileWPtr SetupOpenInfFileWFn = NULL;
SHDeleteKeyWPtr SHDeleteKeyWFn = NULL;
SHStrDupWPtr SHStrDupWFn = NULL;
+ChangeWindowMessageFilterPtr ChangeWindowMessageFilterFn = NULL;
/* Windows dialog class */
#define WINDOWS_DIALOG_CLASS L"#32770"
@@ -265,6 +269,16 @@ SHStrDupWPtr SHStrDupWFn = NULL;
#define TC_DLG_CLASS L"VeraCryptCustomDlg"
#define TC_SPLASH_CLASS L"VeraCryptSplashDlg"
+/* constant used by ChangeWindowMessageFilter calls */
+#ifndef MSGFLT_ADD
+#define MSGFLT_ADD 1
+#endif
+
+/* undocumented message sent during drag-n-drop */
+#ifndef WM_COPYGLOBALDATA
+#define WM_COPYGLOBALDATA 0x0049
+#endif
+
/* Benchmarks */
#ifndef SETUP
@@ -2603,6 +2617,19 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
if (!SHDeleteKeyWFn || !SHStrDupWFn)
AbortProcess ("INIT_DLL");
+ if (IsOSAtLeast (WIN_VISTA))
+ {
+ /* Get ChangeWindowMessageFilter used to enable some messages bypasss UIPI (User Interface Privilege Isolation) */
+ ChangeWindowMessageFilterFn = (ChangeWindowMessageFilterPtr) GetProcAddress (GetModuleHandle (L"user32.dll"), "ChangeWindowMessageFilter");
+
+#ifndef SETUP
+ /* enable drag-n-drop when we are running elevated */
+ AllowMessageInUIPI (WM_DROPFILES);
+ AllowMessageInUIPI (WM_COPYDATA);
+ AllowMessageInUIPI (WM_COPYGLOBALDATA);
+#endif
+ }
+
/* Save the instance handle for later */
hInst = hInstance;
@@ -2903,7 +2930,7 @@ void InitHelpFileName (void)
}
}
-BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem)
+BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL matchVolumeID, const BYTE* pbVolumeID)
{
DWORD dwResult;
BOOL bResult;
@@ -2916,6 +2943,9 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF
driver->bDetectTCBootLoader = FALSE;
driver->DetectFilesystem = detectFilesystem;
+ driver->bMatchVolumeID = matchVolumeID;
+ if (matchVolumeID && pbVolumeID)
+ memcpy (driver->volumeID, pbVolumeID, VOLUME_ID_SIZE);
bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
driver, sizeof (OPEN_TEST_STRUCT),
@@ -2943,6 +2973,7 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF
{
driver->TCBootLoaderDetected = FALSE;
driver->FilesystemDetected = FALSE;
+ driver->VolumeIDMatched = FALSE;
return TRUE;
}
else
@@ -4685,6 +4716,55 @@ wstring IntToWideString (int val)
return szTmp;
}
+wstring ArrayToHexWideString (const unsigned char* pbData, int cbData)
+{
+ static wchar_t* hexChar = L"0123456789ABCDEF";
+ wstring result;
+ if (pbData)
+ {
+ for (int i = 0; i < cbData; i++)
+ {
+ result += hexChar[pbData[i] >> 4];
+ result += hexChar[pbData[i] & 0x0F];
+ }
+ }
+
+ return result;
+}
+
+bool HexToByte (wchar_t c, byte& b)
+{
+ bool bRet = true;
+ if (c >= L'0' && c <= L'9')
+ b = (byte) (c - L'0');
+ else if (c >= L'a' && c <= L'z')
+ b = (byte) (c - L'a' + 10);
+ else if (c >= L'A' && c <= L'Z')
+ b = (byte) (c - L'A' + 10);
+ else
+ bRet = false;
+
+ return bRet;
+}
+
+bool HexWideStringToArray (const wchar_t* hexStr, std::vector<byte>& arr)
+{
+ byte b1, b2;
+ size_t i, len = wcslen (hexStr);
+
+ arr.clear();
+ if (len %2)
+ return false;
+
+ for (i = 0; i < len/2; i++)
+ {
+ if (!HexToByte (*hexStr++, b1) || !HexToByte (*hexStr++, b2))
+ return false;
+ arr.push_back (b1 << 4 | b2);
+ }
+ return true;
+}
+
wstring GetTempPathString ()
{
wchar_t tempPath[MAX_PATH];
@@ -6680,11 +6760,13 @@ DWORD GetUsedLogicalDrives (void)
int GetFirstAvailableDrive ()
{
DWORD dwUsedDrives = GetUsedLogicalDrives();
- int i;
+ int i, drive;
- for (i = 0; i < 26; i++)
+ /* let A: and B: be used as last resort since they can introduce side effects */
+ for (i = 2; i < 28; i++)
{
- if (!(dwUsedDrives & 1 << i))
+ drive = (i < 26) ? i : (i - 26);
+ if (!(dwUsedDrives & 1 << drive))
return i;
}
@@ -7042,12 +7124,37 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v
/************************************************************************/
+static BOOL PerformMountIoctl (MOUNT_STRUCT* pmount, LPDWORD pdwResult, BOOL useVolumeID, BYTE volumeID[VOLUME_ID_SIZE])
+{
+ if (useVolumeID)
+ {
+ wstring devicePath = FindDeviceByVolumeID (volumeID);
+ if (devicePath == L"")
+ {
+ if (pdwResult)
+ *pdwResult = 0;
+ SetLastError (ERROR_PATH_NOT_FOUND);
+ return FALSE;
+ }
+ else
+ {
+ BOOL bDevice = FALSE;
+ CreateFullVolumePath (pmount->wszVolume, sizeof(pmount->wszVolume), devicePath.c_str(), &bDevice);
+ }
+ }
+
+ return DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, pmount,
+ sizeof (MOUNT_STRUCT), pmount, sizeof (MOUNT_STRUCT), pdwResult, NULL);
+}
+
// specific definitions and implementation for support of mount operation
// in wait dialog mechanism
typedef struct
{
MOUNT_STRUCT* pmount;
+ BOOL useVolumeID;
+ BYTE volumeID[VOLUME_ID_SIZE];
BOOL* pbResult;
DWORD* pdwResult;
DWORD dwLastError;
@@ -7057,8 +7164,7 @@ void CALLBACK MountWaitThreadProc(void* pArg, HWND )
{
MountThreadParam* pThreadParam = (MountThreadParam*) pArg;
- *(pThreadParam->pbResult) = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, pThreadParam->pmount,
- sizeof (MOUNT_STRUCT),pThreadParam->pmount, sizeof (MOUNT_STRUCT), pThreadParam->pdwResult, NULL);
+ *(pThreadParam->pbResult) = PerformMountIoctl (pThreadParam->pmount, pThreadParam->pdwResult, pThreadParam->useVolumeID, pThreadParam->volumeID);
pThreadParam->dwLastError = GetLastError ();
}
@@ -7095,6 +7201,8 @@ int MountVolume (HWND hwndDlg,
BOOL bResult, bDevice;
wchar_t root[MAX_PATH];
int favoriteMountOnArrivalRetryCount = 0;
+ BOOL useVolumeID = FALSE;
+ BYTE volumeID[VOLUME_ID_SIZE] = {0};
#ifdef TCMOUNT
if (mountOptions->PartitionInInactiveSysEncScope)
@@ -7181,7 +7289,29 @@ retry:
StringCchCopyW (volumePath, TC_MAX_PATH, resolvedPath.c_str());
}
- CreateFullVolumePath (mount.wszVolume, sizeof(mount.wszVolume), volumePath, &bDevice);
+ if ((path.length () >= 3) && (_wcsnicmp (path.c_str(), L"ID:", 3) == 0))
+ {
+ std::vector<byte> arr;
+ if ( (path.length() == (3 + 2*VOLUME_ID_SIZE))
+ && HexWideStringToArray (path.c_str() + 3, arr)
+ && (arr.size() == VOLUME_ID_SIZE)
+ )
+ {
+ useVolumeID = TRUE;
+ bDevice = TRUE;
+ memcpy (volumeID, &arr[0], VOLUME_ID_SIZE);
+ }
+ else
+ {
+ if (!quiet)
+ Error ("VOLUME_ID_INVALID", hwndDlg);
+
+ SetLastError (ERROR_INVALID_PARAMETER);
+ return -1;
+ }
+ }
+ else
+ CreateFullVolumePath (mount.wszVolume, sizeof(mount.wszVolume), volumePath, &bDevice);
if (!bDevice)
{
@@ -7257,6 +7387,8 @@ retry:
{
MountThreadParam mountThreadParam;
mountThreadParam.pmount = &mount;
+ mountThreadParam.useVolumeID = useVolumeID;
+ memcpy (mountThreadParam.volumeID, volumeID, VOLUME_ID_SIZE);
mountThreadParam.pbResult = &bResult;
mountThreadParam.pdwResult = &dwResult;
mountThreadParam.dwLastError = ERROR_SUCCESS;
@@ -7267,8 +7399,8 @@ retry:
}
else
{
- bResult = DeviceIoControl (hDriver, TC_IOCTL_MOUNT_VOLUME, &mount,
- sizeof (mount), &mount, sizeof (mount), &dwResult, NULL);
+ bResult = PerformMountIoctl (&mount, &dwResult, useVolumeID, volumeID);
+
dwLastError = GetLastError ();
}
@@ -7555,22 +7687,11 @@ BOOL IsPasswordCacheEmpty (void)
return !DeviceIoControl (hDriver, TC_IOCTL_GET_PASSWORD_CACHE_STATUS, 0, 0, 0, 0, &dw, 0);
}
-
-BOOL IsMountedVolume (const wchar_t *volname)
+BOOL IsMountedVolumeID (BYTE volumeID[VOLUME_ID_SIZE])
{
MOUNT_LIST_STRUCT mlist;
DWORD dwResult;
int i;
- wchar_t volume[TC_MAX_PATH*2+16];
-
- StringCbCopyW (volume, sizeof(volume), volname);
-
- if (wcsstr (volname, L"\\Device\\") != volname)
- StringCbPrintfW(volume, sizeof(volume), L"\\??\\%s", volname);
-
- wstring resolvedPath = VolumeGuidPathToDevicePath (volname);
- if (!resolvedPath.empty())
- StringCbCopyW (volume, sizeof (volume), resolvedPath.c_str());
memset (&mlist, 0, sizeof (mlist));
DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
@@ -7578,12 +7699,52 @@ BOOL IsMountedVolume (const wchar_t *volname)
NULL);
for (i=0 ; i<26; i++)
- if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], volume))
+ if (0 == memcmp (mlist.volumeID[i], volumeID, VOLUME_ID_SIZE))
return TRUE;
return FALSE;
}
+BOOL IsMountedVolume (const wchar_t *volname)
+{
+ if ((wcslen (volname) == (3 + 2*VOLUME_ID_SIZE)) && _wcsnicmp (volname, L"ID:", 3) == 0)
+ {
+ /* Volume ID specified. Use it for matching mounted volumes. */
+ std::vector<byte> arr;
+ if (HexWideStringToArray (&volname[3], arr) && (arr.size() == VOLUME_ID_SIZE))
+ {
+ return IsMountedVolumeID (&arr[0]);
+ }
+ }
+ else
+ {
+ MOUNT_LIST_STRUCT mlist;
+ DWORD dwResult;
+ int i;
+ wchar_t volume[TC_MAX_PATH*2+16];
+
+ StringCbCopyW (volume, sizeof(volume), volname);
+
+ if (wcsstr (volname, L"\\Device\\") != volname)
+ StringCbPrintfW(volume, sizeof(volume), L"\\??\\%s", volname);
+
+ wstring resolvedPath = VolumeGuidPathToDevicePath (volname);
+ if (!resolvedPath.empty())
+ StringCbCopyW (volume, sizeof (volume), resolvedPath.c_str());
+
+ memset (&mlist, 0, sizeof (mlist));
+ DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
+ sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
+ NULL);
+
+ for (i=0 ; i<26; i++)
+ if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], volume))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
int GetMountedVolumeDriveNo (wchar_t *volname)
{
@@ -10848,7 +11009,7 @@ std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool
const wchar_t *devPath = devPathStr.c_str();
OPEN_TEST_STRUCT openTest = {0};
- if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems && partNumber != 0))
+ if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems && partNumber != 0, FALSE, NULL))
{
if (partNumber == 0)
break;
@@ -10953,7 +11114,7 @@ std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool
const wchar_t *devPath = devPathStr.c_str();
OPEN_TEST_STRUCT openTest = {0};
- if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems))
+ if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems, FALSE, NULL))
continue;
DISK_PARTITION_INFO_STRUCT info;
@@ -10993,6 +11154,46 @@ std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool
return devices;
}
+wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE])
+{
+ /* if it is already mounted, get the real path name used for mounting */
+ MOUNT_LIST_STRUCT mlist;
+ DWORD dwResult;
+
+ memset (&mlist, 0, sizeof (mlist));
+ DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mlist,
+ sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
+ NULL);
+
+ for (int i=0 ; i < 26; i++)
+ {
+ if (0 == memcmp (mlist.volumeID[i], volumeID, VOLUME_ID_SIZE))
+ return mlist.wszVolume[i];
+ }
+
+ /* not mounted. Look for it in the local drives*/
+ for (int devNumber = 0; devNumber < MAX_HOST_DRIVE_NUMBER; devNumber++)
+ {
+ for (int partNumber = 0; partNumber < MAX_HOST_PARTITION_NUMBER; partNumber++)
+ {
+ wstringstream strm;
+ strm << L"\\Device\\Harddisk" << devNumber << L"\\Partition" << partNumber;
+ wstring devPathStr (strm.str());
+ const wchar_t *devPath = devPathStr.c_str();
+
+ OPEN_TEST_STRUCT openTest = {0};
+ if (!OpenDevice (devPath, &openTest, FALSE, TRUE, volumeID))
+ {
+ continue;
+ }
+
+ if (openTest.VolumeIDMatched)
+ return devPath;
+ }
+ }
+
+ return L"";
+}
BOOL FileHasReadOnlyAttribute (const wchar_t *path)
{
@@ -11215,7 +11416,7 @@ BOOL VolumePathExists (const wchar_t *volumePath)
UpperCaseCopy (upperCasePath, sizeof(upperCasePath), volumePath);
if (wcsstr (upperCasePath, L"\\DEVICE\\") == upperCasePath)
- return OpenDevice (volumePath, &openTest, FALSE);
+ return OpenDevice (volumePath, &openTest, FALSE, FALSE, NULL);
wstring path = volumePath;
if (path.find (L"\\\\?\\Volume{") == 0 && path.rfind (L"}\\") == path.size() - 2)
@@ -11575,3 +11776,89 @@ void ProcessEntropyEstimate (HWND hProgress, DWORD* pdwInitialValue, DWORD dwCou
0);
}
}
+
+void AllowMessageInUIPI (UINT msg)
+{
+ if (ChangeWindowMessageFilterFn)
+ {
+ ChangeWindowMessageFilterFn (msg, MSGFLT_ADD);
+ }
+}
+
+BOOL IsRepeatedByteArray (byte value, const byte* buffer, size_t bufferSize)
+{
+ if (buffer && bufferSize)
+ {
+ size_t i;
+ for (i = 0; i < bufferSize; i++)
+ {
+ if (*buffer++ != value)
+ return FALSE;
+ }
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+BOOL TranslateVolumeID (HWND hwndDlg, wchar_t* pathValue, size_t cchPathValue)
+{
+ BOOL bRet = TRUE;
+ size_t pathLen = pathValue? wcslen (pathValue) : 0;
+ if ((pathLen >= 3) && (_wcsnicmp (pathValue, L"ID:", 3) == 0))
+ {
+ std::vector<byte> arr;
+ if ( (pathLen == (3 + 2*VOLUME_ID_SIZE))
+ && HexWideStringToArray (pathValue + 3, arr)
+ && (arr.size() == VOLUME_ID_SIZE)
+ )
+ {
+ std::wstring devicePath = FindDeviceByVolumeID (&arr[0]);
+ if (devicePath.length() > 0)
+ StringCchCopyW (pathValue, cchPathValue, devicePath.c_str());
+ else
+ {
+ if (!Silent && !MultipleMountOperationInProgress)
+ Error ("VOLUME_ID_NOT_FOUND", hwndDlg);
+ SetLastError (ERROR_PATH_NOT_FOUND);
+ bRet = FALSE;
+ }
+ }
+ else
+ {
+ if (!Silent)
+ Error ("VOLUME_ID_INVALID", hwndDlg);
+
+ SetLastError (ERROR_INVALID_PARAMETER);
+ bRet = FALSE;
+ }
+ }
+
+ return bRet;
+}
+
+BOOL CopyTextToClipboard (LPCWSTR txtValue)
+{
+ size_t txtLen = wcslen(txtValue);
+ HGLOBAL hdst;
+ LPWSTR dst;
+ BOOL bRet = FALSE;
+
+ // Allocate string for cwd
+ hdst = GlobalAlloc(GMEM_MOVEABLE, (txtLen + 1) * sizeof(WCHAR));
+ if (hdst)
+ {
+ dst = (LPWSTR)GlobalLock(hdst);
+ wmemcpy(dst, txtValue, txtLen + 1);
+ GlobalUnlock(hdst);
+
+ if (OpenClipboard(NULL))
+ {
+ EmptyClipboard();
+ SetClipboardData(CF_UNICODETEXT, hdst);
+ CloseClipboard();
+ }
+ }
+
+ return bRet;
+}
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index 20199924..d9f29cd0 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -34,7 +34,8 @@ enum dynamic_gui_element_ids
IDPM_ADD_TO_FAVORITES,
IDPM_ADD_TO_SYSTEM_FAVORITES,
IDM_SHOW_HIDE,
- IDM_HOMEPAGE_SYSTRAY
+ IDM_HOMEPAGE_SYSTRAY,
+ IDPM_COPY_VALUE_TO_CLIPBOARD
};
enum
@@ -298,7 +299,7 @@ void InitOSVersionInfo ();
void InitApp ( HINSTANCE hInstance, wchar_t *lpszCommandLine );
void FinalizeApp (void);
void InitHelpFileName (void);
-BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem);
+BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL matchVolumeID, const BYTE* pbVolumeID);
void NotifyDriverOfPortableMode (void);
int GetAvailableFixedDisks ( HWND hComboBox , char *lpszRootPath );
int GetAvailableRemovables ( HWND hComboBox , char *lpszRootPath );
@@ -342,6 +343,7 @@ int MountVolume (HWND hwndDlg, int driveNo, wchar_t *volumePath, Password *passw
BOOL UnmountVolume (HWND hwndDlg , int nDosDriveNo, BOOL forceUnmount);
BOOL UnmountVolumeAfterFormatExCall (HWND hwndDlg, int nDosDriveNo);
BOOL IsPasswordCacheEmpty (void);
+BOOL IsMountedVolumeID (BYTE volumeID[VOLUME_ID_SIZE]);
BOOL IsMountedVolume (const wchar_t *volname);
int GetMountedVolumeDriveNo (wchar_t *volname);
BOOL IsAdmin (void);
@@ -500,6 +502,10 @@ HIMAGELIST CreateImageList(int cx, int cy, UINT flags, int cInitial, int cGrow)
int AddBitmapToImageList(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask);
HRESULT VCStrDupW(LPCWSTR psz, LPWSTR *ppwsz);
void ProcessEntropyEstimate (HWND hProgress, DWORD* pdwInitialValue, DWORD dwCounter, DWORD dwMaxLevel, DWORD* pdwEntropy);
+void AllowMessageInUIPI (UINT msg);
+BOOL IsRepeatedByteArray (byte value, const byte* buffer, size_t bufferSize);
+BOOL TranslateVolumeID (HWND hwndDlg, wchar_t* pathValue, size_t cchPathValue);
+BOOL CopyTextToClipboard (const wchar_t* txtValue);
#ifdef __cplusplus
}
@@ -564,6 +570,9 @@ std::wstring HarddiskVolumePathToPartitionPath (const std::wstring &harddiskVolu
std::wstring FindLatestFileOrDirectory (const std::wstring &directory, const wchar_t *namePattern, bool findDirectory, bool findFile);
std::wstring GetUserFriendlyVersionString (int version);
std::wstring IntToWideString (int val);
+std::wstring ArrayToHexWideString (const unsigned char* pbData, int cbData);
+bool HexWideStringToArray (const wchar_t* hexStr, std::vector<byte>& arr);
+std::wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE]);
void RegisterDriverInf (bool registerFilter, const std::string& filter, const std::string& filterReg, HWND ParentWindow, HKEY regKey);
std::wstring GetTempPathString ();
inline std::wstring AppendSrcPos (const wchar_t* msg, const char* srcPos)
diff --git a/src/Common/Language.xml b/src/Common/Language.xml
index d994bf63..f72e1a30 100644
--- a/src/Common/Language.xml
+++ b/src/Common/Language.xml
@@ -1388,6 +1388,14 @@
<string lang="en" key="INIT_DLL">Error: Failed to load a system library.</string>
<string lang="en" key="ERR_EXFAT_INVALID_VOLUME_SIZE">The volume file size specified in the command line is incompatible with selected exFAT filesystem.</string>
<control lang="en" key="IDT_ENTROPY_BAR">Randomness Collected From Mouse Movements</control>
+ <control lang="en" key="IDT_VOLUME_ID">Volume ID:</control>
+ <string lang="en" key="VOLUME_ID">Volume ID</string>
+ <control lang="en" key="IDC_FAVORITE_USE_VOLUME_ID">Use Volume ID to mount favorite</control>
+ <string lang="en" key="VOLUME_ID_INVALID">The Volume ID value is invalid</string>
+ <string lang="en" key="VOLUME_ID_NOT_FOUND">No Volume with the specified ID was found on the system</string>
+ <string lang="en" key="IDPM_COPY_VALUE_TO_CLIPBOARD">Copy Value to Clipboard...</string>
+ <control lang="en" key="IDC_DISABLE_BOOT_LOADER_PIM_PROMPT">Do not request PIM in the pre-boot authentication screen (PIM value is stored unencrypted on disk)</control>
+ <string lang="en" key="DISABLE_BOOT_LOADER_PIM_PROMPT">WARNING: Please keep in mind that if you enable this option, the PIM value will be stored unencrypted on the disk.\n\nAre you sure you want to enable this option?</string>
</localization>
<!-- XML Schema -->
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
diff --git a/src/Common/Volumes.c b/src/Common/Volumes.c
index b7c77e9c..955c7e48 100644
--- a/src/Common/Volumes.c
+++ b/src/Common/Volumes.c
@@ -590,6 +590,7 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS
{
// compute Whirlpool+SHA512 fingerprint of bootloader including MBR
// we skip user configuration fields:
+ // TC_BOOT_SECTOR_PIM_VALUE_OFFSET = 400
// TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET = 402
// => TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_SIZE = 4
// TC_BOOT_SECTOR_USER_MESSAGE_OFFSET = 406
@@ -604,8 +605,8 @@ void ComputeBootloaderFingerprint (byte *bootLoaderBuf, unsigned int bootLoaderS
WHIRLPOOL_init (&whirlpool);
sha512_begin (&sha2);
- WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET * 8, &whirlpool);
- sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_OUTER_VOLUME_BAK_HEADER_CRC_OFFSET, &sha2);
+ WHIRLPOOL_add (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET * 8, &whirlpool);
+ sha512_hash (bootLoaderBuf, TC_BOOT_SECTOR_PIM_VALUE_OFFSET, &sha2);
WHIRLPOOL_add (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)) * 8, &whirlpool);
sha512_hash (bootLoaderBuf + TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH, (TC_BOOT_SECTOR_USER_CONFIG_OFFSET - (TC_BOOT_SECTOR_USER_MESSAGE_OFFSET + TC_BOOT_SECTOR_USER_MESSAGE_MAX_LENGTH)), &sha2);
@@ -1005,7 +1006,7 @@ int CreateVolumeHeaderInMemory (HWND hwndDlg, BOOL bBoot, char *header, int ea,
#ifdef VOLFORMAT
- if (showKeys && !bInPlaceEncNonSys)
+ if (!bInPlaceEncNonSys && (showKeys || (bBoot && !masterKeydata)))
{
BOOL dots3 = FALSE;
int i, j;