From fe26ed8a5d224b133c48e2846b851d585460ad30 Mon Sep 17 00:00:00 2001 From: Mounir IDRASSI Date: Wed, 19 Jul 2017 11:25:25 +0200 Subject: Windows: in case of mounting system favorites, call driver to get list of drives instead of using SetupAPI in order to fix some rare issues where some disks were not detected at boot. --- src/Common/Dlgcode.c | 171 ++++++++++++++++++++++++++++----------------------- src/Common/Dlgcode.h | 2 +- src/Mount/Mount.c | 8 +-- 3 files changed, 100 insertions(+), 81 deletions(-) diff --git a/src/Common/Dlgcode.c b/src/Common/Dlgcode.c index 702ba4e9..08bdbc84 100644 --- a/src/Common/Dlgcode.c +++ b/src/Common/Dlgcode.c @@ -11866,8 +11866,11 @@ void AddDeviceToList (std::vector& devices, int devNumber, int partN devices.push_back (device); } -std::vector GetHostRawDeviceList () +std::vector GetHostRawDeviceList (bool bFromService) { + if (bFromService) + return GetAvailableHostDevices (true, false, true, true); + std::vector list; HDEVINFO diskClassDevices; GUID diskClassDeviceInterfaceGuid = GUID_DEVINTERFACE_DISK; @@ -11980,7 +11983,7 @@ bool CompareDeviceList (const std::vector& list1, const std::vector< return true; } -void UpdateMountableHostDeviceList () +void UpdateMountableHostDeviceList (bool bFromService) { ByteArray buffer(4096); DWORD bytesReturned; @@ -11989,7 +11992,7 @@ void UpdateMountableHostDeviceList () EnterCriticalSection (&csMountableDevices); finally_do ({ LeaveCriticalSection (&csMountableDevices); }); - std::vector newList = GetHostRawDeviceList (); + std::vector newList = GetHostRawDeviceList (bFromService); std::map existingDevicesMap; if (CompareDeviceList (newList, rawHostDeviceList)) @@ -12032,104 +12035,120 @@ void UpdateMountableHostDeviceList () 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, + if (bFromService) + { + if (It->Partitions.empty()) + mountableDevices.push_back (*It); + else + { + for (std::vector::iterator partIt = It->Partitions.begin(); partIt != It->Partitions.end(); partIt++) + { + if (!partIt->ContainsSystem && !partIt->HasUnencryptedFilesystem) + mountableDevices.push_back (*partIt); + } + } + } + else + { + HANDLE disk = CreateFile( It->Path.c_str(), + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, 0, - (LPVOID) buffer.data(), - (DWORD) buffer.size(), - (LPDWORD) &bytesReturned, - NULL) && (bytesReturned >= sizeof (DRIVE_LAYOUT_INFORMATION_EX))) - { - PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data(); - // sanity checks - if (layout->PartitionCount <= 256) + 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) && (bytesReturned >= sizeof (DRIVE_LAYOUT_INFORMATION_EX))) { - for (DWORD i = 0; i < layout->PartitionCount; i++) + PDRIVE_LAYOUT_INFORMATION_EX layout = (PDRIVE_LAYOUT_INFORMATION_EX) buffer.data(); + // sanity checks + if (layout->PartitionCount <= 256) { - if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_MBR) + for (DWORD i = 0; i < layout->PartitionCount; i++) { - if (layout->PartitionEntry[i].Mbr.PartitionType == 0) - continue; + if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_MBR) + { + if (layout->PartitionEntry[i].Mbr.PartitionType == 0) + continue; - bHasPartition = true; + 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; + /* 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; + if (layout->PartitionEntry[i].PartitionStyle == PARTITION_STYLE_GPT) + { + if (IsEqualGUID(layout->PartitionEntry[i].Gpt.PartitionType, PARTITION_ENTRY_UNUSED_GUID)) + continue; - bHasPartition = true; + 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; + /* 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) || (GetLastError () == ERROR_ACCESS_DENIED)) - { - AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); - if (handle != INVALID_HANDLE_VALUE) - CloseHandle (handle); + 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) || (GetLastError () == ERROR_ACCESS_DENIED)) + { + AddDeviceToList (mountableDevices, It->SystemNumber, layout->PartitionEntry[i].PartitionNumber); + if (handle != INVALID_HANDLE_VALUE) + CloseHandle (handle); + } } } } - } - if (bIsDynamic) - dynamicVolumesPresent = true; + if (bIsDynamic) + dynamicVolumesPresent = true; - if (!bHasPartition) - AddDeviceToList (mountableDevices, It->SystemNumber, 0); + if (!bHasPartition) + AddDeviceToList (mountableDevices, It->SystemNumber, 0); - CloseHandle (disk); + 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)) + if (!bFromService && dynamicVolumesPresent && (CurrentOSMajor >= 6)) { for (int devNumber = 0; devNumber < 256; devNumber++) { diff --git a/src/Common/Dlgcode.h b/src/Common/Dlgcode.h index 47ab035d..d2db4ba4 100644 --- a/src/Common/Dlgcode.h +++ b/src/Common/Dlgcode.h @@ -626,7 +626,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 (); +void UpdateMountableHostDeviceList (bool bFromService); INT_PTR TextEditDialogBox (BOOL readOnly, HWND parent, const WCHAR* Title, std::string& text); // Display a wait dialog while calling the provided callback with the given parameter diff --git a/src/Mount/Mount.c b/src/Mount/Mount.c index 6a7e1353..51a7c98a 100644 --- a/src/Mount/Mount.c +++ b/src/Mount/Mount.c @@ -495,7 +495,7 @@ static void InitMainDialog (HWND hwndDlg) } // initialize the list of devices available for mounting as early as possible - UpdateMountableHostDeviceList (); + UpdateMountableHostDeviceList (false); // Resize the logo bitmap if the user has a non-default DPI if (ScreenDPI != USER_DEFAULT_SCREEN_DPI @@ -7119,7 +7119,7 @@ BOOL CALLBACK MainDialogProc (HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa { if (wParam == TIMER_ID_UPDATE_DEVICE_LIST) { - UpdateMountableHostDeviceList (); + UpdateMountableHostDeviceList (false); } else { @@ -9168,7 +9168,7 @@ static VOID WINAPI SystemFavoritesServiceMain (DWORD argc, LPTSTR *argv) SystemFavoritesServiceLogInfo (wstring (L"Initializing list of host devices")); // initialize the list of devices available for mounting as early as possible - UpdateMountableHostDeviceList (); + UpdateMountableHostDeviceList (true); SystemFavoritesServiceLogInfo (wstring (L"Starting System Favorites mounting process")); @@ -9702,7 +9702,7 @@ BOOL MountFavoriteVolumes (HWND hwnd, BOOL systemFavorites, BOOL logOnMount, BOO Sleep (5000); SystemFavoritesServiceLogInfo (wstring (L"Updating list of host devices")); - UpdateMountableHostDeviceList (); + UpdateMountableHostDeviceList (true); SystemFavoritesServiceLogInfo (wstring (L"Trying to mount skipped system favorites")); -- cgit v1.2.3