From f5606a44a6331715e9a8a43d6f4441f0cd89cb3a Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 14 Apr 2016 08:52:06 +0200 Subject: Windows: Finalize implementation of the new volume ID mechanism. Use SHA-256 instead of SHA-512 to compute volume ID to reduce string size and make more convenient to use. --- src/Common/Apidrvr.h | 6 +- src/Common/Common.h | 2 + src/Common/Dlgcode.c | 143 +++++++++++++++++++++------- src/Common/Dlgcode.h | 10 +- src/Common/Language.xml | 5 +- src/Driver/Ntdriver.c | 14 +-- src/Driver/Ntdriver.h | 2 +- src/Driver/Ntvol.c | 2 +- src/Mount/Favorites.cpp | 65 ++++++++++--- src/Mount/Favorites.h | 4 +- src/Mount/Mount.c | 245 ++++++++++++++++++++++++++++++++++++++++++++---- src/Mount/Resource.h | 4 +- 12 files changed, 416 insertions(+), 86 deletions(-) diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h index 867366b9..f584582e 100644 --- a/src/Common/Apidrvr.h +++ b/src/Common/Apidrvr.h @@ -128,7 +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 */ + 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.) */ @@ -157,7 +157,7 @@ typedef struct int volumePim; wchar_t wszLabel[33]; BOOL bDriverSetLabel; - unsigned char volumeID[SHA512_DIGESTSIZE]; + unsigned char volumeID[VOLUME_ID_SIZE]; } VOLUME_PROPERTIES_STRUCT; typedef struct @@ -197,7 +197,7 @@ typedef struct BOOL DetectFilesystem; BOOL FilesystemDetected; BOOL bMatchVolumeID; - unsigned char volumeID[SHA512_DIGEST_SIZE]; + unsigned char volumeID[VOLUME_ID_SIZE]; BOOL VolumeIDMatched; } OPEN_TEST_STRUCT; 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/Dlgcode.c b/src/Common/Dlgcode.c index 02d9b499..77210029 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 matchVolumeID, BYTE* pbVolumeID) +BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL matchVolumeID, const BYTE* pbVolumeID) { DWORD dwResult; BOOL bResult; @@ -2945,7 +2945,7 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF driver->DetectFilesystem = detectFilesystem; driver->bMatchVolumeID = matchVolumeID; if (matchVolumeID && pbVolumeID) - memcpy (driver->volumeID, pbVolumeID, SHA512_DIGEST_SIZE); + memcpy (driver->volumeID, pbVolumeID, VOLUME_ID_SIZE); bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST, driver, sizeof (OPEN_TEST_STRUCT), @@ -2973,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 @@ -7121,7 +7122,7 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v /************************************************************************/ -static BOOL PerformMountIoctl (MOUNT_STRUCT* pmount, LPDWORD pdwResult, BOOL useVolumeID, BYTE volumeID[SHA512_DIGEST_SIZE]) +static BOOL PerformMountIoctl (MOUNT_STRUCT* pmount, LPDWORD pdwResult, BOOL useVolumeID, BYTE volumeID[VOLUME_ID_SIZE]) { if (useVolumeID) { @@ -7151,7 +7152,7 @@ typedef struct { MOUNT_STRUCT* pmount; BOOL useVolumeID; - BYTE volumeID[SHA512_DIGEST_SIZE]; + BYTE volumeID[VOLUME_ID_SIZE]; BOOL* pbResult; DWORD* pdwResult; DWORD dwLastError; @@ -7199,7 +7200,7 @@ int MountVolume (HWND hwndDlg, wchar_t root[MAX_PATH]; int favoriteMountOnArrivalRetryCount = 0; BOOL useVolumeID = FALSE; - BYTE volumeID[SHA512_DIGEST_SIZE] = {0}; + BYTE volumeID[VOLUME_ID_SIZE] = {0}; #ifdef TCMOUNT if (mountOptions->PartitionInInactiveSysEncScope) @@ -7289,14 +7290,14 @@ retry: if ((path.length () >= 3) && (_wcsnicmp (path.c_str(), L"ID:", 3) == 0)) { std::vector arr; - if ( (path.length() == (3 + 2*SHA512_DIGEST_SIZE)) + if ( (path.length() == (3 + 2*VOLUME_ID_SIZE)) && HexWideStringToArray (path.c_str() + 3, arr) - && (arr.size() == SHA512_DIGEST_SIZE) + && (arr.size() == VOLUME_ID_SIZE) ) { useVolumeID = TRUE; bDevice = TRUE; - memcpy (volumeID, &arr[0], SHA512_DIGEST_SIZE); + memcpy (volumeID, &arr[0], VOLUME_ID_SIZE); } else { @@ -7385,7 +7386,7 @@ retry: MountThreadParam mountThreadParam; mountThreadParam.pmount = &mount; mountThreadParam.useVolumeID = useVolumeID; - memcpy (mountThreadParam.volumeID, volumeID, SHA512_DIGESTSIZE); + memcpy (mountThreadParam.volumeID, volumeID, VOLUME_ID_SIZE); mountThreadParam.pbResult = &bResult; mountThreadParam.pdwResult = &dwResult; mountThreadParam.dwLastError = ERROR_SUCCESS; @@ -7684,8 +7685,7 @@ 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; @@ -7696,19 +7696,29 @@ BOOL IsMountedVolume (const wchar_t *volname) sizeof (mlist), &mlist, sizeof (mlist), &dwResult, NULL); - if ((wcslen (volname) == (3 + 2*SHA512_DIGEST_SIZE)) && _wcsnicmp (volname, L"ID:", 3) == 0) + for (i=0 ; i<26; i++) + 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 arr; - if (HexWideStringToArray (&volname[3], arr) && (arr.size() == SHA512_DIGEST_SIZE)) + if (HexWideStringToArray (&volname[3], arr) && (arr.size() == VOLUME_ID_SIZE)) { - for (i=0 ; i<26; i++) - if (0 == memcmp (mlist.volumeID[i], &arr[0], SHA512_DIGEST_SIZE)) - return TRUE; + 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); @@ -7720,6 +7730,11 @@ BOOL IsMountedVolume (const wchar_t *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; @@ -11137,8 +11152,24 @@ std::vector GetAvailableHostDevices (bool noDeviceProperties, bool return devices; } -wstring FindDeviceByVolumeID (BYTE volumeID [SHA512_DIGEST_SIZE]) +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++) @@ -11382,23 +11413,6 @@ 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, FALSE, NULL); @@ -11785,3 +11799,64 @@ BOOL IsRepeatedByteArray (byte value, const byte* buffer, size_t bufferSize) 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 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 a2f69bad..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 matchVolumeID, BYTE* pbVolumeID); +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); @@ -502,6 +504,8 @@ 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 } @@ -568,7 +572,7 @@ 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]); +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 42be6bd4..cebbc92d 100644 --- a/src/Common/Language.xml +++ b/src/Common/Language.xml @@ -1388,9 +1388,12 @@ 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: + Volume ID: + Volume ID Use Volume ID to mount favorite The Volume ID value is invalid + No Volume with the specified ID was found on the system + Copy Value to Clipboard... diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c index cd3309d2..eeea7815 100644 --- a/src/Driver/Ntdriver.c +++ b/src/Driver/Ntdriver.c @@ -1049,7 +1049,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (opentest->bMatchVolumeID) { int volumeType; - BYTE volumeID[SHA512_DIGEST_SIZE]; + BYTE volumeID[VOLUME_ID_SIZE]; // Go through all volume types (e.g., normal, hidden) for (volumeType = TC_VOLUME_TYPE_NORMAL; @@ -1069,7 +1069,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex break; } - ntStatus = ZwReadFile (Extension->hDeviceFile, + ntStatus = ZwReadFile (NtFileHandle, NULL, NULL, NULL, @@ -1081,10 +1081,10 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex if (NT_SUCCESS (ntStatus)) { - /* compute the ID of this volume: SHA-512 of the effective header */ - sha512 (volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); + /* compute the ID of this volume: SHA-256 of the effective header */ + sha256 (volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); - if (0 == memcmp (volumeID, opentest->volumeID, SHA512_DIGEST_SIZE)) + if (0 == memcmp (volumeID, opentest->volumeID, VOLUME_ID_SIZE)) { opentest->VolumeIDMatched = TRUE; break; @@ -1265,7 +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); + memcpy (list->volumeID[ListExtension->nDosDriveNo], ListExtension->volumeID, VOLUME_ID_SIZE); list->diskLength[ListExtension->nDosDriveNo] = ListExtension->DiskLength; list->ea[ListExtension->nDosDriveNo] = ListExtension->cryptoInfo->ea; if (ListExtension->cryptoInfo->hiddenVolume) @@ -1317,7 +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); + memcpy (prop->volumeID, ListExtension->volumeID, VOLUME_ID_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 ae91f3af..59634760 100644 --- a/src/Driver/Ntdriver.h +++ b/src/Driver/Ntdriver.h @@ -81,7 +81,7 @@ typedef struct EXTENSION BOOL bIsNTFS; BOOL bDriverSetLabel; - unsigned char volumeID[SHA512_DIGESTSIZE]; + unsigned char volumeID[VOLUME_ID_SIZE]; LARGE_INTEGER fileCreationTime; LARGE_INTEGER fileLastAccessTime; diff --git a/src/Driver/Ntvol.c b/src/Driver/Ntvol.c index 317e3653..4f35323b 100644 --- a/src/Driver/Ntvol.c +++ b/src/Driver/Ntvol.c @@ -518,7 +518,7 @@ 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); + sha256 (Extension->volumeID, readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE); if (volumeType == TC_VOLUME_TYPE_NORMAL) { diff --git a/src/Mount/Favorites.cpp b/src/Mount/Favorites.cpp index 5dde8da0..58bfe263 100644 --- a/src/Mount/Favorites.cpp +++ b/src/Mount/Favorites.cpp @@ -98,7 +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); + memcpy (favorite.VolumeID, prop.volumeID, VOLUME_ID_SIZE); if (favorite.VolumePathId.empty() && IsVolumeDeviceHosted (favorite.Path.c_str()) @@ -421,7 +421,7 @@ namespace VeraCrypt { HDC hdc = (HDC) wParam; HWND hw = (HWND) lParam; - if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_ID)) + if (hw == GetDlgItem(hwndDlg, IDC_FAVORITE_VOLUME_ID)) { // This the favorite ID field. Make its background like normal edit HBRUSH hbr = GetSysColorBrush (COLOR_WINDOW); @@ -582,12 +582,12 @@ namespace VeraCrypt char label[1024]; XmlGetAttributeText (xml, "ID", label, sizeof (label)); - if (strlen (label) == 128) + if (strlen (label) == (2*VOLUME_ID_SIZE)) { std::vector arr; - if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == SHA512_DIGEST_SIZE) + if (HexWideStringToArray (Utf8StringToWide (label).c_str(), arr) && arr.size() == VOLUME_ID_SIZE) { - memcpy (favorite.VolumeID, &arr[0], SHA512_DIGEST_SIZE); + memcpy (favorite.VolumeID, &arr[0], VOLUME_ID_SIZE); } } @@ -639,7 +639,7 @@ namespace VeraCrypt XmlGetAttributeText (xml, "useVolumeID", boolVal, sizeof (boolVal)); if (boolVal[0]) - favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, SHA512_DIGEST_SIZE); + favorite.UseVolumeID = (boolVal[0] == '1') && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)); if (favorite.Path.find (L"\\\\?\\Volume{") == 0 && favorite.Path.rfind (L"}\\") == favorite.Path.size() - 2) { @@ -738,8 +738,8 @@ namespace VeraCrypt wstring s = L"\n\t\t" + wstring (tq) + L""; @@ -840,6 +840,7 @@ namespace VeraCrypt static void SetControls (HWND hwndDlg, const FavoriteVolume &favorite, bool systemFavoritesMode, bool enable) { + BOOL bIsDevice = IsVolumeDeviceHosted (favorite.Path.c_str()) || !enable; if (favorite.Pim > 0) { wchar_t szTmp[MAX_PIM + 1]; @@ -854,12 +855,14 @@ 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); + SetCheckBox (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID, favorite.UseVolumeID && bIsDevice); - if (!IsRepeatedByteArray (0, favorite.VolumeID, SHA512_DIGESTSIZE)) + if (IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID)) || !bIsDevice) { - SetDlgItemText (hwndDlg, IDC_FAVORITE_ID, ArrayToHexWideString (favorite.VolumeID, SHA512_DIGESTSIZE).c_str()); + SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, L""); } + else + SetDlgItemText (hwndDlg, IDC_FAVORITE_VOLUME_ID, ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)).c_str()); if (systemFavoritesMode) { @@ -893,6 +896,44 @@ namespace VeraCrypt EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_MOUNT_REMOVABLE), enable); EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_OPEN_EXPLORER_WIN_ON_MOUNT), enable || systemFavoritesMode); EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_DISABLE_HOTKEY), enable || systemFavoritesMode); + EnableWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), enable && bIsDevice); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), enable && bIsDevice); + EnableWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), enable && bIsDevice && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID))); + + ShowWindow (GetDlgItem (hwndDlg, IDT_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE); + ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE); + ShowWindow (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), bIsDevice? SW_SHOW : SW_HIDE); + + // Group box + RECT boxRect, checkRect, labelRect; + + GetWindowRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), &boxRect); + GetWindowRect (GetDlgItem (hwndDlg, IDC_FAVORITE_USE_VOLUME_ID), &checkRect); + GetWindowRect (GetDlgItem (hwndDlg, IDT_VOLUME_ID), &labelRect); + + if (!bIsDevice && (boxRect.top < checkRect.top)) + { + POINT pt = {boxRect.left, checkRect.bottom}; + ScreenToClient (hwndDlg, &pt); + SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y, + boxRect.right - boxRect.left, + boxRect.bottom - checkRect.bottom, + SWP_NOZORDER); + + InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE); + } + + if (bIsDevice && (boxRect.top >= checkRect.top)) + { + POINT pt = {boxRect.left, labelRect.top - CompensateYDPI (10)}; + ScreenToClient (hwndDlg, &pt); + SetWindowPos (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), 0, pt.x, pt.y, + boxRect.right - boxRect.left, + boxRect.bottom - labelRect.top + CompensateYDPI (10), + SWP_NOZORDER); + + InvalidateRect (GetDlgItem (hwndDlg, IDC_FAV_VOL_OPTIONS_GROUP_BOX), NULL, TRUE); + } } diff --git a/src/Mount/Favorites.h b/src/Mount/Favorites.h index 538ec1db..84ab2a25 100644 --- a/src/Mount/Favorites.h +++ b/src/Mount/Favorites.h @@ -33,7 +33,7 @@ namespace VeraCrypt UseLabelInExplorer (false), UseVolumeID (false) { - memset (VolumeID, 0, SHA512_DIGESTSIZE); + memset (VolumeID, 0, VOLUME_ID_SIZE); } wstring Path; @@ -41,7 +41,7 @@ namespace VeraCrypt wstring VolumePathId; wstring Label; int Pim; - BYTE VolumeID[SHA512_DIGESTSIZE]; + BYTE VolumeID[VOLUME_ID_SIZE]; bool DisableHotkeyMount; bool DisconnectedDevice; diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index dc7d825d..5b6f86f2 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -1900,6 +1900,7 @@ typedef struct { BOOL bRequireConfirmation; wchar_t *lpszVolume; + size_t cchVolume; int* iResult; } BackupHeaderThreadParam; @@ -1907,10 +1908,15 @@ void CALLBACK BackupHeaderWaitThreadProc(void* pArg, HWND hwndDlg) { BackupHeaderThreadParam* pThreadParam = (BackupHeaderThreadParam*) pArg; - if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) - *(pThreadParam->iResult) = UacBackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) + { + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) + *(pThreadParam->iResult) = UacBackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + else + *(pThreadParam->iResult) = BackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + } else - *(pThreadParam->iResult) = BackupVolumeHeader (hwndDlg, pThreadParam->bRequireConfirmation, pThreadParam->lpszVolume); + *(pThreadParam->iResult) = ERR_OS_ERROR; } // implementation for support of restoring header operation in wait dialog mechanism @@ -1918,6 +1924,7 @@ void CALLBACK BackupHeaderWaitThreadProc(void* pArg, HWND hwndDlg) typedef struct { wchar_t *lpszVolume; + size_t cchVolume; int* iResult; } RestoreHeaderThreadParam; @@ -1925,10 +1932,15 @@ void CALLBACK RestoreHeaderWaitThreadProc(void* pArg, HWND hwndDlg) { RestoreHeaderThreadParam* pThreadParam = (RestoreHeaderThreadParam*) pArg; - if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) - *(pThreadParam->iResult) = UacRestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + if (TranslateVolumeID (hwndDlg, pThreadParam->lpszVolume, pThreadParam->cchVolume)) + { + if (!IsAdmin () && IsUacSupported () && IsVolumeDeviceHosted (pThreadParam->lpszVolume)) + *(pThreadParam->iResult) = UacRestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + else + *(pThreadParam->iResult) = RestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + } else - *(pThreadParam->iResult) = RestoreVolumeHeader (hwndDlg, pThreadParam->lpszVolume); + *(pThreadParam->iResult) = ERR_OS_ERROR; } /* Except in response to the WM_INITDIALOG message, the dialog box procedure @@ -3584,6 +3596,60 @@ int GetModeOfOperationByDriveNo (int nDosDriveNo) return 0; } +void DisplayVolumePropertiesListContextMenu (HWND hwndDlg, LPARAM lParam) +{ + /* Volume Properties list context menu */ + DWORD mPos; + int menuItem; + HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); + int hItem = ListView_GetSelectionMark (hList); + + SetFocus (hList); + + if (hItem >= 0) + { + HMENU popup = CreatePopupMenu (); + AppendMenuW (popup, MF_STRING, IDPM_COPY_VALUE_TO_CLIPBOARD, GetString ("IDPM_COPY_VALUE_TO_CLIPBOARD")); + + if (lParam) + { + mPos=GetMessagePos(); + } + else + { + POINT pt = {0}; + if (ListView_GetItemPosition (hList, hItem, &pt)) + { + pt.x += 2 + ::GetSystemMetrics(SM_CXICON); + pt.y += 2; + } + ClientToScreen (hList, &pt); + mPos = MAKELONG (pt.x, pt.y); + } + + menuItem = TrackPopupMenu (popup, + TPM_RETURNCMD | TPM_LEFTBUTTON, + GET_X_LPARAM(mPos), + GET_Y_LPARAM(mPos), + 0, + hwndDlg, + NULL); + + DestroyMenu (popup); + + switch (menuItem) + { + case IDPM_COPY_VALUE_TO_CLIPBOARD: + { + wchar_t valueText[256] = {0}; + ListView_GetItemText (hList, hItem, 1, valueText, ARRAYSIZE (valueText)); + CopyTextToClipboard (valueText); + } + break; + } + } +} + BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { @@ -3701,6 +3767,16 @@ BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP else ListSubItemSet (list, i++, 1, (wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4)); + if (!bSysEnc && IsVolumeDeviceHosted ((wchar_t *) (prop.wszVolume[1] != L'?' ? prop.wszVolume : prop.wszVolume + 4))) + { + // Volume ID + std::wstring hexID = ArrayToHexWideString (prop.volumeID, sizeof (prop.volumeID)); + ListItemAdd (list, i, GetString ("VOLUME_ID")); + + ListSubItemSet (list, i++, 1, hexID.c_str()); + } + + // Size ListItemAdd (list, i, GetString ("SIZE")); StringCbPrintfW (sw, sizeof(sw), L"%I64u %s", prop.diskLength, GetString ("BYTES")); @@ -3901,6 +3977,44 @@ BOOL CALLBACK VolumePropertiesDlgProc (HWND hwndDlg, UINT msg, WPARAM wParam, LP return 0; } + case WM_NOTIFY: + + if(wParam == IDC_VOLUME_PROPERTIES_LIST) + { + /* Right click */ + + switch (((NM_LISTVIEW *) lParam)->hdr.code) + { + case NM_RCLICK: + case LVN_BEGINRDRAG: + /* If the mouse was moving while the right mouse button is pressed, popup menu would + not open, because drag&drop operation would be initiated. Therefore, we're handling + RMB drag-and-drop operations as well. */ + { + + DisplayVolumePropertiesListContextMenu (hwndDlg, lParam); + + return 1; + } + } + } + return 0; + + case WM_CONTEXTMENU: + { + HWND hList = GetDlgItem (hwndDlg, IDC_VOLUME_PROPERTIES_LIST); + // only handle if it is coming from keyboard and if the drive + // list has focus. The other cases are handled elsewhere + if ( (-1 == GET_X_LPARAM(lParam)) + && (-1 == GET_Y_LPARAM(lParam)) + && (GetFocus () == hList) + ) + { + DisplayVolumePropertiesListContextMenu (hwndDlg, NULL); + } + } + return 0; + case WM_COMMAND: if (lw == IDOK) { @@ -4442,15 +4556,24 @@ static BOOL Mount (HWND hwndDlg, int nDosDriveNo, wchar_t *szFileName, int pim) if (szFileName == NULL) { GetVolumePath (hwndDlg, fileName, ARRAYSIZE (fileName)); - szFileName = fileName; + } + else + StringCchCopyW (fileName, ARRAYSIZE (fileName), szFileName); + + if (wcslen(fileName) == 0) + { + status = FALSE; + goto ret; } - if (wcslen(szFileName) == 0) + if (!TranslateVolumeID (hwndDlg, fileName, ARRAYSIZE (fileName))) { status = FALSE; goto ret; } + szFileName = fileName; + if (IsMountedVolume (szFileName)) { Warning ("VOL_ALREADY_MOUNTED", hwndDlg); @@ -5129,6 +5252,12 @@ static void ChangePassword (HWND hwndDlg) int newPimValue = -1; GetVolumePath (hwndDlg, szFileName, ARRAYSIZE (szFileName)); + + if (!TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) + { + return; + } + if (IsMountedVolume (szFileName)) { Warning (pwdChangeDlgMode == PCDM_CHANGE_PKCS5_PRF ? "MOUNTED_NO_PKCS5_PRF_CHANGE" : "MOUNTED_NOPWCHANGE", hwndDlg); @@ -6309,7 +6438,11 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa exitCode = 1; } - if (szFileName[0] != 0 && !IsMountedVolume (szFileName)) + if (szFileName[0] != 0 && !TranslateVolumeID (hwndDlg, szFileName, ARRAYSIZE (szFileName))) + { + exitCode = 1; + } + else if (szFileName[0] != 0 && !IsMountedVolume (szFileName)) { BOOL mounted = FALSE; int EffectiveVolumePkcs5 = CmdVolumePkcs5; @@ -6759,7 +6892,21 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa foreach (FavoriteVolume favorite, FavoritesOnArrivalMountRequired) { - if (!favorite.VolumePathId.empty()) + if (favorite.UseVolumeID) + { + if (IsMountedVolumeID (favorite.VolumeID)) + continue; + + std::wstring volDevPath = FindDeviceByVolumeID (favorite.VolumeID); + if (volDevPath.length() > 0) + { + favorite.Path = volDevPath; + favorite.DisconnectedDevice = false; + } + else + continue; + } + else if (!favorite.VolumePathId.empty()) { if (IsMountedVolume (favorite.Path.c_str())) continue; @@ -6835,6 +6982,16 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa continue; } + // set DisconnectedDevice field on FavoritesOnArrivalMountRequired element + foreach (FavoriteVolume onArrivalFavorite, FavoritesOnArrivalMountRequired) + { + if (onArrivalFavorite.Path == favorite->Path) + { + onArrivalFavorite.DisconnectedDevice = true; + break; + } + } + favorite = FavoritesMountedOnArrivalStillConnected.erase (favorite); deleted = true; } @@ -7412,6 +7569,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa BackupHeaderThreadParam threadParam; threadParam.bRequireConfirmation = TRUE; threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); threadParam.iResult = &iStatus; ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); @@ -7434,6 +7592,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa int iStatus = 0; RestoreHeaderThreadParam threadParam; threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); threadParam.iResult = &iStatus; ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); @@ -7717,6 +7876,8 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (VolumeSelected (hwndDlg) && IsMountedVolume (volPathLower)) { + TranslateVolumeID (hwndDlg, volPathLower, ARRAYSIZE (volPathLower)); + if (LOWORD (selectedDrive) != TC_MLIST_ITEM_NONSYS_VOL) { driveNo = GetMountedVolumeDriveNo (volPathLower); @@ -7852,6 +8013,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa BackupHeaderThreadParam threadParam; threadParam.bRequireConfirmation = TRUE; threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); threadParam.iResult = &iStatus; ShowWaitDialog (hwndDlg, TRUE, BackupHeaderWaitThreadProc, &threadParam); @@ -7878,6 +8040,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa int iStatus = 0; RestoreHeaderThreadParam threadParam; threadParam.lpszVolume = volPath; + threadParam.cchVolume = ARRAYSIZE (volPath); threadParam.iResult = &iStatus; ShowWaitDialog(hwndDlg, TRUE, RestoreHeaderWaitThreadProc, &threadParam); @@ -8005,9 +8168,16 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa if (favoriteIndex < FavoriteVolumes.size()) { - if (IsMountedVolume (FavoriteVolumes[favoriteIndex].Path.c_str())) + if ((FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolumeID (FavoriteVolumes[favoriteIndex].VolumeID)) + || (!FavoriteVolumes[favoriteIndex].UseVolumeID && IsMountedVolume (FavoriteVolumes[favoriteIndex].Path.c_str())) + ) { + std::wstring volName; WaitCursor(); + if (FavoriteVolumes[favoriteIndex].UseVolumeID) + volName = FindDeviceByVolumeID (FavoriteVolumes[favoriteIndex].VolumeID); + else + volName = FavoriteVolumes[favoriteIndex].Path; OpenVolumeExplorerWindow (GetMountedVolumeDriveNo ((wchar_t*) FavoriteVolumes[favoriteIndex].Path.c_str())); NormalCursor(); } @@ -8648,6 +8818,7 @@ static BOOL StartSystemFavoritesService () ServiceMode = TRUE; Silent = TRUE; DeviceChangeBroadcastDisabled = TRUE; + bShowDisconnectedNetworkDrives = TRUE; InitOSVersionInfo(); @@ -8920,8 +9091,10 @@ 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); + if (favorite.UseVolumeID && !IsRepeatedByteArray (0, favorite.VolumeID, sizeof (favorite.VolumeID))) + { + effectiveVolumePath = FindDeviceByVolumeID (favorite.VolumeID); + } else effectiveVolumePath = favorite.Path; @@ -8982,7 +9155,7 @@ static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, BOOL prevReadOnly = mountOptions.ReadOnly; if (ServiceMode) - SystemFavoritesServiceLogInfo (wstring (L"Mounting system favorite \"") + favorite.Path + L"\""); + SystemFavoritesServiceLogInfo (wstring (L"Mounting system favorite \"") + effectiveVolumePath + L"\""); status = Mount (hwnd, drive, (wchar_t *) effectiveVolumePath.c_str(), favorite.Pim); @@ -8994,11 +9167,11 @@ static BOOL MountFavoriteVolumeBase (HWND hwnd, const FavoriteVolume &favorite, if (status) { - SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + favorite.Path + wstring (L"\" mounted successfully as ") + (wchar_t) (drive + L'A') + L":"); + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + effectiveVolumePath + wstring (L"\" mounted successfully as ") + (wchar_t) (drive + L'A') + L":"); } else { - SystemFavoritesServiceLogError (wstring (L"Favorite \"") + favorite.Path + L"\" failed to mount"); + SystemFavoritesServiceLogError (wstring (L"Favorite \"") + effectiveVolumePath + L"\" failed to mount"); } } @@ -9039,7 +9212,7 @@ skipMount: Error ("DRIVE_LETTER_UNAVAILABLE", MainDlg); else if (ServiceMode && systemFavorites) { - SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + favorite.Path + L"\" is already taken.\nThis system favorite will not be mounted"); + SystemFavoritesServiceLogError (wstring (L"The drive letter ") + (wchar_t) (drive + L'A') + wstring (L" used by favorite \"") + effectiveVolumePath + L"\" is already taken.\nThis system favorite will not be mounted"); } return status; @@ -9079,6 +9252,26 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO wchar_t szTmp[32]; StringCbPrintf (szTmp, sizeof(szTmp), L"%d", (int) favorites.size()); SystemFavoritesServiceLogInfo (wstring (L"Loaded ") + szTmp + wstring (L" favorites from the file")); + + /* correct set the connected state of the system favorites */ + for (vector ::iterator favorite = favorites.begin(); + favorite != favorites.end(); favorite++) + { + if (favorite->UseVolumeID) + { + std::wstring path = FindDeviceByVolumeID (favorite->VolumeID); + if (path.empty ()) + { + favorite->DisconnectedDevice = true; + } + else + { + favorite->DisconnectedDevice = false; + favorite->Path = path; + favorite->UseVolumeID = false; /* force the use of real path to avoid calling FindDeviceByVolumeID again */ + } + } + } } } catch (...) @@ -9098,7 +9291,10 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO if (ServiceMode && systemFavorites && favorite.DisconnectedDevice) { skippedSystemFavorites.push_back (favorite); - SystemFavoritesServiceLogWarning (wstring (L"Favorite \"") + favorite.Path + L"\" is disconnected. It will be ignored."); + if (favorite.UseVolumeID) + SystemFavoritesServiceLogWarning (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite.VolumeID, sizeof (favorite.VolumeID)) + L"\" is disconnected. It will be ignored."); + else + SystemFavoritesServiceLogWarning (wstring (L"Favorite \"") + favorite.Path + L"\" is disconnected. It will be ignored."); } if (favorite.DisconnectedDevice @@ -9135,7 +9331,13 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO if (favorite->DisconnectedDevice) { // check if the favorite is here and get its path - wstring resolvedPath = VolumeGuidPathToDevicePath (favorite->Path); + wstring resolvedPath; + if (favorite->UseVolumeID) + { + resolvedPath = FindDeviceByVolumeID (favorite->VolumeID); + } + else + resolvedPath = VolumeGuidPathToDevicePath (favorite->Path); if (!resolvedPath.empty()) { favorite->DisconnectedDevice = false; @@ -9145,7 +9347,10 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO remainingFavorites--; // favorite OK. - SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + favorite->VolumePathId + L"\" is connected. Performing mount."); + if (favorite->UseVolumeID) + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"ID:") + ArrayToHexWideString (favorite->VolumeID, sizeof (favorite->VolumeID)) + L"\" is connected. Performing mount."); + else + SystemFavoritesServiceLogInfo (wstring (L"Favorite \"") + favorite->VolumePathId + L"\" is connected. Performing mount."); status = MountFavoriteVolumeBase (hwnd, *favorite, lastbExplore, userForcedReadOnly, systemFavorites, logOnMount, hotKeyMount, favoriteVolumeToMount); if (!status) diff --git a/src/Mount/Resource.h b/src/Mount/Resource.h index 1cacfcd7..5b564a94 100644 --- a/src/Mount/Resource.h +++ b/src/Mount/Resource.h @@ -176,8 +176,8 @@ #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 IDT_VOLUME_ID 1157 +#define IDC_FAVORITE_VOLUME_ID 1158 #define IDC_FAVORITE_USE_VOLUME_ID 1159 #define IDM_HELP 40001 #define IDM_ABOUT 40002 -- cgit v1.2.3