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 +- 5 files changed, 125 insertions(+), 41 deletions(-) (limited to 'src/Common') 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... -- cgit v1.2.3