`SYSTEM`; accounts in the Administrators group use
`C:\ProgramData\ssh\administrators_authorized_keys` instead.
- **rsync brings its own `ssh.exe`.** That release ships as one zip per
- architecture — `rsync-windows-x64.zip` / `rsync-windows-x86.zip`, each holding
- `rsync.exe`, an `ssh.exe`, `COPYING.txt` and `NOTICE-ssh.txt` — and the
- elevated half picks the zip for the host architecture (ARM64 takes the x64 one;
- there is no ARM64 asset), verifies it against the published `.sha256`, unpacks
- the pair together, then **runs** the unpacked `ssh.exe` and removes it if it
- will not start. Together is the point:
+ architecture — `rsync-windows-x86.zip`, `-x64.zip` and `-arm64.zip`, each
+ holding `rsync.exe`, an `ssh.exe`, `COPYING.txt` and `NOTICE-ssh.txt` — and the
+ elevated half picks the zip matching the host, verifies it against the
+ published `.sha256`, unpacks the pair together, then **runs** the unpacked
+ `ssh.exe` and removes it if it will not start. Together is the point:
`rsync.exe` prefers an `ssh.exe` sitting in its own directory, and the release
builds one because the client Windows ships reads its stdin 3 KB at a time,
which holds a transfer *from* the box at ~17 MB/s however fast the link is.
| | On ARM64 |
| --- | --- |
| **Native ARM64** | Git, Python, .NET SDK, PowerShell, VS Code, Windows Terminal, Sysinternals, Claude Code, CMake, Ninja, the VS installer, **MSVC**, MSBuild, the SDK tools (`rc`, `signtool`), the in-box OpenSSH client, and the Windows Performance Toolkit. |
-| **Emulated x64** | `iperf3` and `rsync.exe` — both network-bound — and the ADK *installer* (the toolkit it lays down is native). |
+| **Emulated x64** | `iperf3` (network-bound) and the ADK *installer* (the toolkit it lays down is native). |
| **Emulated, minor** | `py.exe` (python.org ships the launcher shim as x86; it execs the native `python.exe`) and `vswhere.exe` (Microsoft ships x86 only; runs once). |
| **Not installed** | Brave, WinMerge, upstream LLVM, NASM, Android GPU Inspector, OpenCppCoverage, BinSkim, VS `clang-cl`, and the WDK — see the table above. |
| **Unavailable** | VirtualBox, the Windows 7 x86 test VM, Intel VTune, and the `v141` / Windows XP targeting toolset. |
rest of the x64-only set to keep the rule simple, not because it was broken.
The RID list is still ordered preference on x64, so a future `win-arm64` build
would be picked up with no further change.
-- **`rsync` gets the x64 zip, and its `ssh.exe` is verified by running it.** The
- release publishes x64 and x86 assets and no ARM64 one. x64 is still the right
- pick — a transfer is bounded by the socket, not by emulated CPU, so lifting the
- in-box client's 3 KB stdin cap wins by far more than emulation costs. But that
- `ssh.exe` links against a `System32\libcrypto.dll` which on ARM64 is an **ARM64**
- binary, so it may not load at all. That matters more than it sounds:
- `rsync.exe` *prefers* an `ssh.exe` in its own directory, so a present-but-broken
- one does not degrade to the in-box client — it breaks rsync outright, with an
- error that names a dead remote shell rather than `ssh.exe`. The elevated half
- therefore runs `ssh -V` after unpacking and **deletes** the binary if it will
- not start, so `rsync` falls back to the native in-box client. The
- `core.sshCommand` step in the non-elevated half already picked its candidate by
- running it, and is unchanged.
+- **`rsync` is native on ARM64 now**, and its `ssh.exe` is still verified by
+ running it. The release publishes an `arm64` asset as of `v3.5.0-gdeeda96f`;
+ both binaries in it are `0xAA64`, and the `ssh.exe` reports
+ `OpenSSH_for_Windows_10.0p2 ... LibreSSL 3.8.2` on this box.
+
+ Before that asset existed, ARM64 took the x64 zip. The `rsync.exe` was fine —
+ a transfer is bounded by the socket, not by emulated CPU — but its `ssh.exe`
+ links against `System32\libcrypto.dll`, which on ARM64 is an **ARM64** binary
+ an x64 process cannot load. It died with `0xC0000135`
+ (`STATUS_DLL_NOT_FOUND`) and had to be deleted on every run. That matters more
+ than it sounds: `rsync.exe` *prefers* an `ssh.exe` in its own directory, so a
+ present-but-broken one does not degrade to the in-box client — it breaks rsync
+ outright, with an error naming a dead remote shell rather than `ssh.exe`.
+
+ The elevated half still runs `ssh -V` after unpacking and **deletes** the
+ binary if it will not start. The check is kept because it is what found that
+ problem, and it still covers a missing or too-old `libcrypto.dll` on any
+ architecture. An x64 `rsync.exe` surviving on an ARM64 box now shows up in the
+ audit as emulation *without* a listed reason, with a remedy pointing at a
+ re-run. The `core.sshCommand` step in the non-elevated half already picked its
+ candidate by running it, and is unchanged.
- **Intel VTune reports `n/a`** rather than printing a download link: there is no
Windows-on-Arm build, and its value is reading Intel PMU counters. Use the
Windows Performance Toolkit (`wpr`/`xperf` to collect, `wpa` to analyse), or
Arm Performance Studio / Streamline for Arm PMU sampling.
-- **NASM is still installed** (as emulated x64) because this box cross-compiles
- x86/x64, where NASM is the assembler that builds them. If you only target
- ARM64, nothing uses it — the ARM64 assembler is `armasm64.exe`, which ships
- with MSVC.
+- **NASM is not installed on ARM64.** It assembles x86/x86-64 only — there is no
+ ARM64 target in it and no ARM64 build of it — so it went into the x64-only set
+ with the rest. The ARM64 assembler is `armasm64.exe`, which ships with MSVC.
+ Its installer is also one of the two here that fall back to a per-user
+ directory it never registers (`%LOCALAPPDATA%\bin\NASM`), so `winget uninstall`
+ cannot find it afterwards; the `Uninstall.exe` in that directory is the way out.
- **`vswhere` stays under the 32-bit Program Files** on ARM64 too
(`%ProgramFiles(x86)%\Microsoft Visual Studio\Installer`), so that path is
unchanged. The VS Installer is x86-registered there by contract even though the