Skip to content

Commit 6d15b0c

Browse files
Feature: Prevent setting cloud placeholder files as lock screen wallpaper
1 parent 9fe7b3b commit 6d15b0c

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

src/Files.App/Services/Windows/WindowsWallpaperService.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
// Copyright (c) Files Community
22
// Licensed under the MIT License.
33

4+
using System.IO;
5+
using Vanara.PInvoke;
6+
using Vanara.Windows.Shell;
47
using Windows.Storage;
58
using Windows.System.UserProfile;
69
using Windows.Win32;
@@ -13,6 +16,8 @@ namespace Files.App.Services
1316
/// <inheritdoc cref="IWindowsWallpaperService"/>
1417
public sealed class WindowsWallpaperService : IWindowsWallpaperService
1518
{
19+
private static readonly Ole32.PROPERTYKEY PKEY_FilePlaceholderStatus = new Ole32.PROPERTYKEY(new Guid("B2F9B9D6-FEC4-4DD5-94D7-8957488C807B"), 2);
20+
private const uint PS_CLOUDFILE_PLACEHOLDER = 8;
1621
/// <inheritdoc/>
1722
public unsafe void SetDesktopWallpaper(string szPath)
1823
{
@@ -69,8 +74,38 @@ public unsafe void SetDesktopSlideshow(string[] aszPaths)
6974
/// <inheritdoc/>
7075
public async Task SetLockScreenWallpaper(string szPath)
7176
{
77+
// Verify the file exists on disk
78+
if (!File.Exists(szPath))
79+
throw new FileNotFoundException("The specified file does not exist.", szPath);
80+
81+
// Check if the file is a cloud placeholder (online-only file)
82+
if (IsCloudPlaceholder(szPath))
83+
throw new InvalidOperationException("The file is stored in the cloud and is not available offline. Please download the file before setting it as a wallpaper.");
84+
7285
IStorageFile sourceFile = await StorageFile.GetFileFromPathAsync(szPath);
7386
await LockScreen.SetImageFileAsync(sourceFile);
7487
}
88+
89+
/// <summary>
90+
/// Checks if the file is a cloud placeholder (online-only file).
91+
/// </summary>
92+
/// <param name="path">The path to the file.</param>
93+
/// <returns>True if the file is a cloud placeholder; otherwise, false.</returns>
94+
private static bool IsCloudPlaceholder(string path)
95+
{
96+
try
97+
{
98+
using var shi = new ShellItem(path);
99+
if (shi.Properties.TryGetValue<uint>(PKEY_FilePlaceholderStatus, out var value) && value == PS_CLOUDFILE_PLACEHOLDER)
100+
return true;
101+
}
102+
catch
103+
{
104+
// If we can't determine the placeholder status, assume it's not a placeholder
105+
// and let the subsequent StorageFile.GetFileFromPathAsync call handle any errors
106+
}
107+
108+
return false;
109+
}
75110
}
76111
}

0 commit comments

Comments
 (0)