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/Mount/Mount.c | 330 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 174 insertions(+), 156 deletions(-) (limited to 'src/Mount/Mount.c') 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