From d1a7695841f5ee824b0782503a50bd6503ce605f Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:10:01 -0400 Subject: [PATCH 1/8] address issue #16149 Address the following issue: https://github.com/files-community/Files/issues/16149 Avoid skipping detection of a drive named G that is not Google Drive when the registry contains old keys for Google Drive. Add "My Drive" to the Google Drive registry path in RemovableDrivesService and check if it's valid. Then DON'T skip the found "G" drive if the "My Drive" path is NOT valid. --- .../Services/Storage/StorageDevicesService.cs | 10 ++++++---- .../Utils/Cloud/Detector/GoogleDriveCloudDetector.cs | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs index a2971a217fab..7a0c07f469ed 100644 --- a/src/Files.App/Services/Storage/StorageDevicesService.cs +++ b/src/Files.App/Services/Storage/StorageDevicesService.cs @@ -25,25 +25,27 @@ public async IAsyncEnumerable GetDrivesAsync() var googleDrivePath = GoogleDriveCloudDetector.GetRegistryBasePath(); sw.Stop(); Debug.WriteLine($"In RemovableDrivesService: Time elapsed for registry check: {sw.Elapsed}"); - App.AppModel.GoogleDrivePath = googleDrivePath ?? string.Empty; + var googleDrivePathWithMyDrive = googleDrivePath ?? string.Empty; + var gdPathIsValid = GoogleDriveCloudDetector.AddMyDriveToPathAndValidate(ref googleDrivePathWithMyDrive); + App.AppModel.GoogleDrivePath = gdPathIsValid ? googleDrivePathWithMyDrive : string.Empty; foreach (var drive in list) { // We don't want cloud drives to appear in a plain "Drives" section. - if (drive.Name.Equals(googleDrivePath) || drive.Name.Equals(pCloudDrivePath)) + if ((gdPathIsValid && drive.Name.Equals(googleDrivePath)) || drive.Name.Equals(pCloudDrivePath)) continue; var res = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(drive.Name).AsTask()); if (res.ErrorCode is FileSystemStatusCode.Unauthorized) { App.Logger.LogWarning($"{res.ErrorCode}: Attempting to add the device, {drive.Name}," - + " failed at the StorageFolder initialization step. This device will be ignored."); + + " failed at the StorageFolder initialization step. This device will be ignored."); continue; } else if (!res) { App.Logger.LogWarning($"{res.ErrorCode}: Attempting to add the device, {drive.Name}," - + " failed at the StorageFolder initialization step. This device will be ignored."); + + " failed at the StorageFolder initialization step. This device will be ignored."); continue; } diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index b390e35560a8..14d8ce1f1636 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -108,7 +108,7 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a await Inspect(database, "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY 1", "root_preferences db, all tables"); var registryPath = App.AppModel.GoogleDrivePath; - if (!AddMyDriveToPathAndValidate(ref registryPath)) + if (registryPath.Equals(string.Empty)) yield break; yield return new CloudProvider(CloudProviders.GoogleDrive) { @@ -258,7 +258,7 @@ private static bool ValidatePath(string path) return await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(iconPath).AsTask()); } - private static bool AddMyDriveToPathAndValidate(ref string path) + public static bool AddMyDriveToPathAndValidate(ref string path) { // If `path` contains a shortcut named "My Drive", store its target in `shellFolderBaseFirst`. // This happens when "My Drive syncing options" is set to "Mirror files". From 5cac6dab1326b13bc453e3a7a6104e7eb1953f21 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Wed, 11 Sep 2024 18:04:36 -0400 Subject: [PATCH 2/8] issue #16149 different approach Different approach to addressing the following issue: https://github.com/files-community/Files/issues/16149 Use DriveHelpers.GetExtendedDriveLabel to safely get the VolumeLabel of each DriveInfo object that RemovableDrivesService looks at. Then use this to filter out GoogleDrive drives from appearing in a plain "Drives" section, while still (hopefully) allowing drives named "G" to appear in such a section. Next I will test this by renaming my Google Drive drive to something other than G, and then making a new drive that is not Google Drive and naming it "G", and then running the program to see if it detects the non-Google Drive "G" drive. next: testing --- src/Files.App/Services/Storage/StorageDevicesService.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs index 7a0c07f469ed..a46c691bb664 100644 --- a/src/Files.App/Services/Storage/StorageDevicesService.cs +++ b/src/Files.App/Services/Storage/StorageDevicesService.cs @@ -24,15 +24,17 @@ public async IAsyncEnumerable GetDrivesAsync() var sw = Stopwatch.StartNew(); var googleDrivePath = GoogleDriveCloudDetector.GetRegistryBasePath(); sw.Stop(); - Debug.WriteLine($"In RemovableDrivesService: Time elapsed for registry check: {sw.Elapsed}"); + Debug.WriteLine($"In RemovableDrivesService: Time elapsed for Google Drive registry check: {sw.Elapsed}"); var googleDrivePathWithMyDrive = googleDrivePath ?? string.Empty; var gdPathIsValid = GoogleDriveCloudDetector.AddMyDriveToPathAndValidate(ref googleDrivePathWithMyDrive); App.AppModel.GoogleDrivePath = gdPathIsValid ? googleDrivePathWithMyDrive : string.Empty; foreach (var drive in list) { + var driveLabel = DriveHelpers.GetExtendedDriveLabel(drive); + Debug.WriteLine($"In RemovableDrivesService: Drive {drive.Name} has ExtendedDriveLabel `{driveLabel}`"); // We don't want cloud drives to appear in a plain "Drives" section. - if ((gdPathIsValid && drive.Name.Equals(googleDrivePath)) || drive.Name.Equals(pCloudDrivePath)) + if (driveLabel.Equals("Google Drive") || drive.Name.Equals(pCloudDrivePath)) continue; var res = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(drive.Name).AsTask()); From 0aec20fa5b5549cf1516d5c2167ef72620656084 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Wed, 18 Dec 2024 22:14:49 -0500 Subject: [PATCH 3/8] progress on #16149 (pre-PR) Move Registry query for the base Google Drive path from `StorageDevicesService` back into `GoogleDriveCloudDetector` because we can use the drive label to filter GD out of the plain "Drives" sections (we were using the base GD path). Comments and logging adjustments. next: test on all the mirror/stream-letter/folder configs --- .../Services/Storage/StorageDevicesService.cs | 10 ------ .../Detector/GoogleDriveCloudDetector.cs | 31 ++++++++++++------- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs index a46c691bb664..0c9b33dd5683 100644 --- a/src/Files.App/Services/Storage/StorageDevicesService.cs +++ b/src/Files.App/Services/Storage/StorageDevicesService.cs @@ -20,19 +20,9 @@ public async IAsyncEnumerable GetDrivesAsync() { var list = DriveInfo.GetDrives(); var pCloudDrivePath = App.AppModel.PCloudDrivePath; - - var sw = Stopwatch.StartNew(); - var googleDrivePath = GoogleDriveCloudDetector.GetRegistryBasePath(); - sw.Stop(); - Debug.WriteLine($"In RemovableDrivesService: Time elapsed for Google Drive registry check: {sw.Elapsed}"); - var googleDrivePathWithMyDrive = googleDrivePath ?? string.Empty; - var gdPathIsValid = GoogleDriveCloudDetector.AddMyDriveToPathAndValidate(ref googleDrivePathWithMyDrive); - App.AppModel.GoogleDrivePath = gdPathIsValid ? googleDrivePathWithMyDrive : string.Empty; - foreach (var drive in list) { var driveLabel = DriveHelpers.GetExtendedDriveLabel(drive); - Debug.WriteLine($"In RemovableDrivesService: Drive {drive.Name} has ExtendedDriveLabel `{driveLabel}`"); // We don't want cloud drives to appear in a plain "Drives" section. if (driveLabel.Equals("Google Drive") || drive.Name.Equals(pCloudDrivePath)) continue; diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index 14d8ce1f1636..77e2a166c6a0 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -103,19 +103,25 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a }; } + // Log the contents of the root_preferences database to the debug output. await Inspect(database, "SELECT * FROM roots", "root_preferences db, roots table"); await Inspect(database, "SELECT * FROM media", "root_preferences db, media table"); await Inspect(database, "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY 1", "root_preferences db, all tables"); - var registryPath = App.AppModel.GoogleDrivePath; - if (registryPath.Equals(string.Empty)) - yield break; - yield return new CloudProvider(CloudProviders.GoogleDrive) - { - Name = "Google Drive", - SyncFolder = registryPath, - IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null - }; + // Query the Windows Registry for the base Google Drive path and time the query. + var sw = Stopwatch.StartNew(); + var googleDrivePath = GetRegistryBasePath() ?? string.Empty; + sw.Stop(); + Debug.WriteLine($"Google Drive path registry check took {sw.Elapsed} seconds."); + + // Add "My Drive" to the base GD path and return the resulting cloud provider. + if (AddMyDriveToPathAndValidate(ref googleDrivePath)) + yield return new CloudProvider(CloudProviders.GoogleDrive) + { + Name = "Google Drive", + SyncFolder = googleDrivePath, + IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null + }; } private static async Task Inspect(SqliteConnection database, string sqlCommand, string targetDescription) @@ -175,8 +181,8 @@ private static async Task Inspect(SqliteConnection database, string sqlCommand, .RootElement.EnumerateObject() .FirstOrDefault(); - // A default JsonProperty struct has an "Undefined" Value#ValueKind and throws an - // error if you try to call EnumerateArray on its Value. + // A default `JsonProperty` struct has an Undefined `Value.ValueKind` and throws an + // error if you try to call `EnumerateArray` on its `Value`. if (googleDriveRegValJsonProperty.Value.ValueKind == JsonValueKind.Undefined) { _logger.LogWarning($"Root element of Google Drive registry value for value name '{_googleDriveRegValName}' was empty."); @@ -269,7 +275,8 @@ public static bool AddMyDriveToPathAndValidate(ref string path) si.Name?.Equals("My Drive") ?? false) as ShellLink)?.TargetPath ?? string.Empty); - Debug.WriteLine("SHELL FOLDER LOGGING"); + var callingMethod = new StackFrame(1).GetMethod(); + Debug.WriteLine($"SHELL FOLDER LOGGING (Context: `{callingMethod?.Name}` in `{callingMethod?.DeclaringType}`)"); rootFolder?.ForEach(si => Debug.WriteLine(si.Name)); if (!string.IsNullOrEmpty(myDriveFolder)) From 4379f91f26fa7a02e2fa376e847bba9e3c57f190 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Thu, 9 Jan 2025 18:02:52 -0500 Subject: [PATCH 4/8] progress on #16149 -- cleanup (pre-PR) StorageDevicesService Fix spacing of concatenated string that somehow got changed. GoogleDriveCloudDetector Change back to early yield break at end of `GetProviders` to reduce nesting. GoogleDriveCloudDetector Change `AddMyDriveToPathAndValidate` back to private. GoogleDriveCloudDetector Remove call stack logging from `AddMyDriveToPathAndValidate`. --- .../Services/Storage/StorageDevicesService.cs | 7 +++--- .../Detector/GoogleDriveCloudDetector.cs | 22 +++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs index 0c9b33dd5683..eae44e0fe634 100644 --- a/src/Files.App/Services/Storage/StorageDevicesService.cs +++ b/src/Files.App/Services/Storage/StorageDevicesService.cs @@ -23,7 +23,8 @@ public async IAsyncEnumerable GetDrivesAsync() foreach (var drive in list) { var driveLabel = DriveHelpers.GetExtendedDriveLabel(drive); - // We don't want cloud drives to appear in a plain "Drives" section. + // Cloud Drive Filter If (CDFI) + // We don't want cloud drives to appear in the plain "Drives" sections. if (driveLabel.Equals("Google Drive") || drive.Name.Equals(pCloudDrivePath)) continue; @@ -31,13 +32,13 @@ public async IAsyncEnumerable GetDrivesAsync() if (res.ErrorCode is FileSystemStatusCode.Unauthorized) { App.Logger.LogWarning($"{res.ErrorCode}: Attempting to add the device, {drive.Name}," - + " failed at the StorageFolder initialization step. This device will be ignored."); + + " failed at the StorageFolder initialization step. This device will be ignored."); continue; } else if (!res) { App.Logger.LogWarning($"{res.ErrorCode}: Attempting to add the device, {drive.Name}," - + " failed at the StorageFolder initialization step. This device will be ignored."); + + " failed at the StorageFolder initialization step. This device will be ignored."); continue; } diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index 77e2a166c6a0..e62688102e22 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -114,14 +114,15 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a sw.Stop(); Debug.WriteLine($"Google Drive path registry check took {sw.Elapsed} seconds."); - // Add "My Drive" to the base GD path and return the resulting cloud provider. - if (AddMyDriveToPathAndValidate(ref googleDrivePath)) - yield return new CloudProvider(CloudProviders.GoogleDrive) - { - Name = "Google Drive", - SyncFolder = googleDrivePath, - IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null - }; + // Add "My Drive" to the base GD path; validate; return the resulting cloud provider. + if (!AddMyDriveToPathAndValidate(ref googleDrivePath)) + yield break; + yield return new CloudProvider(CloudProviders.GoogleDrive) + { + Name = "Google Drive", + SyncFolder = googleDrivePath, + IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null + }; } private static async Task Inspect(SqliteConnection database, string sqlCommand, string targetDescription) @@ -264,7 +265,7 @@ private static bool ValidatePath(string path) return await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(iconPath).AsTask()); } - public static bool AddMyDriveToPathAndValidate(ref string path) + private static bool AddMyDriveToPathAndValidate(ref string path) { // If `path` contains a shortcut named "My Drive", store its target in `shellFolderBaseFirst`. // This happens when "My Drive syncing options" is set to "Mirror files". @@ -275,8 +276,7 @@ public static bool AddMyDriveToPathAndValidate(ref string path) si.Name?.Equals("My Drive") ?? false) as ShellLink)?.TargetPath ?? string.Empty); - var callingMethod = new StackFrame(1).GetMethod(); - Debug.WriteLine($"SHELL FOLDER LOGGING (Context: `{callingMethod?.Name}` in `{callingMethod?.DeclaringType}`)"); + Debug.WriteLine("SHELL FOLDER LOGGING"); rootFolder?.ForEach(si => Debug.WriteLine(si.Name)); if (!string.IsNullOrEmpty(myDriveFolder)) From 08c88aaa76e0c99249a2fb5baf5978c94dc15ea7 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Sun, 12 Jan 2025 18:20:23 -0500 Subject: [PATCH 5/8] add comment Provide link to advanced Google Drive for desktop settings reference in summary comment above `GoogleDriveCloudDetector.GetRegistryBasePath`. --- .../Utils/Cloud/Detector/GoogleDriveCloudDetector.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index e62688102e22..4faeb8b2ca14 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -171,6 +171,11 @@ private static async Task Inspect(SqliteConnection database, string sqlCommand, return googleDriveRegValueJson; } + /// + /// Get the base file system path for Google Drive from the Registry. + /// For advanced "Google Drive for desktop" settings reference, see: + /// https://support.google.com/a/answer/7644837 + /// public static string? GetRegistryBasePath() { var googleDriveRegValJson = GetGoogleDriveRegValJson(); From e6564984c2d0def223654c51e8b54863409b362d Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Sun, 19 Jan 2025 15:00:42 -0500 Subject: [PATCH 6/8] Update src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs Co-authored-by: Lamparter <71598437+Lamparter@users.noreply.github.com> Signed-off-by: Tim <81175852+wharvex@users.noreply.github.com> --- .../Utils/Cloud/Detector/GoogleDriveCloudDetector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index 4faeb8b2ca14..efcdcd8555f6 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -187,8 +187,8 @@ private static async Task Inspect(SqliteConnection database, string sqlCommand, .RootElement.EnumerateObject() .FirstOrDefault(); - // A default `JsonProperty` struct has an Undefined `Value.ValueKind` and throws an - // error if you try to call `EnumerateArray` on its `Value`. + // A default "JsonProperty" struct has an undefined "Value.ValueKind" and throws an + // error if you try to call "EnumerateArray" on its value. if (googleDriveRegValJsonProperty.Value.ValueKind == JsonValueKind.Undefined) { _logger.LogWarning($"Root element of Google Drive registry value for value name '{_googleDriveRegValName}' was empty."); From aa8cbbd71d74afdc1bf6c79466aad63df8e8d909 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Sun, 19 Jan 2025 15:19:31 -0500 Subject: [PATCH 7/8] Update src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs Co-authored-by: Lamparter <71598437+Lamparter@users.noreply.github.com> Signed-off-by: Tim <81175852+wharvex@users.noreply.github.com> --- .../Utils/Cloud/Detector/GoogleDriveCloudDetector.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs index efcdcd8555f6..c6042c8176bb 100644 --- a/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs @@ -172,10 +172,12 @@ private static async Task Inspect(SqliteConnection database, string sqlCommand, } /// - /// Get the base file system path for Google Drive from the Registry. - /// For advanced "Google Drive for desktop" settings reference, see: - /// https://support.google.com/a/answer/7644837 + /// Get the base file system path for Google Drive from the Registry. /// + /// + /// For advanced "Google Drive for desktop" settings reference, see: + /// https://support.google.com/a/answer/7644837 + /// public static string? GetRegistryBasePath() { var googleDriveRegValJson = GetGoogleDriveRegValJson(); From fec01df376d5f2b013534559484c0f35881c4dd8 Mon Sep 17 00:00:00 2001 From: Tim <81175852+wharvex@users.noreply.github.com> Date: Sun, 19 Jan 2025 16:20:00 -0500 Subject: [PATCH 8/8] Update src/Files.App/Services/Storage/StorageDevicesService.cs Co-authored-by: Lamparter <71598437+Lamparter@users.noreply.github.com> Signed-off-by: Tim <81175852+wharvex@users.noreply.github.com> --- src/Files.App/Services/Storage/StorageDevicesService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Files.App/Services/Storage/StorageDevicesService.cs b/src/Files.App/Services/Storage/StorageDevicesService.cs index eae44e0fe634..a13ab8d41a42 100644 --- a/src/Files.App/Services/Storage/StorageDevicesService.cs +++ b/src/Files.App/Services/Storage/StorageDevicesService.cs @@ -23,7 +23,7 @@ public async IAsyncEnumerable GetDrivesAsync() foreach (var drive in list) { var driveLabel = DriveHelpers.GetExtendedDriveLabel(drive); - // Cloud Drive Filter If (CDFI) + // Filter out cloud drives // We don't want cloud drives to appear in the plain "Drives" sections. if (driveLabel.Equals("Google Drive") || drive.Name.Equals(pCloudDrivePath)) continue;