From 7d0b8b8a89b4cce032d8aa827d7cbebd844f263d Mon Sep 17 00:00:00 2001 From: Gordon Lam Date: Sun, 21 Jun 2026 10:43:13 +0800 Subject: [PATCH 1/4] Mouse Without Borders: create received files in the logged-on user's context When the service runs elevated, the destination folder for an incoming clipboard/file transfer is created while impersonating the logged-on user, but the file itself was created outside that context. This makes the resulting file ownership/permissions inconsistent with the folder. Create the file in the same impersonated context as its folder so it is owned by the logged-on user and inherits the folder's permissions. On the logon/screen-saver desktop the storage lives under Program Files where there is no interactive user to impersonate, so the file is still created directly to preserve existing behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../MouseWithoutBorders/App/Core/Clipboard.cs | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs index db16ac8b4d2d..4255914299ab 100644 --- a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs +++ b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs @@ -574,8 +574,30 @@ internal static void ReceiveAndProcessClipboardData(string remoteMachine, Socket } else { + // Create received files in the same context that the destination folder is created + // in. For per-user storage (the user's Desktop) that means as the logged-on user, so + // the file ends up owned by that user and inherits the folder's permissions. On the + // logon/screen-saver desktop the storage lives under Program Files where there is no + // interactive user to impersonate, so create the file directly. + void CreateDestinationFile(string path) + { + if (Common.RunOnLogonDesktop || Common.RunOnScrSaverDesktop) + { + m = new FileStream(path, FileMode.Create); + } + else + { + _ = Launch.ImpersonateLoggedOnUserAndDoSomething(() => + { + m = new FileStream(path, FileMode.Create); + }); + } + } + if (postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase)) { + // Create the folder and open the file in a single impersonated scope so both + // are owned by the logged-on user. This branch always targets the user's Desktop. _ = Launch.ImpersonateLoggedOnUserAndDoSomething(() => { savingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\MouseWithoutBorders\\"; @@ -584,22 +606,22 @@ internal static void ReceiveAndProcessClipboardData(string remoteMachine, Socket { _ = Directory.CreateDirectory(savingFolder); } - }); - tempFile = savingFolder + Path.GetFileName(fileName); - m = new FileStream(tempFile, FileMode.Create); + tempFile = savingFolder + Path.GetFileName(fileName); + m = new FileStream(tempFile, FileMode.Create); + }); } else if (postAct.Contains("mspaint")) { tempFile = Common.GetMyStorageDir() + @"ScreenCapture-" + remoteMachine + ".png"; - m = new FileStream(tempFile, FileMode.Create); + CreateDestinationFile(tempFile); } else { tempFile = Common.GetMyStorageDir(); tempFile += Path.GetFileName(fileName); - m = new FileStream(tempFile, FileMode.Create); + CreateDestinationFile(tempFile); } Logger.Log("==> " + tempFile); From db9fdc2ade040cd4db8098adc838fe5c86068d40 Mon Sep 17 00:00:00 2001 From: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:37:51 +0800 Subject: [PATCH 2/4] Update src/modules/MouseWithoutBorders/App/Core/Clipboard.cs --- src/modules/MouseWithoutBorders/App/Core/Clipboard.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs index 4255914299ab..4f691db0e5d8 100644 --- a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs +++ b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs @@ -587,10 +587,16 @@ void CreateDestinationFile(string path) } else { - _ = Launch.ImpersonateLoggedOnUserAndDoSomething(() => + bool success = Launch.ImpersonateLoggedOnUserAndDoSomething(() => { m = new FileStream(path, FileMode.Create); }); + + if (!success || m == null) + { + Logger.Log("Impersonation failed for file creation, falling back to direct creation."); + m = new FileStream(path, FileMode.Create); + } } } From 51f9f74774e86f58ca1753f1f8644cce530bb6e9 Mon Sep 17 00:00:00 2001 From: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> Date: Mon, 22 Jun 2026 16:38:01 +0800 Subject: [PATCH 3/4] Update src/modules/MouseWithoutBorders/App/Core/Clipboard.cs --- .../MouseWithoutBorders/App/Core/Clipboard.cs | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs index 4f691db0e5d8..1631ee19e65d 100644 --- a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs +++ b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs @@ -600,11 +600,9 @@ void CreateDestinationFile(string path) } } - if (postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase)) - { // Create the folder and open the file in a single impersonated scope so both // are owned by the logged-on user. This branch always targets the user's Desktop. - _ = Launch.ImpersonateLoggedOnUserAndDoSomething(() => + bool success = Launch.ImpersonateLoggedOnUserAndDoSomething(() => { savingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\MouseWithoutBorders\\"; @@ -616,6 +614,19 @@ void CreateDestinationFile(string path) tempFile = savingFolder + Path.GetFileName(fileName); m = new FileStream(tempFile, FileMode.Create); }); + + if (!success || m == null) + { + Logger.Log("Impersonation failed for desktop file creation, falling back to direct creation."); + savingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\MouseWithoutBorders\\"; + if (!Directory.Exists(savingFolder)) + { + _ = Directory.CreateDirectory(savingFolder); + } + + tempFile = savingFolder + Path.GetFileName(fileName); + m = new FileStream(tempFile, FileMode.Create); + } } else if (postAct.Contains("mspaint")) { From 79c01b50904510c22b26801668ae5ae120c5d667 Mon Sep 17 00:00:00 2001 From: Muyuan Li <116717757+MuyuanMS@users.noreply.github.com> Date: Tue, 23 Jun 2026 10:49:09 +0800 Subject: [PATCH 4/4] Update src/modules/MouseWithoutBorders/App/Core/Clipboard.cs --- src/modules/MouseWithoutBorders/App/Core/Clipboard.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs index 1631ee19e65d..74f47be98456 100644 --- a/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs +++ b/src/modules/MouseWithoutBorders/App/Core/Clipboard.cs @@ -600,6 +600,8 @@ void CreateDestinationFile(string path) } } + if (postAct.Equals("desktop", StringComparison.OrdinalIgnoreCase)) + { // Create the folder and open the file in a single impersonated scope so both // are owned by the logged-on user. This branch always targets the user's Desktop. bool success = Launch.ImpersonateLoggedOnUserAndDoSomething(() =>