From 60575d9a496bd4b796bab73888b69c249a1f8048 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Fri, 8 Apr 2016 23:51:29 +0200 Subject: Windows: start implementation of volume ID mechanism that will be used to identify VeraCrypt disk volumes instead of device name. --- src/Common/Apidrvr.h | 5 ++ src/Common/Dlgcode.c | 219 +++++++++++++++++++++++++++++++++++++++++++----- src/Common/Dlgcode.h | 6 +- src/Common/Language.xml | 3 + src/Driver/Ntdriver.c | 111 +++++++++++++++++------- src/Driver/Ntdriver.h | 2 + src/Driver/Ntvol.c | 3 + src/Mount/Favorites.cpp | 42 ++++++++++ src/Mount/Favorites.h | 6 +- src/Mount/Mount.c | 10 ++- src/Mount/Mount.rc | 44 +++++----- src/Mount/Resource.h | 5 +- 12 files changed, 380 insertions(+), 76 deletions(-) diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 2cfa369f..867366b9 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][SHA512_DIGEST_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[SHA512_DIGESTSIZE]; } VOLUME_PROPERTIES_STRUCT; typedef struct @@ -194,6 +196,9 @@ typedef struct BOOL TCBootLoaderDetected; BOOL DetectFilesystem; BOOL FilesystemDetected; + BOOL bMatchVolumeID; + unsigned char volumeID[SHA512_DIGEST_SIZE]; + BOOL VolumeIDMatched; } OPEN_TEST_STRUCT; diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 749caa40..02d9b499 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -2930,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, BYTE* pbVolumeID) { DWORD dwResult; BOOL bResult; @@ -2943,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, SHA512_DIGEST_SIZE); bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, driver, sizeof (OPEN_TEST_STRUCT), @@ -4712,6 +4715,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& 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]; @@ -7069,12 +7121,37 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v /************************************************************************/ +static BOOL PerformMountIoctl (MOUNT_STRUCT* pmount, LPDWORD pdwResult, BOOL useVolumeID, BYTE volumeID[SHA512_DIGEST_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[SHA512_DIGEST_SIZE]; BOOL* pbResult; DWORD* pdwResult; DWORD dwLastError; @@ -7084,8 +7161,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 (); } @@ -7122,6 +7198,8 @@ int MountVolume (HWND hwndDlg, BOOL bResult, bDevice; wchar_t root[MAX_PATH]; int favoriteMountOnArrivalRetryCount = 0; + BOOL useVolumeID = FALSE; + BYTE volumeID[SHA512_DIGEST_SIZE] = {0}; #ifdef TCMOUNT if (mountOptions->PartitionInInactiveSysEncScope) @@ -7208,7 +7286,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 arr; + if ( (path.length() == (3 + 2*SHA512_DIGEST_SIZE)) + && HexWideStringToArray (path.c_str() + 3, arr) + && (arr.size() == SHA512_DIGEST_SIZE) + ) + { + useVolumeID = TRUE; + bDevice = TRUE; + memcpy (volumeID, &arr[0], SHA512_DIGEST_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) { @@ -7284,6 +7384,8 @@ retry: { MountThreadParam mountThreadParam; mountThreadParam.pmount = &mount; + mountThreadParam.useVolumeID = useVolumeID; + memcpy (mountThreadParam.volumeID, volumeID, SHA512_DIGESTSIZE); mountThreadParam.pbResult = &bResult; mountThreadParam.pdwResult = &dwResult; mountThreadParam.dwLastError = ERROR_SUCCESS; @@ -7294,8 +7396,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 (); } @@ -7588,25 +7690,40 @@ BOOL IsMountedVolume (const wchar_t *volname) 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; + if ((wcslen (volname) == (3 + 2*SHA512_DIGEST_SIZE)) && _wcsnicmp (volname, L"ID:", 3) == 0) + { + /* Volume ID specified. Use it for matching mounted volumes. */ + std::vector arr; + if (HexWideStringToArray (&volname[3], arr) && (arr.size() == SHA512_DIGEST_SIZE)) + { + for (i=0 ; i<26; i++) + if (0 == memcmp (mlist.volumeID[i], &arr[0], SHA512_DIGEST_SIZE)) + return TRUE; + } + } + else + { + 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()); + + for (i=0 ; i<26; i++) + if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], volume)) + return TRUE; + } return FALSE; } @@ -10875,7 +10992,7 @@ std::vector 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; @@ -10980,7 +11097,7 @@ std::vector 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; @@ -11020,6 +11137,30 @@ std::vector GetAvailableHostDevices (bool noDeviceProperties, bool return devices; } +wstring FindDeviceByVolumeID (BYTE volumeID [SHA512_DIGEST_SIZE]) +{ + 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) { @@ -11241,8 +11382,25 @@ BOOL VolumePathExists (const wchar_t *volumePath) UpperCaseCopy (upperCasePath, sizeof(upperCasePath), volumePath); + if (wcsstr (upperCasePath, L"ID:") == upperCasePath) + { + std::vector arr; + if ( (wcslen (upperCasePath) == (3 + 2*SHA512_DIGEST_SIZE)) + && HexWideStringToArray (&upperCasePath[3], arr) + && (arr.size() == SHA512_DIGEST_SIZE) + ) + { + if (FindDeviceByVolumeID (&arr[0]).length() > 0) + return TRUE; + else + return FALSE; + } + else + return FALSE; + } + 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) @@ -11610,3 +11768,20 @@ void AllowMessageInUIPI (UINT msg) 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; +} + diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index ef00871e..a2f69bad 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -298,7 +298,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, BYTE* pbVolumeID); void NotifyDriverOfPortableMode (void); int GetAvailableFixedDisks ( HWND hComboBox , char *lpszRootPath ); int GetAvailableRemovables ( HWND hComboBox , char *lpszRootPath ); @@ -501,6 +501,7 @@ 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); #ifdef __cplusplus } @@ -565,6 +566,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& arr); +std::wstring FindDeviceByVolumeID (BYTE volumeID [SHA512_DIGEST_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..42be6bd4 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1388,6 +1388,9 @@ Error: Failed to load a system library. The volume file size specified in the command line is incompatible with selected exFAT filesystem. Randomness Collected From Mouse Movements + Volume ID: + Use Volume ID to mount favorite + The Volume ID value is invalid diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index 5153c67b..cd3309d2 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -975,7 +975,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); - if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem) + if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID) access |= FILE_READ_DATA; ntStatus = ZwCreateFile (&NtFileHandle, @@ -986,8 +986,9 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex { opentest->TCBootLoaderDetected = FALSE; opentest->FilesystemDetected = FALSE; + opentest->VolumeIDMatched = FALSE; - if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem) + if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID) { byte *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE); if (!readBuffer) @@ -996,49 +997,99 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex } else { - // Determine if the first sector contains a portion of the VeraCrypt Boot Loader - - offset.QuadPart = 0; + if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem) + { + // Determine if the first sector contains a portion of the VeraCrypt Boot Loader - ntStatus = ZwReadFile (NtFileHandle, - NULL, - NULL, - NULL, - &IoStatus, - readBuffer, - TC_MAX_VOLUME_SECTOR_SIZE, - &offset, - NULL); + offset.QuadPart = 0; - if (NT_SUCCESS (ntStatus)) - { - size_t i; + ntStatus = ZwReadFile (NtFileHandle, + NULL, + NULL, + NULL, + &IoStatus, + readBuffer, + TC_MAX_VOLUME_SECTOR_SIZE, + &offset, + NULL); - if (opentest->bDetectTCBootLoader && IoStatus.Information >= TC_SECTOR_SIZE_BIOS) + if (NT_SUCCESS (ntStatus)) { - // Search for the string "VeraCrypt" - for (i = 0; i < TC_SECTOR_SIZE_BIOS - strlen (TC_APP_NAME); ++i) + size_t i; + + if (opentest->bDetectTCBootLoader && IoStatus.Information >= TC_SECTOR_SIZE_BIOS) { - if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) + // Search for the string "VeraCrypt" + for (i = 0; i < TC_SECTOR_SIZE_BIOS - strlen (TC_APP_NAME); ++i) { - opentest->TCBootLoaderDetected = TRUE; + if (memcmp (readBuffer + i, TC_APP_NAME, strlen (TC_APP_NAME)) == 0) + { + opentest->TCBootLoaderDetected = TRUE; + break; + } + } + } + + if (opentest->DetectFilesystem && IoStatus.Information >= sizeof (int64)) + { + switch (BE64 (*(uint64 *) readBuffer)) + { + case 0xEB52904E54465320: // NTFS + case 0xEB3C904D53444F53: // FAT16 + case 0xEB58904D53444F53: // FAT32 + case 0xEB76904558464154: // exFAT + + opentest->FilesystemDetected = TRUE; break; } } } + } - if (opentest->DetectFilesystem && IoStatus.Information >= sizeof (int64)) + if (opentest->bMatchVolumeID) + { + int volumeType; + BYTE volumeID[SHA512_DIGEST_SIZE]; + + // Go through all volume types (e.g., normal, hidden) + for (volumeType = TC_VOLUME_TYPE_NORMAL; + volumeType < TC_VOLUME_TYPE_COUNT; + volumeType++) { - switch (BE64 (*(uint64 *) readBuffer)) + /* Read the volume header */ + switch (volumeType) { - case 0xEB52904E54465320: // NTFS - case 0xEB3C904D53444F53: // FAT16 - case 0xEB58904D53444F53: // FAT32 - case 0xEB76904558464154: // exFAT + case TC_VOLUME_TYPE_NORMAL: + offset.QuadPart = TC_VOLUME_HEADER_OFFSET; + break; - opentest->FilesystemDetected = TRUE; + case TC_VOLUME_TYPE_HIDDEN: + + offset.QuadPart = TC_HIDDEN_VOLUME_HEADER_OFFSET; break; } + + ntStatus = ZwReadFile (Extension->hDeviceFile, + NULL, + NULL, + NULL, + &IoStatus, + readBuffer, + TC_MAX_VOLUME_SECTOR_SIZE, + &offset, + NULL); + + if (NT_SUCCESS (ntStatus)) + { + /* compute the ID of this volume: SHA-512 of the effective header */ + sha512 (volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); + + if (0 == memcmp (volumeID, opentest->volumeID, SHA512_DIGEST_SIZE)) + { + opentest->VolumeIDMatched = TRUE; + break; + } + } } } @@ -1214,6 +1265,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex list->ulMountedDrives |= (1 << ListExtension->nDosDriveNo); RtlStringCbCopyW (list->wszVolume[ListExtension->nDosDriveNo], sizeof(list->wszVolume[ListExtension->nDosDriveNo]),ListExtension->wszVolume); RtlStringCbCopyW (list->wszLabel[ListExtension->nDosDriveNo], sizeof(list->wszLabel[ListExtension->nDosDriveNo]),ListExtension->wszLabel); + memcpy (list->volumeID[ListExtension->nDosDriveNo], ListExtension->volumeID, SHA512_DIGEST_SIZE); list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength; list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea; if (ListExtension->cryptoInfo->hiddenVolume) @@ -1265,6 +1317,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex prop->uniqueId = ListExtension->UniqueVolumeId; RtlStringCbCopyW (prop->wszVolume, sizeof(prop->wszVolume),ListExtension->wszVolume); RtlStringCbCopyW (prop->wszLabel, sizeof(prop->wszLabel),ListExtension->wszLabel); + memcpy (prop->volumeID, ListExtension->volumeID, SHA512_DIGEST_SIZE); prop->bDriverSetLabel = ListExtension->bDriverSetLabel; prop->diskLength = ListExtension->DiskLength; prop->ea = ListExtension->cryptoInfo->ea; diff --git a/src/Driver/Ntdriver.h b/src/Driver/Ntdriver.h index 21051e44..ae91f3af 100644 --- a/src/Driver/Ntdriver.h +++ b/src/Driver/Ntdriver.h @@ -81,6 +81,8 @@ typedef struct EXTENSION BOOL bIsNTFS; BOOL bDriverSetLabel; + unsigned char volumeID[SHA512_DIGESTSIZE]; + LARGE_INTEGER fileCreationTime; LARGE_INTEGER fileLastAccessTime; LARGE_INTEGER fileLastWriteTime; diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index 46dd46fd..317e3653 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -517,6 +517,9 @@ NTSTATUS TCOpenVolume (PDEVICE_OBJECT DeviceObject, Extension->cryptoInfo->bPartitionInInactiveSysEncScope = mount->bPartitionInInactiveSysEncScope; + /* compute the ID of this volume: SHA-512 of the effective header */ + sha512 (Extension->volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); + if (volumeType == TC_VOLUME_TYPE_NORMAL) { if (mount->bPartitionInInactiveSysEncScope) diff --git a/src/Mount/Favorites.cpp b/src/Mount/Favorites.cpp index 825562f2..5dde8da0 100644 --- a/src/Mount/Favorites.cpp +++ b/src/Mount/Favorites.cpp @@ -98,6 +98,7 @@ namespace VeraCrypt favorite.SystemEncryption = prop.partitionInInactiveSysEncScope ? true : false; favorite.OpenExplorerWindow = (bExplore == TRUE); favorite.Pim = prop.volumePim; + memcpy (favorite.VolumeID, prop.volumeID, SHA512_DIGESTSIZE); if (favorite.VolumePathId.empty() && IsVolumeDeviceHosted (favorite.Path.c_str()) @@ -416,6 +417,19 @@ namespace VeraCrypt case WM_CLOSE: EndDialog (hwndDlg, IDCLOSE); return 1; + case WM_CTLCOLORSTATIC: + { + HDC hdc = (HDC) wParam; + HWND hw = (HWND) lParam; + if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_ID)) + { + // This the favorite ID field. Make its background like normal edit + HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW); + ::SelectObject(hdc, hbr); + return (BOOL) hbr; + } + } + break; } return 0; @@ -566,6 +580,17 @@ namespace VeraCrypt favorite.Path = Utf8StringToWide (volume); char label[1024]; + + XmlGetAttributeText (xml, "ID", label, sizeof (label)); + if (strlen (label) == 128) + { + std::vector arr; + if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == SHA512_DIGEST_SIZE) + { + memcpy (favorite.VolumeID, &arr[0], SHA512_DIGEST_SIZE); + } + } + XmlGetAttributeText (xml, "label", label, sizeof (label)); favorite.Label = Utf8StringToWide (label); @@ -612,6 +637,10 @@ namespace VeraCrypt if (boolVal[0]) favorite.UseLabelInExplorer = (boolVal[0] == '1') && !favorite.ReadOnly; + XmlGetAttributeText (xml, "useVolumeID", boolVal, sizeof (boolVal)); + if (boolVal[0]) + favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, SHA512_DIGEST_SIZE); + if (favorite.Path.find (L"\\\\?\\Volume{") == 0 && favorite.Path.rfind (L"}\\") == favorite.Path.size() - 2) { wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path); @@ -709,6 +738,9 @@ namespace VeraCrypt wstring s = L"\n\t\t" + wstring (tq) + L""; fwprintf (f, L"%ws", s.c_str()); @@ -819,6 +854,12 @@ namespace VeraCrypt SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_ON_ARRIVAL, favorite.MountOnArrival); SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_READONLY, favorite.ReadOnly); SetCheckBox (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE, favorite.Removable); + SetCheckBox (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID, favorite.UseVolumeID); + + if (!IsRepeatedByteArray (0, favorite.VolumeID, SHA512_DIGESTSIZE)) + { + SetDlgItemText (hwndDlg, IDC_FAVORITE_ID, ArrayToHexWideString (favorite.VolumeID, SHA512_DIGESTSIZE).c_str()); + } if (systemFavoritesMode) { @@ -873,6 +914,7 @@ namespace VeraCrypt favorite.Pim = GetPim (hwndDlg, IDC_PIM); favorite.UseLabelInExplorer = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_LABEL_IN_EXPLORER) != 0); + favorite.UseVolumeID = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID) != 0); favorite.ReadOnly = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_READONLY) != 0); favorite.Removable = (IsDlgButtonChecked (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE) != 0); diff --git a/src/Mount/Favorites.h b/src/Mount/Favorites.h index 8195eb7b..538ec1db 100644 --- a/src/Mount/Favorites.h +++ b/src/Mount/Favorites.h @@ -30,8 +30,10 @@ namespace VeraCrypt ReadOnly (false), Removable (false), SystemEncryption (false), - UseLabelInExplorer (false) + UseLabelInExplorer (false), + UseVolumeID (false) { + memset (VolumeID, 0, SHA512_DIGESTSIZE); } wstring Path; @@ -39,6 +41,7 @@ namespace VeraCrypt wstring VolumePathId; wstring Label; int Pim; + BYTE VolumeID[SHA512_DIGESTSIZE]; bool DisableHotkeyMount; bool DisconnectedDevice; @@ -49,6 +52,7 @@ namespace VeraCrypt bool Removable; bool SystemEncryption; bool UseLabelInExplorer; + bool UseVolumeID; }; struct FavoriteVolumesDlgProcArguments diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 0acf58dd..dc7d825d 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -7065,7 +7065,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa { OPEN_TEST_STRUCT ots = {0}; - if (!OpenDevice (vol, &ots, FALSE)) + if (!OpenDevice (vol, &ots, FALSE, FALSE, NULL)) { UnmountVolume (hwndDlg, m, TRUE); WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg); @@ -8899,6 +8899,7 @@ static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, { BOOL status = TRUE; int drive; + std::wstring effectiveVolumePath; drive = towupper (favorite.MountPoint[0]) - L'A'; if ((drive < MIN_MOUNTED_VOLUME_DRIVE_NUMBER) || (drive > MAX_MOUNTED_VOLUME_DRIVE_NUMBER)) @@ -8919,6 +8920,11 @@ static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, else ZeroMemory (mountOptions.Label, sizeof (mountOptions.Label)); + if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, SHA512_DIGEST_SIZE)) + effectiveVolumePath = L"ID:" + ArrayToHexWideString (favorite.VolumeID, SHA512_DIGEST_SIZE); + else + effectiveVolumePath = favorite.Path; + if (favorite.SystemEncryption) { mountOptions.PartitionInInactiveSysEncScope = TRUE; @@ -8978,7 +8984,7 @@ static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, if (ServiceMode) SystemFavoritesServiceLogInfo (wstring (L"Mounting system favorite \"") + favorite.Path + L"\""); - status = Mount (hwnd, drive, (wchar_t *) favorite.Path.c_str(), favorite.Pim); + status = Mount (hwnd, drive, (wchar_t *) effectiveVolumePath.c_str(), favorite.Pim); if (ServiceMode) { diff --git a/src/Mount/Mount.rc b/src/Mount/Mount.rc index f7f927e3..eb3178a0 100644 --- a/src/Mount/Mount.rc +++ b/src/Mount/Mount.rc @@ -330,7 +330,7 @@ BEGIN "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,198,337,10 END -IDD_FAVORITE_VOLUMES DIALOGEX 0, 0, 380, 339 +IDD_FAVORITE_VOLUMES DIALOGEX 0, 0, 380, 368 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "VeraCrypt - Favorite Volumes" FONT 8, "MS Shell Dlg", 400, 0, 0x1 @@ -339,31 +339,35 @@ BEGIN PUSHBUTTON "Move &Up",IDC_FAVORITE_MOVE_UP,7,104,63,14 PUSHBUTTON "Move &Down",IDC_FAVORITE_MOVE_DOWN,74,104,63,14 PUSHBUTTON "&Remove",IDC_FAVORITE_REMOVE,310,104,63,14 - EDITTEXT IDC_FAVORITE_LABEL,18,185,204,13,ES_AUTOHSCROLL + EDITTEXT IDC_FAVORITE_LABEL,18,225,204,13,ES_AUTOHSCROLL CONTROL "Mount selected volume as read-o&nly",IDC_FAVORITE_MOUNT_READONLY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,215,349,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,255,349,10 CONTROL "Mount selected volume as remo&vable medium",IDC_FAVORITE_MOUNT_REMOVABLE, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,229,349,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,269,349,10 CONTROL "Mount selected volume upon log&on",IDC_FAVORITE_MOUNT_ON_LOGON, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,243,349,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,283,349,10 CONTROL "Mount selected volume when its host device gets &connected",IDC_FAVORITE_MOUNT_ON_ARRIVAL, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,257,349,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,297,349,10 CONTROL "Open &Explorer window for selected volume when successfully mounted",IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,271,349,11 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,311,349,11 CONTROL "Do not mount selected volume when 'Mount Favorite Volumes' &hot key is pressed",IDC_FAVORITE_DISABLE_HOTKEY, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,286,349,11 - LTEXT "Help on favorite volumes",IDC_FAVORITES_HELP_LINK,17,322,237,10,SS_NOTIFY - DEFPUSHBUTTON "OK",IDOK,269,318,50,14 - PUSHBUTTON "Cancel",IDCANCEL,323,318,50,14 - GROUPBOX "",IDC_FAV_VOL_OPTIONS_GROUP_BOX,7,122,366,180 - LTEXT "Label of selected favorite volume:",IDT_FAVORITE_LABEL,18,175,202,8 - GROUPBOX "Global Settings",IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX,7,260,366,42 - EDITTEXT IDC_PIM,18,143,42,13,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER - LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,64,145,189,8 - LTEXT "Volume PIM:",IDT_PIM,18,133,65,8 - CONTROL "Display PIM",IDC_SHOW_PIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,159,150,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,326,349,11 + LTEXT "Help on favorite volumes",IDC_FAVORITES_HELP_LINK,17,351,237,10,SS_NOTIFY + DEFPUSHBUTTON "OK",IDOK,269,347,50,14 + PUSHBUTTON "Cancel",IDCANCEL,323,347,50,14 + GROUPBOX "",IDC_FAV_VOL_OPTIONS_GROUP_BOX,7,123,366,219 + LTEXT "Label of selected favorite volume:",IDT_FAVORITE_LABEL,18,215,202,8 + GROUPBOX "Global Settings",IDC_FAV_VOL_OPTIONS_GLOBAL_SETTINGS_BOX,7,300,366,42 + EDITTEXT IDC_PIM,18,183,42,13,ES_RIGHT | ES_PASSWORD | ES_AUTOHSCROLL | ES_NUMBER + LTEXT "(Empty or 0 for default iterations)",IDC_PIM_HELP,64,185,189,8 + LTEXT "Volume PIM:",IDT_PIM,18,173,65,8 + CONTROL "Display PIM",IDC_SHOW_PIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,199,150,10 CONTROL "Use favorite label as Explorer drive label",IDC_FAVORITE_USE_LABEL_IN_EXPLORER, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,202,349,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,242,349,10 + LTEXT "Volume ID:",IDT_FAVORITE_ID,18,131,57,8 + EDITTEXT IDC_FAVORITE_ID,18,141,204,14,ES_AUTOHSCROLL | ES_READONLY + CONTROL "Use Volume ID to mount favorite",IDC_FAVORITE_USE_VOLUME_ID, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,159,337,10 END IDD_DEFAULT_MOUNT_PARAMETERS DIALOGEX 0, 0, 167, 65 @@ -468,7 +472,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 373 TOPMARGIN, 7 - BOTTOMMARGIN, 332 + BOTTOMMARGIN, 361 END IDD_DEFAULT_MOUNT_PARAMETERS, DIALOG diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h index 1a3bc9b4..1cacfcd7 100644 --- a/src/Mount/Resource.h +++ b/src/Mount/Resource.h @@ -176,6 +176,9 @@ #define IDC_PREF_CACHE_PIM 1154 #define IDC_BOOT_LOADER_CACHE_PIM 1155 #define IDC_SHOW_DISCONNECTED_NETWORK_DRIVES 1156 +#define IDT_FAVORITE_ID 1157 +#define IDC_FAVORITE_ID 1158 +#define IDC_FAVORITE_USE_VOLUME_ID 1159 #define IDM_HELP 40001 #define IDM_ABOUT 40002 #define IDM_UNMOUNT_VOLUME 40003 @@ -252,7 +255,7 @@ #define _APS_NO_MFC 1 #define _APS_NEXT_RESOURCE_VALUE 119 #define _APS_NEXT_COMMAND_VALUE 40069 -#define _APS_NEXT_CONTROL_VALUE 1157 +#define _APS_NEXT_CONTROL_VALUE 1160 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif -- cgit v1.2.3