Files
PowerToys/src/modules/Workspaces/WorkspacesCsharpLibrary/Utils/FolderUtils.cs
Boliang Zhang (from Dev Box) 5a931f9d24 Workspaces v6: route the WPF Editor read/write through the settings service
This is the core integration that makes the EoP protection actually take effect:
the Editor now persists settings through PTSettingsSvc instead of writing
workspaces.json directly into the protected folder (which would be denied for a
non-elevated user).

WorkspacesEditorIO:
- ParseWorkspaces (read): GetBlob -> WorkspacesData.Deserialize, using the SAME
  serializer/format as before (native Launcher stays compatible). NotFound ->
  empty; Unavailable -> legacy %LocalAppData% file fallback (no-admin only, §10).
- SerializeWorkspaces (write): WorkspacesData.Serialize -> PutBlob; Unavailable ->
  legacy file fallback. The transient snapshot->editor temp file stays direct IO.
- Fires SettingsBootstrapper.EnsureInitialized at editor open (the per-user
  deferred-init / migration trigger the design called for).

FolderUtils.DataFolder() reverted to the user-writable %LocalAppData% working
folder. v6 had repointed it at the protected %ProgramData% store, which also
broke the Editor's icons and temp-project handoff (those need to stay
user-writable). The protected store is reached only through the service now.

Verified locally (harness compiling the real source files, run as an
allow-listed PowerToys.WorkspacesEditor.exe against the dev service) — 8/8:
Serialize->PutBlob Ok, GetBlob->Deserialize round-trips, dash-case JSON lands in
the protected %ProgramData%\\...\\blob.bin (owner NT SERVICE\\PTSettingsSvc,
user RX), non-elevated write+delete rejected.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-29 00:05:06 +08:00

42 lines
1.5 KiB
C#

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
namespace WorkspacesCsharpLibrary.Utils;
public class FolderUtils
{
public static string Desktop()
{
return Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
}
public static string Temp()
{
return Path.GetTempPath();
}
// User-writable working folder for the Editor's transient files (icons,
// temp-project handoff) AND the legacy / no-service fallback store.
//
// v6 note: the *protected* settings store does NOT live here — it is the
// service-managed blob under %ProgramData% (see SettingsPaths / §9). The
// Editor reads/writes the real settings through PTSettingsClient
// (GetBlob / PutBlob); this %LocalAppData% path is only the working dir and
// the no-service fallback, both of which must stay user-writable.
public static string DataFolder()
{
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Microsoft\\PowerToys\\Workspaces";
}
// The pre-v6 location. Same as DataFolder() now; kept as a distinct name
// for the one-shot migration source and the no-service fallback.
public static string LegacyDataFolder()
{
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Microsoft\\PowerToys\\Workspaces";
}
}