From bdef3b949efea886de6fd4ed4ece4b1497ac96a9 Mon Sep 17 00:00:00 2001 From: Saravanan Date: Mon, 14 Jul 2025 11:33:09 +0530 Subject: [PATCH] OX Drive support. --- src/Files.App/Utils/Cloud/CloudProviders.cs | 4 +- .../Utils/Cloud/Detector/CloudDetector.cs | 1 + .../Cloud/Detector/OXDriveCloudDetector.cs | 80 +++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/Files.App/Utils/Cloud/Detector/OXDriveCloudDetector.cs diff --git a/src/Files.App/Utils/Cloud/CloudProviders.cs b/src/Files.App/Utils/Cloud/CloudProviders.cs index 89526ec02aaa..e708103929e0 100644 --- a/src/Files.App/Utils/Cloud/CloudProviders.cs +++ b/src/Files.App/Utils/Cloud/CloudProviders.cs @@ -49,6 +49,8 @@ public enum CloudProviders SyncDrive, - MagentaCloud + MagentaCloud, + + OXDrive } } diff --git a/src/Files.App/Utils/Cloud/Detector/CloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/CloudDetector.cs index 940eedcf61d7..ccb376c556f5 100644 --- a/src/Files.App/Utils/Cloud/Detector/CloudDetector.cs +++ b/src/Files.App/Utils/Cloud/Detector/CloudDetector.cs @@ -33,6 +33,7 @@ private static IEnumerable EnumerateDetectors() yield return new BoxCloudDetector(); yield return new GenericCloudDetector(); yield return new SynologyDriveCloudDetector(); + yield return new OXDriveCloudDetector(); } } } diff --git a/src/Files.App/Utils/Cloud/Detector/OXDriveCloudDetector.cs b/src/Files.App/Utils/Cloud/Detector/OXDriveCloudDetector.cs new file mode 100644 index 000000000000..b53fdfb15623 --- /dev/null +++ b/src/Files.App/Utils/Cloud/Detector/OXDriveCloudDetector.cs @@ -0,0 +1,80 @@ +// Copyright (c) Files Community +// Licensed under the MIT License. + +using Files.App.Utils.Cloud; +using Microsoft.Win32; +using System.IO; +using System.Text.Json; +using Windows.Storage; +using static Vanara.PInvoke.Gdi32; + +namespace Files.App.Utils.Cloud +{ + /// + /// Provides an utility for OX Drive Cloud detection. + /// + public sealed class OXDriveCloudDetector : AbstractCloudDetector + { + protected override async IAsyncEnumerable GetProviders() + { + var syncFolder = await GetOXDriveSyncFolder(); + if (!string.IsNullOrEmpty(syncFolder)) + { + var iconFile = GetOXDriveIconFile(); + yield return new CloudProvider(CloudProviders.OXDrive) + { + Name = "OX Drive", + SyncFolder = syncFolder, + IconData = iconFile?.IconData + }; + } + } + public static async Task GetOXDriveSyncFolder() + { + var jsonPath = Path.Combine(UserDataPaths.GetDefault().LocalAppData, "Open-Xchange", "OXDrive", "userConfig.json"); + if (!File.Exists(jsonPath)) + return null; + + var configFile = await StorageFile.GetFileFromPathAsync(jsonPath); + using var jsonDoc = JsonDocument.Parse(await FileIO.ReadTextAsync(configFile)); + var jsonElem = jsonDoc.RootElement; + + string? syncFolderPath = null; + + if (jsonElem.TryGetProperty("Accounts", out var accounts) && accounts.GetArrayLength() > 0) + { + var account = accounts[0]; + + if (account.TryGetProperty("MainFolderPath", out var folderPathElem)) + syncFolderPath = folderPathElem.GetString(); + } + + return syncFolderPath; + } + + private static IconFileInfo? GetOXDriveIconFile() + { + var installPath = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Open-Xchange\OXDrive", "InstallDir", null) as string; + + // Fallback to default known path if not found in the registry. + if (string.IsNullOrEmpty(installPath)) + { + var pfX86 = Environment.GetEnvironmentVariable("ProgramFiles(x86)"); + if (string.IsNullOrEmpty(pfX86)) + return null; + + installPath = Path.Combine(pfX86, "Open-Xchange", "OXDrive"); + } + + var oxDriveFilePath = Path.Combine(installPath, "OXDrive.exe"); + if (!File.Exists(oxDriveFilePath)) + { + return null; + } + + // Extract the icon from the OXDrive executable (though it is executable, it contains icons) + var icons = Win32Helper.ExtractSelectedIconsFromDLL(oxDriveFilePath, new List { 0 }, 32); + return icons.FirstOrDefault(); + } + } +}