From 55aa098295567868af26ca753e33cd9907d3b33d Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Thu, 1 Jun 2017 01:53:03 +0200 Subject: Windows: fix high CPU usage when a favorite is configured to mount using VolumeID when its host device is connected to the machine. --- src/Common/Apidrvr.h | 6 +- src/Common/BootEncryption.cpp | 2 + src/Common/Dlgcode.c | 464 +++++++++++++++++++++++++++++++++++++++--- src/Common/Dlgcode.h | 32 ++- src/Driver/Ntdriver.c | 53 +++-- src/Mount/Mount.c | 330 ++++++++++++++++-------------- 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 #include +#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 mountableDevices; +static std::vector 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 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 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 GetAvailableHostDevices (bool noDeviceProperties, bool return devices; } +void AddDeviceToList (std::vector& 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 GetHostRawDeviceList () +{ + std::vector 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& list1, const std::vector& list2) +{ + if (list1.size() != list2.size()) + return false; + + for (std::vector::const_iterator It1 = list1.begin(); It1 != list1.end(); It1++) + { + bool bFound = false; + for (std::vector::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 newList = GetHostRawDeviceList (); + std::map existingDevicesMap; + + if (CompareDeviceList (newList, rawHostDeviceList)) + return; //no change, return + + // remove raw devices that don't exist anymore + for (std::vector::iterator It = rawHostDeviceList.begin(); + It != rawHostDeviceList.end();) + { + for (std::vector::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::iterator It = mountableDevices.begin(); + It != mountableDevices.end();) + { + if (existingDevicesMap[It->SystemNumber]) + It++; + else + It = mountableDevices.erase (It); + } + + // add new devices + for (std::vector::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 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 newDevices = mountableDevices; + LeaveCriticalSection (&csMountableDevices); + + EnterCriticalSection (&csVolumeIdCandidates); + finally_do ({ LeaveCriticalSection (&csVolumeIdCandidates); }); + + /* remove any devices that don't exist anymore */ + for (std::vector::iterator It = volumeIdCandidates.begin(); + It != volumeIdCandidates.end();) { - for (int partNumber = 0; partNumber < MAX_HOST_PARTITION_NUMBER; partNumber++) + bool bFound = false; + for (std::vector::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::iterator newIt = newDevices.begin(); + newIt != newDevices.end(); newIt++) + { + bool bFound = false; + + for (std::vector::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::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 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 ::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 ::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); -- cgit v1.2.3