diff --git a/src/Files.App.CsWin32/Windows.Win32.ComHeapPtr.cs b/src/Files.App.CsWin32/ComHeapPtr`1.cs
similarity index 100%
rename from src/Files.App.CsWin32/Windows.Win32.ComHeapPtr.cs
rename to src/Files.App.CsWin32/ComHeapPtr`1.cs
diff --git a/src/Files.App.CsWin32/Windows.Win32.ComPtr.cs b/src/Files.App.CsWin32/ComPtr`1.cs
similarity index 100%
rename from src/Files.App.CsWin32/Windows.Win32.ComPtr.cs
rename to src/Files.App.CsWin32/ComPtr`1.cs
diff --git a/src/Files.App.CsWin32/Windows.Win32.Extras.cs b/src/Files.App.CsWin32/Extras.cs
similarity index 100%
rename from src/Files.App.CsWin32/Windows.Win32.Extras.cs
rename to src/Files.App.CsWin32/Extras.cs
diff --git a/src/Files.App.CsWin32/HRESULT.Extensions.cs b/src/Files.App.CsWin32/HRESULT.Extensions.cs
new file mode 100644
index 000000000000..8d8315526d71
--- /dev/null
+++ b/src/Files.App.CsWin32/HRESULT.Extensions.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32
+{
+ public static class HRESULTExtensions
+ {
+ ///
+ /// Throws an exception if the indicates a failure in debug mode. Otherwise, it returns the original .
+ ///
+ /// Represents the result of an operation, indicating success or failure.
+ /// Returns the original value regardless of the operation's success.
+ public static HRESULT ThrowIfFailedOnDebug(this HRESULT hr)
+ {
+#if DEBUG
+ if (hr.Failed)
+ Marshal.ThrowExceptionForHR(hr.Value);
+#endif
+
+ return hr;
+ }
+ }
+}
diff --git a/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs b/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs
new file mode 100644
index 000000000000..3e28cfcabded
--- /dev/null
+++ b/src/Files.App.CsWin32/IStorageProviderQuotaUI.cs
@@ -0,0 +1,47 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.System.WinRT
+{
+ public unsafe struct IStorageProviderQuotaUI : IComIID
+ {
+ private void** lpVtbl;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public HRESULT GetQuotaTotalInBytes(ulong* value)
+ {
+ return ((delegate* unmanaged[Stdcall])(lpVtbl[6]))((IStorageProviderQuotaUI*)Unsafe.AsPointer(ref this), value);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public HRESULT GetQuotaUsedInBytes(ulong* value)
+ {
+ return ((delegate* unmanaged[Stdcall])(lpVtbl[8]))((IStorageProviderQuotaUI*)Unsafe.AsPointer(ref this), value);
+ }
+
+ public static ref readonly Guid Guid
+ {
+ get
+ {
+ // BA6295C3-312E-544F-9FD5-1F81B21F3649
+ ReadOnlySpan data =
+ [
+ 0xC3, 0x95, 0x62, 0xBA,
+ 0x2E, 0x31,
+ 0x4F, 0x54,
+ 0x9F, 0xD5,
+ 0x1F, 0x81, 0xB2, 0x1F, 0x36, 0x49
+ ];
+
+ Debug.Assert(data.Length == sizeof(Guid));
+ return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
+ }
+ }
+ }
+}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUI.cs b/src/Files.App.CsWin32/IStorageProviderStatusUI.cs
new file mode 100644
index 000000000000..ab7bdcc050d4
--- /dev/null
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUI.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.System.WinRT
+{
+ public unsafe struct IStorageProviderStatusUI : IComIID
+ {
+ private void** lpVtbl;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public HRESULT GetQuotaUI(IStorageProviderQuotaUI** result)
+ {
+ return ((delegate* unmanaged[Stdcall])lpVtbl[14])((IStorageProviderStatusUI*)Unsafe.AsPointer(ref this), result);
+ }
+
+ public static ref readonly Guid Guid
+ {
+ get
+ {
+ // d6b6a758-198d-5b80-977f-5ff73da33118
+ ReadOnlySpan data =
+ [
+ 0x58, 0xa7, 0xb6, 0xd6,
+ 0x8d, 0x19,
+ 0x80, 0x5b,
+ 0x97, 0x7f,
+ 0x5f, 0xf7, 0x3d, 0xa3, 0x31, 0x18
+ ];
+
+ Debug.Assert(data.Length == sizeof(Guid));
+ return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
+ }
+ }
+ }
+}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs b/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs
new file mode 100644
index 000000000000..b7d80b4efb8f
--- /dev/null
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUISource.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.System.WinRT
+{
+ public unsafe struct IStorageProviderStatusUISource : IComIID
+ {
+ private void** lpVtbl;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public HRESULT GetStatusUI(IStorageProviderStatusUI** result)
+ {
+ return ((delegate* unmanaged[Stdcall])lpVtbl[6])((IStorageProviderStatusUISource*)Unsafe.AsPointer(ref this), result);
+ }
+
+ public static ref readonly Guid Guid
+ {
+ get
+ {
+ // A306C249-3D66-5E70-9007-E43DF96051FF
+ ReadOnlySpan data =
+ [
+ 0x49, 0xc2, 0x06, 0xa3,
+ 0x66, 0x3d,
+ 0x70, 0x5e,
+ 0x90, 0x07,
+ 0xe4, 0x3d, 0xf9, 0x60, 0x51, 0xff
+ ];
+
+ Debug.Assert(data.Length == sizeof(Guid));
+ return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
+ }
+ }
+ }
+}
diff --git a/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs b/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs
new file mode 100644
index 000000000000..4927fa32577e
--- /dev/null
+++ b/src/Files.App.CsWin32/IStorageProviderStatusUISourceFactory.cs
@@ -0,0 +1,41 @@
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using System;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using Windows.Win32.Foundation;
+
+namespace Windows.Win32.System.WinRT
+{
+ public unsafe struct IStorageProviderStatusUISourceFactory : IComIID
+ {
+ private void** lpVtbl;
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public HRESULT GetStatusUISource(nint syncRootId, IStorageProviderStatusUISource** result)
+ {
+ return ((delegate* unmanaged[Stdcall])lpVtbl[6])((IStorageProviderStatusUISourceFactory*)Unsafe.AsPointer(ref this), syncRootId, result);
+ }
+
+ public static ref readonly Guid Guid
+ {
+ get
+ {
+ // 12E46B74-4E5A-58D1-A62F-0376E8EE7DD8
+ ReadOnlySpan data =
+ [
+ 0x74, 0x6b, 0xe4, 0x12,
+ 0x5a, 0x4e,
+ 0xd1, 0x58,
+ 0xa6, 0x2f,
+ 0x03, 0x76, 0xe8, 0xee, 0x7d, 0xd8
+ ];
+
+ Debug.Assert(data.Length == sizeof(Guid));
+ return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
+ }
+ }
+ }
+}
diff --git a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
index 16b17c2b5ca3..e013316b9b34 100644
--- a/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
+++ b/src/Files.App/Utils/Storage/Helpers/SyncRootHelpers.cs
@@ -1,144 +1,62 @@
-using Microsoft.Win32;
+// Copyright (c) Files Community
+// Licensed under the MIT License.
+
+using Microsoft.Win32;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using Windows.Storage.Provider;
using Windows.Win32;
using Windows.Win32.Foundation;
+using Windows.Win32.System.Com;
+using Windows.Win32.System.WinRT;
using WinRT;
namespace Files.App.Utils.Storage
{
internal static class SyncRootHelpers
{
- private unsafe struct IStorageProviderStatusUISourceFactory : IComIID
- {
- private void** vtbl;
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public HRESULT GetStatusUISource(nint syncRootId, IStorageProviderStatusUISource** result)
- {
- return ((delegate* unmanaged[Stdcall])vtbl[6])((IStorageProviderStatusUISourceFactory*)Unsafe.AsPointer(ref this), syncRootId, result);
- }
-
- public static ref readonly Guid Guid
- {
- get
- {
- // 12e46b74-4e5a-58d1-a62f-0376e8ee7dd8
- ReadOnlySpan data = new byte[]
- {
- 0x74, 0x6b, 0xe4, 0x12,
- 0x5a, 0x4e,
- 0xd1, 0x58,
- 0xa6, 0x2f,
- 0x03, 0x76, 0xe8, 0xee, 0x7d, 0xd8
- };
- Debug.Assert(data.Length == sizeof(Guid));
- return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
- }
- }
- }
-
- private unsafe struct IStorageProviderStatusUISource : IComIID
- {
- private void** vtbl;
-
- public HRESULT GetStatusUI(IStorageProviderStatusUI** result)
- {
- return ((delegate* unmanaged[Stdcall])vtbl[6])((IStorageProviderStatusUISource*)Unsafe.AsPointer(ref this), result);
- }
-
- public static ref readonly Guid Guid
- {
- get
- {
- // a306c249-3d66-5e70-9007-e43df96051ff
- ReadOnlySpan data = new byte[]
- {
- 0x49, 0xc2, 0x06, 0xa3,
- 0x66, 0x3d,
- 0x70, 0x5e,
- 0x90, 0x07,
- 0xe4, 0x3d, 0xf9, 0x60, 0x51, 0xff
- };
- Debug.Assert(data.Length == sizeof(Guid));
- return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
- }
- }
- }
-
- private unsafe struct IStorageProviderStatusUI : IComIID
- {
- public static ref readonly Guid Guid
- {
- get
- {
- // d6b6a758-198d-5b80-977f-5ff73da33118
- ReadOnlySpan data = new byte[]
- {
- 0x58, 0xa7, 0xb6, 0xd6,
- 0x8d, 0x19,
- 0x80, 0x5b,
- 0x97, 0x7f,
- 0x5f, 0xf7, 0x3d, 0xa3, 0x31, 0x18
- };
- Debug.Assert(data.Length == sizeof(Guid));
- return ref Unsafe.As(ref MemoryMarshal.GetReference(data));
- }
- }
- }
-
private static unsafe (bool Success, ulong Capacity, ulong Used) GetSyncRootQuotaFromSyncRootId(string syncRootId)
{
- RegistryKey? key;
- if ((key = Registry.LocalMachine.OpenSubKey($"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SyncRootManager\\{syncRootId}")) is null)
- {
+ using var key = Registry.LocalMachine.OpenSubKey($"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SyncRootManager\\{syncRootId}");
+ if (key?.GetValue("StorageProviderStatusUISourceFactory") is not string factoryClsidString ||
+ !Guid.TryParse(factoryClsidString, out var factoryClsid))
return (false, 0, 0);
- }
- using (key)
- {
- if (key.GetValue("StorageProviderStatusUISourceFactory") is string statusUIclass)
- {
- StorageProviderStatusUI statusUI;
- using (ComPtr sourceFactoryNative = default)
- {
- Guid statusUIclassGuid = Guid.Parse(statusUIclass);
- if (PInvoke.CoCreateInstance(&statusUIclassGuid, null, Windows.Win32.System.Com.CLSCTX.CLSCTX_LOCAL_SERVER, (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IStorageProviderStatusUISourceFactory.Guid)), (void**)sourceFactoryNative.GetAddressOf()) != 0)
- {
- return (false, 0, 0);
- }
+ HRESULT hr = default;
+ ulong ulTotalSize = 0ul, ulUsedSize = 0ul;
+ using ComPtr pStorageProviderStatusUISourceFactory = default;
+ using ComPtr pStorageProviderStatusUISource = default;
+ using ComPtr pStorageProviderStatusUI = default;
+ using ComPtr pStorageProviderQuotaUI = default;
- MarshalString.Pinnable syncRootIdHstring = new(syncRootId);
- fixed (char* ptr = syncRootIdHstring)
- using (ComPtr sourceNative = default)
- {
- ExceptionHelpers.ThrowExceptionForHR(sourceFactoryNative.Get()->GetStatusUISource(syncRootIdHstring.GetAbi(), sourceNative.GetAddressOf()));
+ if (PInvoke.CoCreateInstance(
+ &factoryClsid,
+ null,
+ CLSCTX.CLSCTX_LOCAL_SERVER,
+ (Guid*)Unsafe.AsPointer(ref Unsafe.AsRef(in IStorageProviderStatusUISourceFactory.Guid)),
+ (void**)pStorageProviderStatusUISourceFactory.GetAddressOf()).ThrowIfFailedOnDebug().Failed)
+ return (false, 0, 0);
- using (ComPtr statusNative = default)
- {
- ExceptionHelpers.ThrowExceptionForHR(sourceNative.Get()->GetStatusUI(statusNative.GetAddressOf()));
- statusUI = StorageProviderStatusUI.FromAbi((nint)statusNative.Get());
- }
- }
- }
- return (true, statusUI.QuotaUI.QuotaTotalInBytes, statusUI.QuotaUI.QuotaUsedInBytes);
- }
- else
- {
+ var syncRootIdHString = new MarshalString.Pinnable(syncRootId);
+ fixed (char* pSyncRootIdHString = syncRootIdHString)
+ {
+ if (pStorageProviderStatusUISourceFactory.Get()->GetStatusUISource(syncRootIdHString.GetAbi(), pStorageProviderStatusUISource.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
+ pStorageProviderStatusUISource.Get()->GetStatusUI(pStorageProviderStatusUI.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
+ pStorageProviderStatusUI.Get()->GetQuotaUI(pStorageProviderQuotaUI.GetAddressOf()).ThrowIfFailedOnDebug().Failed ||
+ pStorageProviderQuotaUI.Get()->GetQuotaTotalInBytes(&ulTotalSize).ThrowIfFailedOnDebug().Failed ||
+ pStorageProviderQuotaUI.Get()->GetQuotaUsedInBytes(&ulUsedSize).ThrowIfFailedOnDebug().Failed)
return (false, 0, 0);
- }
}
+
+ return (true, ulTotalSize, ulUsedSize);
}
public static async Task<(bool Success, ulong Capacity, ulong Used)> GetSyncRootQuotaAsync(string path)
{
Windows.Storage.StorageFolder folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(path);
- StorageProviderSyncRootInfo? syncRootInfo = null;
+ Windows.Storage.Provider.StorageProviderSyncRootInfo? syncRootInfo = null;
try
{
- syncRootInfo = StorageProviderSyncRootManager.GetSyncRootInformationForFolder(folder);
+ syncRootInfo = Windows.Storage.Provider.StorageProviderSyncRootManager.GetSyncRootInformationForFolder(folder);
}
catch
{