Skip to content

Commit fcca16f

Browse files
committed
Revert "Fix: Fixed an issue where Google Drive wasn't displayed when mounted as a folder (#15771)"
This reverts commit 9ecf257.
1 parent c9e2fe2 commit fcca16f

File tree

2 files changed

+11
-213
lines changed

2 files changed

+11
-213
lines changed

src/Files.App/Services/Storage/StorageDevicesService.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,11 @@ public IStorageDeviceWatcher CreateWatcher()
1919
public async IAsyncEnumerable<ILocatableFolder> GetDrivesAsync()
2020
{
2121
var list = DriveInfo.GetDrives();
22+
var googleDrivePath = App.AppModel.GoogleDrivePath;
2223
var pCloudDrivePath = App.AppModel.PCloudDrivePath;
2324

24-
var sw = Stopwatch.StartNew();
25-
var googleDrivePath = GoogleDriveCloudDetector.GetRegistryBasePath();
26-
sw.Stop();
27-
Debug.WriteLine($"In RemovableDrivesService: Time elapsed for registry check: {sw.Elapsed}");
28-
App.AppModel.GoogleDrivePath = googleDrivePath ?? string.Empty;
29-
3025
foreach (var drive in list)
3126
{
32-
// We don't want cloud drives to appear in a plain "Drives" section.
33-
if (drive.Name.Equals(googleDrivePath) || drive.Name.Equals(pCloudDrivePath))
34-
continue;
35-
3627
var res = await FilesystemTasks.Wrap(() => StorageFolder.GetFolderFromPathAsync(drive.Name).AsTask());
3728
if (res.ErrorCode is FileSystemStatusCode.Unauthorized)
3829
{
@@ -52,6 +43,10 @@ public async IAsyncEnumerable<ILocatableFolder> GetDrivesAsync()
5243
var label = DriveHelpers.GetExtendedDriveLabel(drive);
5344
var driveItem = await DriveItem.CreateFromPropertiesAsync(res.Result, drive.Name.TrimEnd('\\'), label, type, thumbnail);
5445

46+
// Don't add here because Google Drive is already displayed under cloud drives
47+
if (drive.Name == googleDrivePath || drive.Name == pCloudDrivePath)
48+
continue;
49+
5550
App.Logger.LogInformation($"Drive added: {driveItem.Path}, {driveItem.Type}");
5651

5752
yield return driveItem;

src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs

Lines changed: 6 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,16 @@
22
// Licensed under the MIT License. See the LICENSE.
33

44
using Microsoft.Data.Sqlite;
5-
using Microsoft.Extensions.Logging;
6-
using Microsoft.Win32;
75
using System.IO;
86
using Windows.Storage;
9-
using Vanara.Windows.Shell;
107

118
namespace Files.App.Utils.Cloud
129
{
1310
/// <summary>
14-
/// Provides a utility for Google Drive Cloud detection.
11+
/// Provides an utility for Google Drive Cloud detection.
1512
/// </summary>
1613
public sealed class GoogleDriveCloudDetector : AbstractCloudDetector
1714
{
18-
private static readonly ILogger _logger = Ioc.Default.GetRequiredService<ILogger<App>>();
19-
20-
private const string _googleDriveRegKeyName = @"Software\Google\DriveFS";
21-
private const string _googleDriveRegValName = "PerAccountPreferences";
22-
private const string _googleDriveRegValPropName = "value";
23-
private const string _googleDriveRegValPropPropName = "mount_point_path";
24-
2515
protected override async IAsyncEnumerable<ICloudProvider> GetProviders()
2616
{
2717
// Google Drive's sync database can be in a couple different locations. Go find it.
@@ -66,8 +56,7 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
6656
var folder = await StorageFolder.GetFolderFromPathAsync(path);
6757
string title = reader["title"]?.ToString() ?? folder.Name;
6858

69-
Debug.WriteLine("YIELD RETURNING from `GoogleDriveCloudDetector.GetProviders()` (roots): ");
70-
Debug.WriteLine($"Name: Google Drive ({title}); SyncFolder: {path}");
59+
App.AppModel.GoogleDrivePath = path;
7160

7261
yield return new CloudProvider(CloudProviders.GoogleDrive)
7362
{
@@ -76,7 +65,6 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
7665
};
7766
}
7867

79-
var iconFile = await GetGoogleDriveIconFileAsync();
8068
// Google virtual drive
8169
reader = cmdMedia.ExecuteReader();
8270

@@ -86,14 +74,13 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
8674
if (string.IsNullOrWhiteSpace(path))
8775
continue;
8876

89-
if (!AddMyDriveToPathAndValidate(ref path))
90-
continue;
91-
9277
var folder = await StorageFolder.GetFolderFromPathAsync(path);
9378
string title = reader["name"]?.ToString() ?? folder.Name;
79+
string iconPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "Google", "Drive File Stream", "drive_fs.ico");
80+
81+
App.AppModel.GoogleDrivePath = path;
9482

95-
Debug.WriteLine("YIELD RETURNING from `GoogleDriveCloudDetector.GetProviders` (media): ");
96-
Debug.WriteLine($"Name: {title}; SyncFolder: {path}");
83+
StorageFile iconFile = await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(iconPath).AsTask());
9784

9885
yield return new CloudProvider(CloudProviders.GoogleDrive)
9986
{
@@ -102,190 +89,6 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
10289
IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null,
10390
};
10491
}
105-
106-
await Inspect(database, "SELECT * FROM roots", "root_preferences db, roots table");
107-
await Inspect(database, "SELECT * FROM media", "root_preferences db, media table");
108-
await Inspect(database, "SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY 1", "root_preferences db, all tables");
109-
110-
var registryPath = App.AppModel.GoogleDrivePath;
111-
if (!AddMyDriveToPathAndValidate(ref registryPath))
112-
yield break;
113-
yield return new CloudProvider(CloudProviders.GoogleDrive)
114-
{
115-
Name = "Google Drive",
116-
SyncFolder = registryPath,
117-
IconData = iconFile is not null ? await iconFile.ToByteArrayAsync() : null
118-
};
119-
}
120-
121-
private static async Task Inspect(SqliteConnection database, string sqlCommand, string targetDescription)
122-
{
123-
await using var cmdTablesAll = new SqliteCommand(sqlCommand, database);
124-
var reader = await cmdTablesAll.ExecuteReaderAsync();
125-
var colNamesList = Enumerable.Range(0, reader.FieldCount).Select(i => reader.GetName(i)).ToList();
126-
127-
Debug.WriteLine($"BEGIN LOGGING of {targetDescription}");
128-
129-
for (int rowIdx = 0; reader.Read() is not false; rowIdx++)
130-
{
131-
var colVals = new object[reader.FieldCount];
132-
reader.GetValues(colVals);
133-
134-
colVals.Select((val, colIdx) => $"row {rowIdx}: column {colIdx}: {colNamesList[colIdx]}: {val}")
135-
.ToList().ForEach(s => Debug.WriteLine(s));
136-
}
137-
138-
Debug.WriteLine($"END LOGGING of {targetDescription} contents");
139-
}
140-
141-
private static JsonDocument? GetGoogleDriveRegValJson()
142-
{
143-
// This will be null if the key name is not found.
144-
using var googleDriveRegKey = Registry.CurrentUser.OpenSubKey(_googleDriveRegKeyName);
145-
146-
if (googleDriveRegKey is null)
147-
{
148-
_logger.LogWarning($"Google Drive registry key for key name '{_googleDriveRegKeyName}' not found.");
149-
return null;
150-
}
151-
152-
var googleDriveRegVal = googleDriveRegKey.GetValue(_googleDriveRegValName);
153-
154-
if (googleDriveRegVal is null)
155-
{
156-
_logger.LogWarning($"Google Drive registry value for value name '{_googleDriveRegValName}' not found.");
157-
return null;
158-
}
159-
160-
JsonDocument? googleDriveRegValueJson = null;
161-
try
162-
{
163-
googleDriveRegValueJson = JsonDocument.Parse(googleDriveRegVal.ToString() ?? "");
164-
}
165-
catch (JsonException je)
166-
{
167-
_logger.LogWarning(je, $"Google Drive registry value for value name '{_googleDriveRegValName}' could not be parsed as a JsonDocument.");
168-
}
169-
170-
return googleDriveRegValueJson;
171-
}
172-
173-
public static string? GetRegistryBasePath()
174-
{
175-
var googleDriveRegValJson = GetGoogleDriveRegValJson();
176-
177-
if (googleDriveRegValJson is null)
178-
return null;
179-
180-
var googleDriveRegValJsonProperty = googleDriveRegValJson
181-
.RootElement.EnumerateObject()
182-
.FirstOrDefault();
183-
184-
// A default JsonProperty struct has an "Undefined" Value#ValueKind and throws an
185-
// error if you try to call EnumerateArray on its Value.
186-
if (googleDriveRegValJsonProperty.Value.ValueKind == JsonValueKind.Undefined)
187-
{
188-
_logger.LogWarning($"Root element of Google Drive registry value for value name '{_googleDriveRegValName}' was empty.");
189-
return null;
190-
}
191-
192-
Debug.WriteLine("REGISTRY LOGGING");
193-
Debug.WriteLine(googleDriveRegValJsonProperty.ToString());
194-
195-
var item = googleDriveRegValJsonProperty.Value.EnumerateArray().FirstOrDefault();
196-
if (item.ValueKind == JsonValueKind.Undefined)
197-
{
198-
_logger.LogWarning($"Array in the root element of Google Drive registry value for value name '{_googleDriveRegValName}' was empty.");
199-
return null;
200-
}
201-
202-
if (!item.TryGetProperty(_googleDriveRegValPropName, out var googleDriveRegValProp))
203-
{
204-
_logger.LogWarning($"First element in the Google Drive Registry Root Array did not have property named {_googleDriveRegValPropName}");
205-
return null;
206-
}
207-
208-
if (!googleDriveRegValProp.TryGetProperty(_googleDriveRegValPropPropName, out var googleDriveRegValPropProp))
209-
{
210-
_logger.LogWarning($"Value from {_googleDriveRegValPropName} did not have property named {_googleDriveRegValPropPropName}");
211-
return null;
212-
}
213-
214-
var path = googleDriveRegValPropProp.GetString();
215-
if (path is not null)
216-
return ConvertDriveLetterToPathAndValidate(ref path) ? path : null;
217-
218-
_logger.LogWarning($"Could not get string from value from {_googleDriveRegValPropPropName}");
219-
return null;
220-
}
221-
222-
/// <summary>
223-
/// If Google Drive is mounted as a drive, then the path found in the registry will be
224-
/// *just* the drive letter (e.g. just "G" as opposed to "G:\"), and therefore must be
225-
/// reformatted as a valid path.
226-
/// </summary>
227-
private static bool ConvertDriveLetterToPathAndValidate(ref string path)
228-
{
229-
if (path.Length > 1)
230-
return ValidatePath(path);
231-
232-
DriveInfo driveInfo;
233-
try
234-
{
235-
driveInfo = new DriveInfo(path);
236-
}
237-
catch (ArgumentException e)
238-
{
239-
_logger.LogWarning(e, $"Could not resolve drive letter '{path}' to a valid drive.");
240-
return false;
241-
}
242-
243-
path = driveInfo.RootDirectory.Name;
244-
return true;
245-
}
246-
247-
private static bool ValidatePath(string path)
248-
{
249-
if (Directory.Exists(path))
250-
return true;
251-
_logger.LogWarning($"Invalid path: {path}");
252-
return false;
253-
}
254-
255-
private static async Task<StorageFile?> GetGoogleDriveIconFileAsync()
256-
{
257-
var programFilesEnvVar = Environment.GetEnvironmentVariable("ProgramFiles");
258-
259-
if (programFilesEnvVar is null)
260-
return null;
261-
262-
var iconPath = Path.Combine(programFilesEnvVar, "Google", "Drive File Stream", "drive_fs.ico");
263-
264-
return await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(iconPath).AsTask());
265-
}
266-
267-
private static bool AddMyDriveToPathAndValidate(ref string path)
268-
{
269-
// If `path` contains a shortcut named "My Drive", store its target in `shellFolderBaseFirst`.
270-
// This happens when "My Drive syncing options" is set to "Mirror files".
271-
// TODO: Avoid to use Vanara (#15000)
272-
using var rootFolder = ShellFolderExtensions.GetShellItemFromPathOrPIDL(path) as ShellFolder;
273-
var myDriveFolder = Environment.ExpandEnvironmentVariables((
274-
rootFolder?.FirstOrDefault(si =>
275-
si.Name?.Equals("My Drive") ?? false) as ShellLink)?.TargetPath
276-
?? string.Empty);
277-
278-
Debug.WriteLine("SHELL FOLDER LOGGING");
279-
rootFolder?.ForEach(si => Debug.WriteLine(si.Name));
280-
281-
if (!string.IsNullOrEmpty(myDriveFolder))
282-
{
283-
path = myDriveFolder;
284-
return true;
285-
}
286-
287-
path = Path.Combine(path, "My Drive");
288-
return ValidatePath(path);
28992
}
29093
}
29194
}

0 commit comments

Comments
 (0)