Repository navigation
fix: uninstall apps from any drive, and let Cancel stop the leftover search - #3152
Merged
Merged
Conversation
…search Closes #2783. UninstallerService started a local uninstaller only from Program Files, the Windows folder, ProgramData or Local AppData. Uninstalling runs only at standard integrity, so the list protected nothing and refused apps on another drive or under Roaming AppData. LocalExecutable now takes any .exe on this PC's drives and still refuses relative and network paths. Shell metacharacters are checked in a quoted path's arguments only, and CannotStart words every refusal with Windows Settings > Apps. The leftover search and removal were given no token, so Cancel stopped neither. Each gets a source of its own; a stopped search shows what it found, and RemoveAsync returns what it removed, marked Stopped.
| // A source of its own, which Cancel reaches: the batch's may be cancelled already, and measuring a | ||
| // large folder can keep the search going for a while. It was given no token, so Cancel showed and | ||
| // stopped nothing (#2783). | ||
| _cts.Dispose(); |
Auto-release tags only when the newest entry carries today's UTC date.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #2783, with both points from its comment.
What changes for a user
D:\Games, or under Roaming AppData as some per-user installers put theirs, showed "outside trusted directories" and stayed. Uninstalling runs only while SysManager is not elevated, so the uninstaller gets the user's own rights, the same as when Windows Settings runs the same entry. The folder list protected nothing: Local AppData was on it, and a user can write there like anywhere else. Any.exeon this PC's drives is started now.∨in the command refused it. The quoted path is the file the shell starts, and no command interpreter reads it, so only the arguments are checked now. On this PC, 1 of 292 uninstall commands has one of those characters.How
UninstallerService.LocalExecutablereplaces the folder check. It refuses a path that is not fully qualified, a path whose root is not a drive letter (a share or a\\?\path, refused before any file lookup, so a network path is never reached), and anything but an.exe.EnsureStandardIntegritystill stops every uninstall while SysManager is elevated, which is why the folder does not matter.ParseUninstallCommandruns the shell metacharacter check on a quoted path's arguments only. Every other form is still checked whole before it is parsed (fix: security hardening batch 2 — cache validation, zip slip, DLL hijack, parser hardening #403).AppAlertService.FoldersOfandLeftoverFindershare the parser, so they now also read the folder of an uninstaller with&in its path.CannotStart(why)builds every refusal, fromLocalExecutable, the parser, and the rundll32 and MsiExec checks. The rundll32 DLL keeps its folder rule: rundll32 loads whatever file it is named, and all 5 rundll32 uninstall commands on this PC load from those folders.UninstallerViewModelgives the leftover search and the removal each a newCancellationTokenSource. The search after a cancelled batch still runs for the apps that were removed.ShowLeftoversAsyncstops at the cancel and shows what it found, andDescribeFindingssays the search was stopped.LeftoverService.RemoveAsyncchecks the token between items and returns aLeftoverRemovalmarkedStoppedinstead of throwing; before, a throw would have lost the list of what had already gone to the Recycle Bin. The token is not passed toTask.Run, so a removal cancelled before it starts still returns.Tests
D:andE:and under Roaming AppData are accepted. A share, a\\?\path, a.bat, a relative path and a drive-relative path are refused without a file lookup. A missing file says the app may be gone already. Six kinds of refusal throughUninstallLocalAsyncstart with Windows Settings ▸ Apps, and none says "refusing". Quoted paths with∧parse, and chaining in the arguments is still refused.RemoveAsyncstops before its next item with the first already recycled, and one cancelled before it starts removes nothing. Both reportStopped.Red before the fix, by mutation, each file restored byte for byte afterwards:
RemoveAsyncthrowing on cancel, or with the token passed toTask.Run: 1 fails each.Checks
dotnet format --verify-no-changesis clean.UninstallerService,LeftoverService,UninstallerViewModel) are in this pull request.