VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Common/Apidrvr.h6
-rw-r--r--src/Common/BootEncryption.cpp2
-rw-r--r--src/Common/Dlgcode.c464
-rw-r--r--src/Common/Dlgcode.h32
-rw-r--r--src/Driver/Ntdriver.c53
-rw-r--r--src/Mount/Mount.c330
6 files changed, 670 insertions, 217 deletions
diff --git a/src/Common/Apidrvr.h b/src/Common/Apidrvr.h
index adffacc2..06f32b83 100644
--- a/src/Common/Apidrvr.h
+++ b/src/Common/Apidrvr.h
@@ -266,9 +266,9 @@ typedef struct
BOOL TCBootLoaderDetected;
BOOL DetectFilesystem;
BOOL FilesystemDetected;
- BOOL bMatchVolumeID;
- unsigned char volumeID[VOLUME_ID_SIZE];
- BOOL VolumeIDMatched;
+ BOOL bComputeVolumeIDs;
+ unsigned char volumeIDs[TC_VOLUME_TYPE_COUNT][VOLUME_ID_SIZE];
+ BOOL VolumeIDComputed[TC_VOLUME_TYPE_COUNT];
} OPEN_TEST_STRUCT;
diff --git a/src/Common/BootEncryption.cpp b/src/Common/BootEncryption.cpp
index 0b684e49..f7cfc6e1 100644
--- a/src/Common/BootEncryption.cpp
+++ b/src/Common/BootEncryption.cpp
@@ -1090,6 +1090,7 @@ namespace VeraCrypt
memcpy (fingerprint, request.Fingerprint, sizeof (request.Fingerprint));
}
+#ifndef SETUP
// Note that this does not require admin rights (it just requires the driver to be running)
bool BootEncryption::IsBootLoaderOnDrive (wchar_t *devicePath)
{
@@ -1114,6 +1115,7 @@ namespace VeraCrypt
}
}
+#endif
BootEncryptionStatus BootEncryption::GetStatus ()
{
diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c
index 62b0a4e5..e6a609b3 100644
--- a/src/Common/Dlgcode.c
+++ b/src/Common/Dlgcode.c
@@ -74,8 +74,22 @@
#include "Setup/Setup.h"
#endif
+#include <Setupapi.h>
#include <strsafe.h>
+#pragma comment( lib, "setupapi.lib" )
+
+/* GPT Partition Type GUIDs */
+#define LOCAL_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) const GUID name = {l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8}
+LOCAL_DEFINE_GUID(PARTITION_ENTRY_UNUSED_GUID, 0x00000000L, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); // Entry unused
+LOCAL_DEFINE_GUID(PARTITION_SYSTEM_GUID, 0xC12A7328L, 0xF81F, 0x11D2, 0xBA, 0x4B, 0x00, 0xA0, 0xC9, 0x3E, 0xC9, 0x3B); // EFI system partition
+LOCAL_DEFINE_GUID(PARTITION_MSFT_RESERVED_GUID, 0xE3C9E316L, 0x0B5C, 0x4DB8, 0x81, 0x7D, 0xF9, 0x2D, 0xF0, 0x02, 0x15, 0xAE); // Microsoft reserved space
+LOCAL_DEFINE_GUID(PARTITION_BASIC_DATA_GUID, 0xEBD0A0A2L, 0xB9E5, 0x4433, 0x87, 0xC0, 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7); // Basic data partition
+LOCAL_DEFINE_GUID(PARTITION_LDM_METADATA_GUID, 0x5808C8AAL, 0x7E8F, 0x42E0, 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3); // Logical Disk Manager metadata partition
+LOCAL_DEFINE_GUID(PARTITION_LDM_DATA_GUID, 0xAF9B60A0L, 0x1431, 0x4F62, 0xBC, 0x68, 0x33, 0x11, 0x71, 0x4A, 0x69, 0xAD); // Logical Disk Manager data partition
+LOCAL_DEFINE_GUID(PARTITION_MSFT_RECOVERY_GUID, 0xDE94BBA4L, 0x06D1, 0x4D40, 0xA1, 0x6A, 0xBF, 0xD5, 0x01, 0x79, 0xD6, 0xAC); // Microsoft recovery partition
+LOCAL_DEFINE_GUID(PARTITION_CLUSTER_GUID, 0xdb97dba9L, 0x0840, 0x4bae, 0x97, 0xf0, 0xff, 0xb9, 0xa3, 0x27, 0xc7, 0xe1); // Cluster metadata partition
+
using namespace VeraCrypt;
LONG DriverVersion;
@@ -174,6 +188,13 @@ volatile HANDLE hAppSetupMutex = NULL;
/* Critical section used to protect access to global variables used in WNetGetConnection calls */
CRITICAL_SECTION csWNetCalls;
+/* Critical section used to protect access to global list of physical drives */
+CRITICAL_SECTION csMountableDevices;
+CRITICAL_SECTION csVolumeIdCandidates;
+
+static std::vector<HostDevice> mountableDevices;
+static std::vector<HostDevice> rawHostDeviceList;
+
HINSTANCE hInst = NULL;
HCURSOR hCursor = NULL;
@@ -448,6 +469,8 @@ void cleanup ()
#endif
DeleteCriticalSection (&csWNetCalls);
+ DeleteCriticalSection (&csMountableDevices);
+ DeleteCriticalSection (&csVolumeIdCandidates);
}
@@ -2658,6 +2681,8 @@ void InitApp (HINSTANCE hInstance, wchar_t *lpszCommandLine)
VirtualLock (&CmdTokenPin, sizeof (CmdTokenPin));
InitializeCriticalSection (&csWNetCalls);
+ InitializeCriticalSection (&csMountableDevices);
+ InitializeCriticalSection (&csVolumeIdCandidates);
LoadSystemDll (L"ntmarta.dll", &hntmartadll, TRUE, SRC_POS);
LoadSystemDll (L"MPR.DLL", &hmprdll, TRUE, SRC_POS);
@@ -3049,7 +3074,8 @@ void InitHelpFileName (void)
}
}
-BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL matchVolumeID, const BYTE* pbVolumeID)
+#ifndef SETUP
+BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL computeVolumeIDs)
{
DWORD dwResult;
BOOL bResult;
@@ -3062,9 +3088,7 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF
driver->bDetectTCBootLoader = FALSE;
driver->DetectFilesystem = detectFilesystem;
- driver->bMatchVolumeID = matchVolumeID;
- if (matchVolumeID && pbVolumeID)
- memcpy (driver->volumeID, pbVolumeID, VOLUME_ID_SIZE);
+ driver->bComputeVolumeIDs = computeVolumeIDs;
bResult = DeviceIoControl (hDriver, TC_IOCTL_OPEN_TEST,
driver, sizeof (OPEN_TEST_STRUCT),
@@ -3092,7 +3116,7 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF
{
driver->TCBootLoaderDetected = FALSE;
driver->FilesystemDetected = FALSE;
- driver->VolumeIDMatched = FALSE;
+ memset (driver->VolumeIDComputed, 0, sizeof (driver->VolumeIDComputed));
return TRUE;
}
else
@@ -3102,6 +3126,7 @@ BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectF
return TRUE;
}
+#endif
// Tells the driver that it's running in portable mode
void NotifyDriverOfPortableMode (void)
@@ -7510,6 +7535,7 @@ void ShowWaitDialog(HWND hwnd, BOOL bUseHwndAsParent, WaitThreadProc callback, v
}
}
+#ifndef SETUP
/************************************************************************/
static BOOL PerformMountIoctl (MOUNT_STRUCT* pmount, LPDWORD pdwResult, BOOL useVolumeID, BYTE volumeID[VOLUME_ID_SIZE])
@@ -7989,6 +8015,8 @@ retry:
return 1;
}
+#endif
+
typedef struct
{
int nDosDriveNo;
@@ -8087,8 +8115,6 @@ BOOL UnmountVolumeAfterFormatExCall (HWND hwndDlg, int nDosDriveNo)
return UnmountVolumeBase (hwndDlg, nDosDriveNo, FALSE, TRUE);
}
-#endif //!SETUP
-
BOOL IsPasswordCacheEmpty (void)
{
DWORD dw;
@@ -8106,9 +8132,14 @@ BOOL IsMountedVolumeID (BYTE volumeID[VOLUME_ID_SIZE])
sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
NULL);
- for (i=0 ; i<26; i++)
- if (0 == memcmp (mlist.volumeID[i], volumeID, VOLUME_ID_SIZE))
- return TRUE;
+ if (mlist.ulMountedDrives)
+ {
+ for (i=0 ; i<26; i++)
+ {
+ if ((mlist.ulMountedDrives & (1 << i)) && (0 == memcmp (mlist.volumeID[i], volumeID, VOLUME_ID_SIZE)))
+ return TRUE;
+ }
+ }
return FALSE;
}
@@ -8145,9 +8176,14 @@ BOOL IsMountedVolume (const wchar_t *volname)
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 (mlist.ulMountedDrives)
+ {
+ for (i=0 ; i<26; i++)
+ {
+ if ((mlist.ulMountedDrives & (1 << i)) && (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], volume)))
+ return TRUE;
+ }
+ }
}
return FALSE;
@@ -8178,13 +8214,19 @@ int GetMountedVolumeDriveNo (wchar_t *volname)
sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
NULL);
- for (i=0 ; i<26; i++)
- if (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume))
- return i;
+ if (mlist.ulMountedDrives)
+ {
+ for (i=0 ; i<26; i++)
+ {
+ if ((mlist.ulMountedDrives & (1 << i)) && (0 == _wcsicmp ((wchar_t *) mlist.wszVolume[i], (WCHAR *)volume)))
+ return i;
+ }
+ }
return -1;
}
+#endif //!SETUP
BOOL IsAdmin (void)
{
@@ -11523,7 +11565,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, FALSE, NULL))
+ if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems && partNumber != 0, FALSE))
{
if (partNumber == 0)
break;
@@ -11627,7 +11669,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, FALSE, NULL))
+ if (!OpenDevice (devPath, &openTest, detectUnencryptedFilesystems, FALSE))
continue;
DISK_PARTITION_INFO_STRUCT info;
@@ -11667,8 +11709,305 @@ std::vector <HostDevice> GetAvailableHostDevices (bool noDeviceProperties, bool
return devices;
}
+void AddDeviceToList (std::vector<HostDevice>& devices, int devNumber, int partNumber)
+{
+ wstringstream strm;
+ strm << L"\\Device\\Harddisk" << devNumber << L"\\Partition" << partNumber;
+ wstring devPathStr (strm.str());
+ const wchar_t *devPath = devPathStr.c_str();
+
+ HostDevice device;
+ device.SystemNumber = devNumber;
+ device.Path = devPath;
+
+ devices.push_back (device);
+}
+
+std::vector <HostDevice> GetHostRawDeviceList ()
+{
+ std::vector <HostDevice> list;
+ HDEVINFO diskClassDevices;
+ GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK;
+ SP_DEVICE_INTERFACE_DATA deviceInterfaceData;
+ PSP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData;
+ DWORD requiredSize;
+ DWORD deviceIndex;
+
+ STORAGE_DEVICE_NUMBER diskNumber;
+ DWORD bytesReturned;
+
+ diskClassDevices = SetupDiGetClassDevs( &diskClassDeviceInterfaceGuid,
+ NULL,
+ NULL,
+ DIGCF_PRESENT |
+ DIGCF_DEVICEINTERFACE );
+ if ( INVALID_HANDLE_VALUE != diskClassDevices)
+ {
+ ZeroMemory( &deviceInterfaceData, sizeof( SP_DEVICE_INTERFACE_DATA ) );
+ deviceInterfaceData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
+ deviceIndex = 0;
+
+ while ( SetupDiEnumDeviceInterfaces( diskClassDevices,
+ NULL,
+ &diskClassDeviceInterfaceGuid,
+ deviceIndex,
+ &deviceInterfaceData ) )
+ {
+ ++deviceIndex;
+
+ if (!SetupDiGetDeviceInterfaceDetail( diskClassDevices,
+ &deviceInterfaceData,
+ NULL,
+ 0,
+ &requiredSize,
+ NULL ) && ( ERROR_INSUFFICIENT_BUFFER == GetLastError()))
+ {
+ deviceInterfaceDetailData = ( PSP_DEVICE_INTERFACE_DETAIL_DATA ) malloc( requiredSize );
+ ZeroMemory( deviceInterfaceDetailData, requiredSize );
+ deviceInterfaceDetailData->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );
+ if (SetupDiGetDeviceInterfaceDetail( diskClassDevices,
+ &deviceInterfaceData,
+ deviceInterfaceDetailData,
+ requiredSize,
+ NULL,
+ NULL ))
+ {
+ HANDLE disk = CreateFile( deviceInterfaceDetailData->DevicePath,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+ if ( INVALID_HANDLE_VALUE != disk)
+ {
+ if (DeviceIoControl( disk,
+ IOCTL_STORAGE_GET_DEVICE_NUMBER,
+ NULL,
+ 0,
+ &diskNumber,
+ sizeof( STORAGE_DEVICE_NUMBER ),
+ &bytesReturned,
+ NULL ))
+ {
+ HostDevice device;
+ device.Path = deviceInterfaceDetailData->DevicePath;
+ device.SystemNumber = diskNumber.DeviceNumber;
+ list.push_back (device);
+ }
+
+ CloseHandle( disk );
+ }
+ }
+
+ free (deviceInterfaceDetailData);
+ }
+ }
+
+ SetupDiDestroyDeviceInfoList( diskClassDevices );
+ }
+
+ return list;
+}
+
+bool CompareDeviceList (const std::vector<HostDevice>& list1, const std::vector<HostDevice>& list2)
+{
+ if (list1.size() != list2.size())
+ return false;
+
+ for (std::vector<HostDevice>::const_iterator It1 = list1.begin(); It1 != list1.end(); It1++)
+ {
+ bool bFound = false;
+ for (std::vector<HostDevice>::const_iterator It2 = list2.begin(); It2 != list2.end(); It2++)
+ {
+ if (It1->Path == It2->Path && It1->SystemNumber == It2->SystemNumber)
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (!bFound)
+ return false;
+ }
+
+ return true;
+}
+
+void UpdateMountableHostDeviceList ()
+{
+ ByteArray buffer(4096);
+ DWORD bytesReturned;
+ bool dynamicVolumesPresent = false;
+
+ EnterCriticalSection (&csMountableDevices);
+ finally_do ({ LeaveCriticalSection (&csMountableDevices); });
+
+ std::vector<HostDevice> newList = GetHostRawDeviceList ();
+ std::map<DWORD, bool> existingDevicesMap;
+
+ if (CompareDeviceList (newList, rawHostDeviceList))
+ return; //no change, return
+
+ // remove raw devices that don't exist anymore
+ for (std::vector<HostDevice>::iterator It = rawHostDeviceList.begin();
+ It != rawHostDeviceList.end();)
+ {
+ for (std::vector<HostDevice>::iterator newIt = newList.begin(); newIt != newList.end(); newIt++)
+ {
+ if (newIt->SystemNumber == It->SystemNumber)
+ {
+ existingDevicesMap[It->SystemNumber] = true;
+ break;
+ }
+ }
+
+ if (existingDevicesMap[It->SystemNumber])
+ It++;
+ else
+ {
+ It = rawHostDeviceList.erase (It);
+ }
+ }
+
+ // remove mountable devices that don't exist anymore
+ for (std::vector<HostDevice>::iterator It = mountableDevices.begin();
+ It != mountableDevices.end();)
+ {
+ if (existingDevicesMap[It->SystemNumber])
+ It++;
+ else
+ It = mountableDevices.erase (It);
+ }
+
+ // add new devices
+ for (std::vector<HostDevice>::iterator It = newList.begin(); It != newList.end(); It++)
+ {
+ if (existingDevicesMap[It->SystemNumber])
+ continue;
+
+ HANDLE disk = CreateFile( It->Path.c_str(),
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+ if ( INVALID_HANDLE_VALUE != disk)
+ {
+ bool bIsDynamic = false;
+ bool bHasPartition = false;
+ if (DeviceIoControl(
+ disk,
+ IOCTL_DISK_GET_DRIVE_LAYOUT_EX,
+ NULL,
+ 0,
+ (LPVOID) buffer.data(),
+ (DWORD) buffer.size(),
+ (LPDWORD) &bytesReturned,
+ NULL))
+ {
+ PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data();
+ for (DWORD i = 0; i < layout->PartitionCount; i++)
+ {
+ if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_MBR)
+ {
+ if (layout->PartitionEntry[i].Mbr.PartitionType == 0)
+ continue;
+
+ bHasPartition = true;
+
+ /* skip dynamic volume */
+ if (layout->PartitionEntry[i].Mbr.PartitionType == PARTITION_LDM)
+ {
+ bIsDynamic = true;
+ /* remove any partition that may have been added */
+ while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
+ mountableDevices.pop_back ();
+ break;
+ }
+ }
+
+ if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_GPT)
+ {
+ if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID))
+ continue;
+
+ bHasPartition = true;
+
+ /* skip dynamic volume */
+ if ( IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_METADATA_GUID)
+ || IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_LDM_DATA_GUID)
+ )
+ {
+ bIsDynamic = true;
+ /* remove any partition that may have been added */
+ while (!mountableDevices.empty() && (mountableDevices.back().SystemNumber == It->SystemNumber))
+ mountableDevices.pop_back ();
+ break;
+ }
+ }
+
+ WCHAR path[MAX_PATH];
+ StringCbPrintfW (path, sizeof(path), L"\\\\?\\GLOBALROOT\\Device\\Harddisk%d\\Partition%d", It->SystemNumber, layout->PartitionEntry[i].PartitionNumber);
+ HANDLE handle = CreateFile( path,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL );
+ if (handle != INVALID_HANDLE_VALUE)
+ {
+ AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber);
+ CloseHandle (handle);
+ }
+ }
+ }
+
+ if (bIsDynamic)
+ dynamicVolumesPresent = true;
+
+ if (!bHasPartition)
+ AddDeviceToList (mountableDevices, It->SystemNumber, 0);
+
+ CloseHandle (disk);
+ }
+ }
+
+ rawHostDeviceList = newList;
+
+ // Starting from Vista, Windows does not create partition links for dynamic volumes so it is necessary to scan \\Device\\HarddiskVolumeX devices
+ if (dynamicVolumesPresent && (CurrentOSMajor >= 6))
+ {
+ for (int devNumber = 0; devNumber < 256; devNumber++)
+ {
+ wstringstream strm;
+ strm << L"\\Device\\HarddiskVolume" << devNumber;
+ wstring devPathStr (strm.str());
+ const wchar_t *devPath = devPathStr.c_str();
+
+ OPEN_TEST_STRUCT openTest = {0};
+ if (!OpenDevice (devPath, &openTest, FALSE, FALSE))
+ continue;
+
+ DISK_PARTITION_INFO_STRUCT info;
+ if (GetDeviceInfo (devPath, &info) && info.IsDynamic)
+ {
+ HostDevice device;
+ device.SystemNumber = devNumber;
+ device.Path = devPath;
+
+ mountableDevices.push_back (device);
+ }
+ }
+ }
+}
+
wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE])
{
+ static std::vector<HostDevice> volumeIdCandidates;
+
/* if it is already mounted, get the real path name used for mounting */
MOUNT_LIST_STRUCT mlist;
DWORD dwResult;
@@ -11678,30 +12017,88 @@ wstring FindDeviceByVolumeID (const BYTE volumeID [VOLUME_ID_SIZE])
sizeof (mlist), &mlist, sizeof (mlist), &dwResult,
NULL);
- for (int i=0 ; i < 26; i++)
+ if (mlist.ulMountedDrives)
{
- if (0 == memcmp (mlist.volumeID[i], volumeID, VOLUME_ID_SIZE))
- return mlist.wszVolume[i];
+ for (int i=0 ; i < 26; i++)
+ {
+ if ((mlist.ulMountedDrives & (1 << i)) && (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++)
+
+ EnterCriticalSection (&csMountableDevices);
+ std::vector<HostDevice> newDevices = mountableDevices;
+ LeaveCriticalSection (&csMountableDevices);
+
+ EnterCriticalSection (&csVolumeIdCandidates);
+ finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); });
+
+ /* remove any devices that don't exist anymore */
+ for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
+ It != volumeIdCandidates.end();)
{
- for (int partNumber = 0; partNumber < MAX_HOST_PARTITION_NUMBER; partNumber++)
+ bool bFound = false;
+ for (std::vector<HostDevice>::iterator newIt = newDevices.begin();
+ newIt != newDevices.end(); newIt++)
{
- wstringstream strm;
- strm << L"\\Device\\Harddisk" << devNumber << L"\\Partition" << partNumber;
- wstring devPathStr (strm.str());
- const wchar_t *devPath = devPathStr.c_str();
+ if (It->Path == newIt->Path)
+ {
+ bFound = true;
+ break;
+ }
+ }
+
+ if (bFound)
+ It++;
+ else
+ It = volumeIdCandidates.erase (It);
+ }
+
+ /* Add newly inserted devices and compute their VolumeID */
+ for (std::vector<HostDevice>::iterator newIt = newDevices.begin();
+ newIt != newDevices.end(); newIt++)
+ {
+ bool bFound = false;
+
+ for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
+ It != volumeIdCandidates.end(); It++)
+ {
+ if (It->Path == newIt->Path)
+ {
+ bFound = true;
+ break;
+ }
+ }
+ if (!bFound)
+ {
+ /* new device/partition. Compute its Volume IDs */
OPEN_TEST_STRUCT openTest = {0};
- if (!OpenDevice (devPath, &openTest, FALSE, TRUE, volumeID))
+ if (OpenDevice (newIt->Path.c_str(), &openTest, TRUE, TRUE)
+ && (openTest.VolumeIDComputed[TC_VOLUME_TYPE_NORMAL] && openTest.VolumeIDComputed[TC_VOLUME_TYPE_HIDDEN])
+ )
{
- continue;
+ memcpy (newIt->VolumeIDs, openTest.volumeIDs, sizeof (newIt->VolumeIDs));
+ newIt->HasVolumeIDs = true;
}
+ else
+ newIt->HasVolumeIDs = false;
+ volumeIdCandidates.push_back (*newIt);
+ }
+ }
- if (openTest.VolumeIDMatched)
- return devPath;
+ for (std::vector<HostDevice>::iterator It = volumeIdCandidates.begin();
+ It != volumeIdCandidates.end(); It++)
+ {
+ if ( It->HasVolumeIDs &&
+ ( (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_NORMAL], VOLUME_ID_SIZE))
+ || (0 == memcmp (volumeID, It->VolumeIDs[TC_VOLUME_TYPE_HIDDEN], VOLUME_ID_SIZE))
+ )
+ )
+ {
+ return It->Path;
}
}
@@ -11922,7 +12319,7 @@ BOOL DisableFileCompression (HANDLE file)
return DeviceIoControl (file, FSCTL_SET_COMPRESSION, &format, sizeof (format), NULL, 0, &bytesOut, NULL);
}
-
+#ifndef SETUP
BOOL VolumePathExists (const wchar_t *volumePath)
{
OPEN_TEST_STRUCT openTest = {0};
@@ -11931,7 +12328,7 @@ BOOL VolumePathExists (const wchar_t *volumePath)
UpperCaseCopy (upperCasePath, sizeof(upperCasePath), volumePath);
if (wcsstr (upperCasePath, L"\\DEVICE\\") == upperCasePath)
- return OpenDevice (volumePath, &openTest, FALSE, FALSE, NULL);
+ return OpenDevice (volumePath, &openTest, FALSE, FALSE);
wstring path = volumePath;
if (path.find (L"\\\\?\\Volume{") == 0 && path.rfind (L"}\\") == path.size() - 2)
@@ -12039,6 +12436,7 @@ std::wstring HarddiskVolumePathToPartitionPath (const std::wstring &harddiskVolu
return wstring();
}
+#endif
BOOL IsApplicationInstalled (const wchar_t *appName, BOOL b32bitApp)
{
diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h
index be04bd39..110c8def 100644
--- a/src/Common/Dlgcode.h
+++ b/src/Common/Dlgcode.h
@@ -306,7 +306,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, const BYTE* pbVolumeID);
+BOOL OpenDevice (const wchar_t *lpszPath, OPEN_TEST_STRUCT *driver, BOOL detectFilesystem, BOOL computeVolumeID);
void NotifyDriverOfPortableMode (void);
int GetAvailableFixedDisks ( HWND hComboBox , char *lpszRootPath );
int GetAvailableRemovables ( HWND hComboBox , char *lpszRootPath );
@@ -543,11 +543,34 @@ struct HostDevice
HasUnencryptedFilesystem (false),
Removable (false),
Size (0),
- SystemNumber((uint32) -1)
+ SystemNumber((uint32) -1),
+ HasVolumeIDs (false)
{
+ ZeroMemory (VolumeIDs, sizeof (VolumeIDs));
}
- ~HostDevice () { }
+ HostDevice (const HostDevice& device)
+ :
+ Bootable (device.Bootable),
+ ContainsSystem (device.ContainsSystem),
+ DynamicVolume (device.DynamicVolume),
+ Floppy (device.Floppy),
+ IsPartition (device.IsPartition),
+ IsVirtualPartition (device.IsVirtualPartition),
+ HasUnencryptedFilesystem (device.HasUnencryptedFilesystem),
+ MountPoint (device.MountPoint),
+ Name (device.Name),
+ Path (device.Path),
+ Removable (device.Removable),
+ Size (device.Size),
+ SystemNumber (device.SystemNumber),
+ HasVolumeIDs (device.HasVolumeIDs),
+ Partitions (device.Partitions)
+ {
+ memcpy (VolumeIDs, device.VolumeIDs, sizeof (VolumeIDs));
+ }
+
+ ~HostDevice () {}
bool Bootable;
bool ContainsSystem;
@@ -562,6 +585,8 @@ struct HostDevice
bool Removable;
uint64 Size;
uint32 SystemNumber;
+ BYTE VolumeIDs[TC_VOLUME_TYPE_COUNT][VOLUME_ID_SIZE];
+ bool HasVolumeIDs;
std::vector <HostDevice> Partitions;
};
@@ -597,6 +622,7 @@ inline std::wstring AppendSrcPos (const wchar_t* msg, const char* srcPos)
{
return std::wstring (msg? msg : L"") + L"\n\nSource: " + SingleStringToWide (srcPos);
}
+void UpdateMountableHostDeviceList ();
// Display a wait dialog while calling the provided callback with the given parameter
typedef void (CALLBACK* WaitThreadProc)(void* pArg, HWND hWaitDlg);
diff --git a/src/Driver/Ntdriver.c b/src/Driver/Ntdriver.c
index 3505826b..a84ada37 100644
--- a/src/Driver/Ntdriver.c
+++ b/src/Driver/Ntdriver.c
@@ -203,6 +203,16 @@ void DumpMemory (void *mem, int size)
}
}
+BOOL IsAllZeroes (unsigned char* pbData, DWORD dwDataLen)
+{
+ while (dwDataLen--)
+ {
+ if (*pbData)
+ return FALSE;
+ pbData++;
+ }
+ return TRUE;
+}
BOOL ValidateIOBufferSize (PIRP irp, size_t requiredBufferSize, ValidateIOBufferSizeType type)
{
@@ -1293,7 +1303,7 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
InitializeObjectAttributes (&ObjectAttributes, &FullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
- if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID)
+ if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bComputeVolumeIDs)
access |= FILE_READ_DATA;
ntStatus = ZwCreateFile (&NtFileHandle,
@@ -1304,9 +1314,10 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
{
opentest->TCBootLoaderDetected = FALSE;
opentest->FilesystemDetected = FALSE;
- opentest->VolumeIDMatched = FALSE;
+ memset (opentest->VolumeIDComputed, 0, sizeof (opentest->VolumeIDComputed));
+ memset (opentest->volumeIDs, 0, sizeof (opentest->volumeIDs));
- if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bMatchVolumeID)
+ if (opentest->bDetectTCBootLoader || opentest->DetectFilesystem || opentest->bComputeVolumeIDs)
{
byte *readBuffer = TCalloc (TC_MAX_VOLUME_SECTOR_SIZE);
if (!readBuffer)
@@ -1352,27 +1363,30 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
{
switch (BE64 (*(uint64 *) readBuffer))
{
- case 0xEB52904E54465320: // NTFS
- case 0xEB3C904D53444F53: // FAT16/FAT32
- case 0xEB58904D53444F53: // FAT32
- case 0xEB76904558464154: // exFAT
- case 0x0000005265465300: // ReFS
- case 0xEB58906D6B66732E: // FAT32 mkfs.fat
- case 0xEB58906D6B646F73: // FAT32 mkfs.vfat/mkdosfs
- case 0xEB3C906D6B66732E: // FAT16/FAT12 mkfs.fat
- case 0xEB3C906D6B646F73: // FAT16/FAT12 mkfs.vfat/mkdosfs
+ case 0xEB52904E54465320ULL: // NTFS
+ case 0xEB3C904D53444F53ULL: // FAT16/FAT32
+ case 0xEB58904D53444F53ULL: // FAT32
+ case 0xEB76904558464154ULL: // exFAT
+ case 0x0000005265465300ULL: // ReFS
+ case 0xEB58906D6B66732EULL: // FAT32 mkfs.fat
+ case 0xEB58906D6B646F73ULL: // FAT32 mkfs.vfat/mkdosfs
+ case 0xEB3C906D6B66732EULL: // FAT16/FAT12 mkfs.fat
+ case 0xEB3C906D6B646F73ULL: // FAT16/FAT12 mkfs.vfat/mkdosfs
opentest->FilesystemDetected = TRUE;
break;
+ case 0x0000000000000000ULL:
+ // all 512 bytes are zeroes => unencrypted filesystem like Microsoft reserved partition
+ if (IsAllZeroes (readBuffer + 8, TC_VOLUME_HEADER_EFFECTIVE_SIZE - 8))
+ opentest->FilesystemDetected = TRUE;
+ break;
}
}
}
}
- if (opentest->bMatchVolumeID)
+ if (opentest->bComputeVolumeIDs && (!opentest->DetectFilesystem || !opentest->FilesystemDetected))
{
int volumeType;
- BYTE volumeID[VOLUME_ID_SIZE];
-
// Go through all volume types (e.g., normal, hidden)
for (volumeType = TC_VOLUME_TYPE_NORMAL;
volumeType < TC_VOLUME_TYPE_COUNT;
@@ -1404,13 +1418,8 @@ NTSTATUS ProcessMainDeviceControlIrp (PDEVICE_OBJECT DeviceObject, PEXTENSION Ex
if (NT_SUCCESS (ntStatus))
{
/* 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, VOLUME_ID_SIZE))
- {
- opentest->VolumeIDMatched = TRUE;
- break;
- }
+ sha256 (opentest->volumeIDs[volumeType], readBuffer, TC_VOLUME_HEADER_EFFECTIVE_SIZE);
+ opentest->VolumeIDComputed[volumeType] = TRUE;
}
}
}
diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c
index c4052f7b..f55b7589 100644
--- a/src/Mount/Mount.c
+++ b/src/Mount/Mount.c
@@ -61,7 +61,8 @@ using namespace VeraCrypt;
enum timer_ids
{
TIMER_ID_MAIN = 0xff,
- TIMER_ID_KEYB_LAYOUT_GUARD
+ TIMER_ID_KEYB_LAYOUT_GUARD,
+ TIMER_ID_UPDATE_DEVICE_LIST
};
enum hidden_os_read_only_notif_mode
@@ -73,6 +74,7 @@ enum hidden_os_read_only_notif_mode
#define TIMER_INTERVAL_MAIN 500
#define TIMER_INTERVAL_KEYB_LAYOUT_GUARD 10
+#define TIMER_INTERVAL_UPDATE_DEVICE_LIST 1000
BootEncryption *BootEncObj = NULL;
BootEncryptionStatus BootEncStatus;
@@ -290,6 +292,7 @@ void EndMainDlg (HWND hwndDlg)
else
{
KillTimer (hwndDlg, TIMER_ID_MAIN);
+ KillTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST);
TaskBarIconRemove (hwndDlg);
UnregisterWtsNotification(hwndDlg);
EndDialog (hwndDlg, 0);
@@ -1482,6 +1485,7 @@ void LoadDriveLetters (HWND hwndDlg, HWND hTree, int drive)
if (bResult == FALSE)
{
KillTimer (MainDlg, TIMER_ID_MAIN);
+ KillTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST);
handleWin32Error (hTree, SRC_POS);
AbortProcessSilent();
}
@@ -4978,11 +4982,14 @@ retry:
DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, &mountList, sizeof (mountList), &mountList, sizeof (mountList), &dwResult, NULL);
// remove any custom label from registry
- for (i = 0; i < 26; i++)
+ if (prevMountList.ulMountedDrives)
{
- if ((prevMountList.ulMountedDrives & (1 << i)) && (!(mountList.ulMountedDrives & (1 << i))) && wcslen (prevMountList.wszLabel[i]))
+ for (i = 0; i < 26; i++)
{
- UpdateDriveCustomLabel (i, prevMountList.wszLabel[i], FALSE);
+ if ((prevMountList.ulMountedDrives & (1 << i)) && (!(mountList.ulMountedDrives & (1 << i))) && wcslen (prevMountList.wszLabel[i]))
+ {
+ UpdateDriveCustomLabel (i, prevMountList.wszLabel[i], FALSE);
+ }
}
}
@@ -5013,12 +5020,15 @@ retry:
// Undo SHCNE_DRIVEREMOVED
DeviceIoControl (hDriver, TC_IOCTL_GET_MOUNTED_VOLUMES, NULL, 0, &mountList, sizeof (mountList), &dwResult, NULL);
- for (i = 0; i < 26; i++)
+ if (mountList.ulMountedDrives)
{
- if (mountList.ulMountedDrives & (1 << i))
+ for (i = 0; i < 26; i++)
{
- wchar_t root[] = { (wchar_t) i + L'A', L':', L'\\', 0 };
- SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
+ if (mountList.ulMountedDrives & (1 << i))
+ {
+ wchar_t root[] = { (wchar_t) i + L'A', L':', L'\\', 0 };
+ SHChangeNotify (SHCNE_DRIVEADD, SHCNF_PATH, root, NULL);
+ }
}
}
}
@@ -6799,6 +6809,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
GetMountList (&LastKnownMountList);
SetTimer (hwndDlg, TIMER_ID_MAIN, TIMER_INTERVAL_MAIN, NULL);
+ SetTimer (hwndDlg, TIMER_ID_UPDATE_DEVICE_LIST, TIMER_INTERVAL_UPDATE_DEVICE_LIST, NULL);
taskBarCreatedMsg = RegisterWindowMessage (L"TaskbarCreated");
@@ -6955,197 +6966,204 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
case WM_TIMER:
{
- // Check mount list and update GUI if needed
- CheckMountList (hwndDlg, FALSE);
-
- // Cache status
- if (IsPasswordCacheEmpty() == IsWindowEnabled (GetDlgItem (hwndDlg, IDC_WIPE_CACHE)))
- EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty());
-
- // Check driver warning flags
- DWORD bytesOut;
- GetWarningFlagsRequest warnings;
- if (DeviceIoControl (hDriver, TC_IOCTL_GET_WARNING_FLAGS, NULL, 0, &warnings, sizeof (warnings), &bytesOut, NULL))
+ if (wParam == TIMER_ID_UPDATE_DEVICE_LIST)
{
- if (warnings.SystemFavoriteVolumeDirty)
- WarningTopMost ("SYS_FAVORITE_VOLUME_DIRTY", hwndDlg);
-
- if (warnings.PagingFileCreationPrevented)
- WarningTopMost ("PAGING_FILE_CREATION_PREVENTED", hwndDlg);
+ UpdateMountableHostDeviceList ();
}
-
- if (TaskBarIconMutex != NULL)
+ else
{
+ // Check mount list and update GUI if needed
+ CheckMountList (hwndDlg, FALSE);
- // Idle auto-dismount
- if (MaxVolumeIdleTime > 0)
- DismountIdleVolumes ();
+ // Cache status
+ if (IsPasswordCacheEmpty() == IsWindowEnabled (GetDlgItem (hwndDlg, IDC_WIPE_CACHE)))
+ EnableWindow (GetDlgItem (hwndDlg, IDC_WIPE_CACHE), !IsPasswordCacheEmpty());
- // Screen saver auto-dismount
- if (bDismountOnScreenSaver)
+ // Check driver warning flags
+ DWORD bytesOut;
+ GetWarningFlagsRequest warnings;
+ if (DeviceIoControl (hDriver, TC_IOCTL_GET_WARNING_FLAGS, NULL, 0, &warnings, sizeof (warnings), &bytesOut, NULL))
{
- static BOOL previousState = FALSE;
- BOOL running = FALSE;
- SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0);
+ if (warnings.SystemFavoriteVolumeDirty)
+ WarningTopMost ("SYS_FAVORITE_VOLUME_DIRTY", hwndDlg);
- if (running && !previousState)
- {
- DWORD dwResult;
- previousState = TRUE;
-
- if (bWipeCacheOnAutoDismount)
- {
- DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
- SecurityToken::CloseAllSessions();
- }
-
- DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY);
- }
- else
- {
- previousState = running;
- }
+ if (warnings.PagingFileCreationPrevented)
+ WarningTopMost ("PAGING_FILE_CREATION_PREVENTED", hwndDlg);
}
- // Auto-mount favorite volumes on arrival
-#if TIMER_INTERVAL_MAIN != 500
-#error TIMER_INTERVAL_MAIN != 500
-#endif
- static int favoritesAutoMountTimerDivisor = 0;
- if ((++favoritesAutoMountTimerDivisor & 1) && !FavoritesOnArrivalMountRequired.empty())
+ if (TaskBarIconMutex != NULL)
{
- static bool reentry = false;
- if (reentry)
- break;
- reentry = true;
+ // Idle auto-dismount
+ if (MaxVolumeIdleTime > 0)
+ DismountIdleVolumes ();
- foreach (FavoriteVolume favorite, FavoritesOnArrivalMountRequired)
+ // Screen saver auto-dismount
+ if (bDismountOnScreenSaver)
{
- if (favorite.UseVolumeID)
+ static BOOL previousState = FALSE;
+ BOOL running = FALSE;
+ SystemParametersInfo (SPI_GETSCREENSAVERRUNNING, 0, &running, 0);
+
+ if (running && !previousState)
{
- if (IsMountedVolumeID (favorite.VolumeID))
- continue;
+ DWORD dwResult;
+ previousState = TRUE;
- std::wstring volDevPath = FindDeviceByVolumeID (favorite.VolumeID);
- if (volDevPath.length() > 0)
+ if (bWipeCacheOnAutoDismount)
{
- favorite.Path = volDevPath;
- favorite.DisconnectedDevice = false;
+ DeviceIoControl (hDriver, TC_IOCTL_WIPE_PASSWORD_CACHE, NULL, 0, NULL, 0, &dwResult, NULL);
+ SecurityToken::CloseAllSessions();
}
- else
- continue;
- }
- else if (!favorite.VolumePathId.empty())
- {
- if (IsMountedVolume (favorite.Path.c_str()))
- continue;
- wchar_t volDevPath[TC_MAX_PATH];
- if (QueryDosDevice (favorite.VolumePathId.substr (4, favorite.VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) == 0)
- continue;
-
- favorite.DisconnectedDevice = false;
+ DismountAll (hwndDlg, bForceAutoDismount, FALSE, UNMOUNT_MAX_AUTO_RETRIES, UNMOUNT_AUTO_RETRY_DELAY);
}
- else if (favorite.Path.find (L"\\\\?\\Volume{") == 0)
+ else
{
- wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path);
- if (resolvedPath.empty())
- continue;
-
- favorite.DisconnectedDevice = false;
- favorite.VolumePathId = favorite.Path;
- favorite.Path = resolvedPath;
+ previousState = running;
}
+ }
- if (IsMountedVolume (favorite.Path.c_str()))
- continue;
+ // Auto-mount favorite volumes on arrival
+ #if TIMER_INTERVAL_MAIN != 500
+ #error TIMER_INTERVAL_MAIN != 500
+ #endif
+ static int favoritesAutoMountTimerDivisor = 0;
+ if ((++favoritesAutoMountTimerDivisor & 1) && !FavoritesOnArrivalMountRequired.empty())
+ {
+ static bool reentry = false;
+ if (reentry)
+ break;
- if (!IsVolumeDeviceHosted (favorite.Path.c_str()))
- {
- if (!FileExists (favorite.Path.c_str()))
- continue;
- }
- else if (favorite.VolumePathId.empty())
- continue;
+ reentry = true;
- bool mountedAndNotDisconnected = false;
- foreach (FavoriteVolume mountedFavorite, FavoritesMountedOnArrivalStillConnected)
+ foreach (FavoriteVolume favorite, FavoritesOnArrivalMountRequired)
{
- if (favorite.Path == mountedFavorite.Path)
+ if (favorite.UseVolumeID)
{
- mountedAndNotDisconnected = true;
- break;
+ 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;
- if (!mountedAndNotDisconnected)
- {
- FavoriteMountOnArrivalInProgress = TRUE;
- MountFavoriteVolumes (hwndDlg, FALSE, FALSE, FALSE, favorite);
- FavoriteMountOnArrivalInProgress = FALSE;
+ wchar_t volDevPath[TC_MAX_PATH];
+ if (QueryDosDevice (favorite.VolumePathId.substr (4, favorite.VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) == 0)
+ continue;
- FavoritesMountedOnArrivalStillConnected.push_back (favorite);
- }
- }
+ favorite.DisconnectedDevice = false;
+ }
+ else if (favorite.Path.find (L"\\\\?\\Volume{") == 0)
+ {
+ wstring resolvedPath = VolumeGuidPathToDevicePath (favorite.Path);
+ if (resolvedPath.empty())
+ continue;
- bool deleted;
- for (list <FavoriteVolume>::iterator favorite = FavoritesMountedOnArrivalStillConnected.begin();
- favorite != FavoritesMountedOnArrivalStillConnected.end();
- deleted ? favorite : ++favorite)
- {
- deleted = false;
+ favorite.DisconnectedDevice = false;
+ favorite.VolumePathId = favorite.Path;
+ favorite.Path = resolvedPath;
+ }
- if (IsMountedVolume (favorite->Path.c_str()))
- continue;
+ if (IsMountedVolume (favorite.Path.c_str()))
+ continue;
- if (!IsVolumeDeviceHosted (favorite->Path.c_str()))
- {
- if (FileExists (favorite->Path.c_str()))
+ if (!IsVolumeDeviceHosted (favorite.Path.c_str()))
+ {
+ if (!FileExists (favorite.Path.c_str()))
+ continue;
+ }
+ else if (favorite.VolumePathId.empty())
continue;
- }
- wchar_t volDevPath[TC_MAX_PATH];
- if (favorite->VolumePathId.size() > 5
- && QueryDosDevice (favorite->VolumePathId.substr (4, favorite->VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) != 0)
- {
- continue;
+ bool mountedAndNotDisconnected = false;
+ foreach (FavoriteVolume mountedFavorite, FavoritesMountedOnArrivalStillConnected)
+ {
+ if (favorite.Path == mountedFavorite.Path)
+ {
+ mountedAndNotDisconnected = true;
+ break;
+ }
+ }
+
+ if (!mountedAndNotDisconnected)
+ {
+ FavoriteMountOnArrivalInProgress = TRUE;
+ MountFavoriteVolumes (hwndDlg, FALSE, FALSE, FALSE, favorite);
+ FavoriteMountOnArrivalInProgress = FALSE;
+
+ FavoritesMountedOnArrivalStillConnected.push_back (favorite);
+ }
}
- // set DisconnectedDevice field on FavoritesOnArrivalMountRequired element
- foreach (FavoriteVolume onArrivalFavorite, FavoritesOnArrivalMountRequired)
+ bool deleted;
+ for (list <FavoriteVolume>::iterator favorite = FavoritesMountedOnArrivalStillConnected.begin();
+ favorite != FavoritesMountedOnArrivalStillConnected.end();
+ deleted ? favorite : ++favorite)
{
- if (onArrivalFavorite.Path == favorite->Path)
+ deleted = false;
+
+ if (IsMountedVolume (favorite->Path.c_str()))
+ continue;
+
+ if (!IsVolumeDeviceHosted (favorite->Path.c_str()))
{
- onArrivalFavorite.DisconnectedDevice = true;
- break;
+ if (FileExists (favorite->Path.c_str()))
+ continue;
+ }
+
+ wchar_t volDevPath[TC_MAX_PATH];
+ if (favorite->VolumePathId.size() > 5
+ && QueryDosDevice (favorite->VolumePathId.substr (4, favorite->VolumePathId.size() - 5).c_str(), volDevPath, TC_MAX_PATH) != 0)
+ {
+ 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;
}
- favorite = FavoritesMountedOnArrivalStillConnected.erase (favorite);
- deleted = true;
+ reentry = false;
}
-
- reentry = false;
}
- }
- // Exit background process in non-install mode or if no volume mounted
- // and no other instance active
- if (LastKnownMountList.ulMountedDrives == 0
- && MainWindowHidden
-#ifndef _DEBUG
- && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ())
- && !SysEncDeviceActive (TRUE)
-#endif
- && GetDriverRefCount () < 2)
- {
- TaskBarIconRemove (hwndDlg);
- UnregisterWtsNotification(hwndDlg);
- EndMainDlg (hwndDlg);
+ // Exit background process in non-install mode or if no volume mounted
+ // and no other instance active
+ if (LastKnownMountList.ulMountedDrives == 0
+ && MainWindowHidden
+ #ifndef _DEBUG
+ && (bCloseBkgTaskWhenNoVolumes || IsNonInstallMode ())
+ && !SysEncDeviceActive (TRUE)
+ #endif
+ && GetDriverRefCount () < 2)
+ {
+ TaskBarIconRemove (hwndDlg);
+ UnregisterWtsNotification(hwndDlg);
+ EndMainDlg (hwndDlg);
+ }
}
- }
- return 1;
+ return 1;
+ }
case TC_APPMSG_TASKBAR_ICON:
{
@@ -7316,7 +7334,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
for (i = 0; i < 26; i++)
{
- if ((vol->dbcv_unitmask & (1 << i)) && !(GetUsedLogicalDrives() & (1 << i)))
+ if (LastKnownMountList.ulMountedDrives && (vol->dbcv_unitmask & (1 << i)) && !(GetUsedLogicalDrives() & (1 << i)))
{
for (m = 0; m < 26; m++)
{
@@ -7352,7 +7370,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
{
OPEN_TEST_STRUCT ots = {0};
- if (!OpenDevice (vol, &ots, FALSE, FALSE, NULL))
+ if (!OpenDevice (vol, &ots, FALSE, FALSE))
{
UnmountVolume (hwndDlg, m, TRUE);
WarningBalloon ("HOST_DEVICE_REMOVAL_DISMOUNT_WARN_TITLE", "HOST_DEVICE_REMOVAL_DISMOUNT_WARN", hwndDlg);