Skip to content

Commit

Permalink
AddMyDriveToPathAndValidate; is_my_drive
Browse files Browse the repository at this point in the history
Renamed `ValidatePath` to `AddMyDriveToPathAndValidate`, and made it also append
`My Drive' to the path it is given.

The only path we ever get from the media table is the drive letter (if `Google
Drive streaming location` is set to `Drive letter`, otherwise we get nothing
from the media table) followed by `:\`. As such, I added a call to
`AddMyDriveToPathAndValidate' on this path.

We only find paths in the roots table whose `is_my_drive` is true when `My Drive
syncing options` is set to Mirror files. I believe these paths are the ones Josh
was referring to when he said

> Google Drive set to mirror to a user selected folder will show both the
> redirect drive/folder (This show one My Drive folder) and another that goes
> directly to the store folder location.

The path we get from roots is the one that "goes directly to the store folder
location" (hence its `is_my_drive` is true).

With this PR, we now get the "redirect drive/folder" as well, from the registry.
As such, since Josh said

> Preferably it would only show the redirect drive/folder and add /My Drive to
> the path, then hide all other locations

I added a call to `AddMyDriveToPathAndValidate` on every path we get from the
registry, and I made the roots table read loop `continue` if it finds a path
whose `is_my_drive` is true.
  • Loading branch information
wharvex committed Jul 28, 2024
1 parent fa38634 commit d0d5c00
Showing 1 changed file with 31 additions and 16 deletions.
47 changes: 31 additions & 16 deletions src/Files.App/Utils/Cloud/Detector/GoogleDriveCloudDetector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ protected override async IAsyncEnumerable<ICloudProvider> GetProviders()
{

// TESTING
var rootsLogger = GetAltLogger("debugRoots");
var mediaLogger = GetAltLogger("debugMedia");
var yieldReturnLogger = GetAltLogger("debugYieldReturn");
var rootPrefTablesLogger = GetAltLogger("debugRootPrefTables");
var rootsLogger = GetAltLogger("debugRoots.log");
var mediaLogger = GetAltLogger("debugMedia.log");
var yieldReturnLogger = GetAltLogger("debugYieldReturn.log");
var rootPrefTablesLogger = GetAltLogger("debugRootPrefTables.log");
var invalidPathsLogger = GetAltLogger("debugInvalidPaths.log");

// Google Drive's sync database can be in a couple different locations. Go find it.
string appDataPath = UserDataPaths.GetDefault().LocalAppData;
Expand Down Expand Up @@ -64,6 +65,9 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
continue;
}

if ((long)reader["is_my_drive"] == 1)
continue;

// By default, the path will be prefixed with "\\?\" (unless another app has explicitly changed it).
// \\?\ indicates to Win32 that the filename may be longer than MAX_PATH (see MSDN).
// Parts of .NET (e.g. the File class) don't handle this very well, so remove this prefix.
Expand Down Expand Up @@ -97,6 +101,12 @@ await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(Path.Combine(a
if (string.IsNullOrWhiteSpace(path))
continue;

if (!AddMyDriveToPathAndValidate(ref path))
{
invalidPathsLogger.LogInformation("Validation failed for " + path + " (media)");
continue;
}

var folder = await StorageFolder.GetFolderFromPathAsync(path);
string title = reader["name"]?.ToString() ?? folder.Name;

Expand All @@ -122,7 +132,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", rootPrefTablesLogger);

await foreach (var provider in GetGoogleDriveProvidersFromRegistryAsync())
await foreach (var provider in GetGoogleDriveProvidersFromRegistryAsync(invalidPathsLogger))
{

// TESTING
Expand Down Expand Up @@ -207,7 +217,7 @@ private ILogger GetAltLogger(string filename)
return googleDriveRegValueJson;
}

private async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFromRegistryAsync()
private async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFromRegistryAsync(ILogger invalidPathsLogger)
{
var googleDriveRegValJson = GetGoogleDriveRegValJson();

Expand All @@ -218,7 +228,7 @@ private async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFromRegist
.RootElement.EnumerateObject()
.FirstOrDefault();

// A default JsonProperty struct has an "Undefined" Value.ValueKind and throws an
// 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)
{
Expand All @@ -233,18 +243,21 @@ private async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFromRegist
foreach (var item in googleDriveRegValJsonProperty.Value.EnumerateArray())
{
if (!item.TryGetProperty(_googleDriveRegValPropName, out var googleDriveRegValProp))
yield break;
continue;

if (!googleDriveRegValProp.TryGetProperty(_googleDriveRegValPropPropName,
out var googleDriveRegValPropProp))
yield break;
continue;

var path = googleDriveRegValPropProp.GetString();
if (path is null)
yield break;
continue;

if (!ValidatePath(ref path))
yield break;
if (!AddMyDriveToPathAndValidate(ref path))
{
invalidPathsLogger.LogInformation("Validation failed for " + path + " (media)");
continue;
}

App.AppModel.GoogleDrivePath = path;

Expand All @@ -271,11 +284,11 @@ private async IAsyncEnumerable<ICloudProvider> GetGoogleDriveProvidersFromRegist
return await FilesystemTasks.Wrap(() => StorageFile.GetFileFromPathAsync(iconPath).AsTask());
}

private bool ValidatePath(ref string path)
private bool AddMyDriveToPathAndValidate(ref string path)
{
// If Google Drive is mounted as a drive, `path' will just be the drive letter, and
// therefore needs to be reformatted as a valid path.

// If Google Drive is mounted as a drive, then the path found in the registry will be
// *just* the drive letter (e.g. just "G" as opposed to "G:\"), and therefore must be
// reformatted as a valid path.
if (path.Length == 1)
{
DriveInfo temp;
Expand All @@ -292,6 +305,8 @@ private bool ValidatePath(ref string path)
path = temp.RootDirectory.Name;
}

path = Path.Combine(path, "My Drive");

if (Directory.Exists(path))
return true;

Expand Down

0 comments on commit d0d5c00

Please sign in to comment.