Skip to content

fix(update): embed asInvoker manifest in uffs-update.exe (Windows elevation)#454

Merged
githubrobbi merged 2 commits into
mainfrom
fix/uffs-update-asinvoker-manifest
Jun 18, 2026
Merged

fix(update): embed asInvoker manifest in uffs-update.exe (Windows elevation)#454
githubrobbi merged 2 commits into
mainfrom
fix/uffs-update-asinvoker-manifest

Conversation

@githubrobbi

Copy link
Copy Markdown
Collaborator

On Windows, every uffs --update operation (doctor/acquire/apply) fails immediately:

Error: spawning C:\Users\…\bin\uffs-update.exe
  Caused by: The requested operation requires elevation. (os error 740)

Cause

os error 740 = ERROR_ELEVATION_REQUIRED. Windows' Installer Detection heuristic auto-flags executables whose name contains update/setup/install/patch as installers that require UAC — unless the binary carries an application manifest opting out. uffs.exe already ships an asInvoker manifest (so it's exempt); uffs-update.exe had no manifest at all, so the heuristic force-elevated it, and the non-elevated uffs.exe couldn't CreateProcess it.

Fix

Mirror what uffs.exe already does:

  • crates/uffs-update/app.manifestrequestedExecutionLevel level="asInvoker" (+ longPathAware).
  • crates/uffs-update/build.rs — embeds it into the PE on windows-msvc via winresource (inert on other targets).
  • winresource added to [build-dependencies].

asInvoker is correct: the helper only rewrites files in the user's own install dir; it never needs Administrator.

Verification

  • Built x86_64-pc-windows-msvc/uffs-update.exe now contains requestedExecutionLevel level="asInvoker" (grepped the PE).
  • Host + Windows-MSVC clippy clean; uffs-update tests pass (46).

Together with #452 (Unix exec-bit), this makes uffs --update work on all three platforms.

🤖 Generated with Claude Code

…vation)

On Windows every `uffs --update` op (doctor/acquire/apply) failed at
"spawning uffs-update.exe → The requested operation requires elevation
(os error 740)". Cause: Windows Installer Detection auto-flags executables
whose NAME contains update/setup/install/patch as installers needing UAC —
and uffs-update.exe had no application manifest to opt out. So the
non-elevated uffs.exe couldn't launch it.

Fix: give uffs-update the same treatment uffs.exe already has — an
app.manifest declaring `requestedExecutionLevel level="asInvoker"` (plus
longPathAware), embedded into the PE on Windows MSVC via a winresource
build.rs. asInvoker is correct: the helper only rewrites files in the user's
own install dir and never needs Administrator. Inert on non-Windows.

Verified: the built windows-msvc uffs-update.exe carries
`requestedExecutionLevel level="asInvoker"`. Host + Windows-MSVC clippy clean;
uffs-update tests pass (46).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@githubrobbi githubrobbi enabled auto-merge (squash) June 18, 2026 00:32
…edge

The asInvoker-manifest commit added winresource as a uffs-update
build-dependency but didn't record the lockfile edge, so CI's
`cargo fetch --locked` rejected the stale Cargo.lock. winresource was already
in the graph (uffs-cli uses it), so no new crate — just the edge.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@githubrobbi githubrobbi merged commit d1e0c53 into main Jun 18, 2026
28 checks passed
@githubrobbi githubrobbi deleted the fix/uffs-update-asinvoker-manifest branch June 18, 2026 00:50
githubrobbi added a commit that referenced this pull request Jun 18, 2026
…xS crash (os error 14001) (#456)

The asInvoker manifest added in #454 (to defeat Installer Detection / os
error 740) made the cross-compiled uffs-update.exe fail to *start at all*
on Windows with ERROR_SXS_CANT_GEN_ACTCTX (os error 14001, "side-by-side
configuration is incorrect"). Every invocation died, including the
apply-phase smoke test (`uffs-update --version`), so `uffs --update`
rolled back with "smoke test failed for uffs-update".

Root cause: the richer manifest carried `<assemblyIdentity>` (plus a
`<compatibility>` supportedOS block and `<windowsSettings>`).
`<assemblyIdentity>` in an application manifest makes the loader attempt a
side-by-side assembly resolution that fails for a plain console binary —
ERROR_SXS_CANT_GEN_ACTCTX.

Fix: strip the manifest to the single thing this helper needs — a
`trustInfo`/`asInvoker` block — removing every SxS activation-context
surface. This keeps the #454 740-fix (asInvoker still defeats Installer
Detection) while eliminating the 14001 crash.

Verified by cross-compiling (cargo xwin) and inspecting the embedded PE
manifest: `requestedExecutionLevel level="asInvoker"` present; zero real
`<assemblyIdentity type=>` / `<supportedOS Id=>` elements.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
githubrobbi added a commit that referenced this pull request Jun 18, 2026
…S 14001 cause (#457)

The actual root cause of uffs-update.exe failing to start with
ERROR_SXS_CANT_GEN_ACTCTX (os error 14001, "Invalid Xml syntax ... on
line 1") was a literal double hyphen inside the manifest's XML comment:
the comment body contained the example CLI invocation `uffs --update`,
and XML forbids "--" anywhere inside a <!-- --> comment. Windows' strict
side-by-side manifest parser rejected the whole manifest.

This was present in BOTH the original #454 manifest and the #456
"minimal" rewrite — both carried that same `uffs --update` line in the
comment — which is why #456 (dropping <assemblyIdentity>) did not fix it.
The Application event log (SideBySide id 59) pinpointed it: "Error in
manifest or policy file ... on line 1. Invalid Xml syntax."

Fix: reword the comment so no "--" appears in the body, and add an
explicit DO-NOT-USE-double-hyphen warning so this never regresses.

Verified by extracting the embedded RT_MANIFEST from a freshly
cross-compiled uffs-update.exe and running `xmllint --noout` on it:
now well-formed (previously malformed). asInvoker is retained, so the
#454 Installer-Detection / os error 740 fix still stands.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant