mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-01-04 04:38:12 -06:00
Windows: start implementation of volume ID mechanism that will be used to identify VeraCrypt disk volumes instead of device name.
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
|
||||
@@ -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<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];
|
||||
@@ -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<byte> 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<byte> 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 <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;
|
||||
@@ -10980,7 +11097,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;
|
||||
@@ -11020,6 +11137,30 @@ std::vector <HostDevice> 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<byte> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<byte>& 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)
|
||||
|
||||
@@ -1388,6 +1388,9 @@
|
||||
<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_FAVORITE_ID">Volume ID:</control>
|
||||
<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>
|
||||
</localization>
|
||||
<!-- XML Schema -->
|
||||
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
Reference in New Issue
Block a user