]> vilimpoc.org git repositories - dotfiles/blame - README.md
dotfiles: drop the non-elevated ETW tracing, it never worked
[dotfiles] / README.md
CommitLineData
3c096107
MV
1# dotfiles
2
3Windows development-box provisioning scripts.
4
5`setup-windows.bat` takes a fresh Windows install to a working C++ / native
6development environment: editors and shells, Python, the Visual Studio 2022
7toolchain (including the Clang and Windows XP targeting toolsets), the Windows
8Driver Kit, and a handful of analysis tools (Sysinternals, OpenCppCoverage,
452f525c
MV
9BinSkim, the Windows Performance Toolkit). It also sets the box up to be driven
10remotely: OpenSSH Server plus an rsync build for Windows, which is what makes a
11throwaway VM reachable from a Linux host.
3c096107
MV
12
13## Files
14
15| File | Purpose |
16| --- | --- |
2bbc9b41 17| `setup-windows.bat` | Entry point. Runs the winget installs, then launches the elevated half and prints its log, then runs the non-elevated script. |
2e281421 18| `setup-windows-no-uac.ps1` | The non-elevated, per-user half: WinMerge and BinSkim on the user `PATH`, and the global git config (identity, plus `core.sshCommand`). Can also be run directly from an ordinary prompt. |
95307dbb 19| `setup-windows-with-uac.ps1` | The elevated half, started via UAC by the batch file. Enables `ssh-agent`, installs the OpenSSH Client and Server capabilities and starts `sshd`, unpacks the `rsync-windows` release zip for this architecture (`rsync.exe` plus the `ssh.exe` it runs) into `C:\Tools\rsync` on the machine `PATH`, then installs Visual Studio 2022 Community with the required components, the WDK, and the Windows Performance Toolkit, and reports whether Intel VTune Profiler is present. Can also be run directly from an Administrator prompt. |
541058e3 20| `setup-windows-7-test-env.bat` | Prepares a **Windows 7 VM** as a test target driven from the host by `VBoxManage guestcontrol`. Copy it into the guest and run it there; it is idempotent, so re-run it after any snapshot restore. The per-user half needs no UAC (crash-dialog suppression, no screen blanking, a staging directory, the shared folder on `Z:`); the machine-wide half is skipped with a notice unless run elevated inside the guest. It then reports what the box can actually test: DWM composition, printers, audio capture devices. |
3c096107
MV
21
22## Usage
23
2e281421
MV
241. **Edit `setup-windows-no-uac.ps1` first.** The global git identity near the
25 top of the file is empty:
3c096107 26
2e281421
MV
27 ```powershell
28 $GitUserName = '' # e.g. 'Ada Lovelace'
29 $GitUserEmail = '' # e.g. 'ada@example.com'
3c096107
MV
30 ```
31
2e281421
MV
32 Fill in your own name and email, or leave them empty to keep your identity
33 per-repository - the script skips `user.name` / `user.email` rather than
34 writing a placeholder, and says so. Everything else in that script is set
35 either way.
3c096107
MV
36
372. Run it from a normal (non-elevated) prompt:
38
39 ```bat
40 setup-windows.bat
41 ```
42
43 It will raise a single UAC prompt for the elevated half. Accept it — declining
44 leaves Visual Studio and the WDK uninstalled, and the script says so.
45
463. Restart your shell afterwards so the updated user `PATH` is picked up, and
47 reboot if a step reported that a restart was required.
48
49## Notes
50
51- The elevated half writes a transcript to `setup-windows-uac.log` next to the
52 script; the batch file prints it when the elevated window closes. The log is
53 gitignored, as it contains local paths.
2bbc9b41
MV
54- **git uses a Win32-OpenSSH client.** `setup-windows-no-uac.ps1` sets
55 `core.sshCommand`. Git for Windows otherwise prefers its own bundled MSYS2
56 `ssh.exe`, which cannot reach the Windows `ssh-agent` service that the elevated
57 half enables - Win32-OpenSSH publishes the agent on a named pipe the MSYS2
58 build does not speak. Without this, keys loaded with `ssh-add` from PowerShell
59 are invisible to `git`, and a push falls back to hunting for a key file and
60 prompting for its passphrase. The value uses forward slashes on purpose: git
61 parses `core.sshCommand` with shell quoting rules, in which a backslash is an
62 escape character.
63- **Which `ssh.exe` git gets.** `C:\Tools\rsync\ssh.exe` — the fast build the
64 elevated half unpacks — if it is there, `%WINDIR%/System32/OpenSSH/ssh.exe`
65 otherwise. It is the same client with the same `~/.ssh`, agent and
66 `known_hosts`; the difference is the stdin pump, and without it anything git
67 *pushes* is capped at ~17 MB/s. Candidates are tried by **running** them
68 (`ssh -V`), not by `Test-Path`: the fast build needs a `libcrypto.dll` that an
69 image without the OpenSSH Client capability does not have, and a client that
70 will not start should be found here rather than on the next `git push`.
71 This is also why `setup-windows.bat` now runs the elevated half **first** — the
72 fast `ssh.exe` has to exist before the git config step can prefer it. The
73 non-elevated half still runs even when the elevated one failed; it just falls
74 back. Re-run `setup-windows-no-uac.ps1` on its own at any time to re-pick.
2e281421 75- All three scripts are idempotent — re-running skips anything already installed.
452f525c
MV
76 BinSkim in particular checks NuGet for the newest stable version *before*
77 downloading: the package is a self-contained .NET build well over 100 MB, and
78 re-provisioning an up-to-date box should not pay for it. The installed version
79 is tracked in `nupkg-version.txt` beside the tool.
2e281421
MV
80- `setup-windows-no-uac.ps1` runs its steps independently: one failing warns and
81 the rest still run, and it exits 1 if any did. The `.bat` reports that and
82 carries on to the elevated half, which is the part worth the UAC prompt. Use
83 `-Skip` to re-run a subset, e.g. `.\setup-windows-no-uac.ps1 -Skip BinSkim`.
84 Run it **non-elevated**: it writes per-user state (the `HKCU` `PATH`, the
85 `.gitconfig` under `%USERPROFILE%`), so an elevated run would configure the
86 administrator's profile instead. It warns if you do.
452f525c
MV
87- **Remote access.** OpenSSH Server is installed from the Windows on-demand
88 capability (10/1809+), set to start automatically, and given an inbound TCP 22
89 firewall rule on *all* profiles — a VM's host-only or bridged adapter is
90 routinely classified Public, which is the usual reason a running `sshd` is
91 unreachable. Windows ships no `rsync`, so a build of it
92 ([nuket/rsync-windows](https://github.com/nuket/rsync-windows)) is installed to
93 `C:\Tools\rsync` and added to the **machine** `PATH`. That last detail matters:
94 the remote end of an `rsync` runs non-interactively, with no login shell, and
95 Win32-OpenSSH builds that environment from the registry `PATH` rather than from
96 a profile. Key auth needs `~/.ssh/authorized_keys` ACL'd to just you and
97 `SYSTEM`; accounts in the Administrators group use
98 `C:\ProgramData\ssh\administrators_authorized_keys` instead.
b8144088
MV
99- **rsync brings its own `ssh.exe`.** That release ships as one zip per
100 architecture — `rsync-windows-x64.zip` / `rsync-windows-x86.zip`, each holding
101 `rsync.exe`, an `ssh.exe`, `COPYING.txt` and `NOTICE-ssh.txt` — and the
102 elevated half picks the zip for the OS bitness, verifies it against the
103 published `.sha256`, and unpacks the pair together. Together is the point:
104 `rsync.exe` prefers an `ssh.exe` sitting in its own directory, and the release
105 builds one because the client Windows ships reads its stdin 3 KB at a time,
106 which holds a transfer *from* the box at ~17 MB/s however fast the link is.
107 Nothing else about it differs — same `~/.ssh`, same `ssh-agent`, same
108 `known_hosts` — and a bare `ssh` still resolves to the in-box client, which
109 sits ahead of `C:\Tools\rsync` on the `PATH`. It links against the
110 `libcrypto.dll` the **OpenSSH Client** capability puts in `System32` (Windows'
111 own LibreSSL, which uses AES-NI) and ships no copy of its own, so the elevated
112 half installs that capability first and falls back to `rsync.exe` alone,
113 warning, on an image that will not offer it.
114- The `rsync` download follows the `releases/latest/download/` redirect rather
115 than the GitHub API: unauthenticated API calls are rate-limited to 60/hour per
116 IP, which a provisioning run behind a shared NAT can genuinely exhaust. To hold
117 a box on a known build, pin the tag in `$RsyncUrl`
118 (`.../releases/download/<tag>/<asset>`) instead.
3c096107
MV
119- Visual Studio is installed in three labelled passes (base workload, Clang/LLVM,
120 XP toolset) so a failure identifies which component group is responsible.
99725a30
MV
121- **Windows Performance Analyzer is not part of Visual Studio.** VS has its own
122 Performance Profiler, which is a different, `.diagsession`-based tool and
123 cannot open an `.etl`. WPA ships with `xperf` and `wpr` in the Windows
124 Performance Toolkit, which exists in exactly two places: as an optional
125 *feature* of the Windows SDK (`OptionId.WindowsPerformanceToolkit`) and inside
126 the Windows ADK, which bundles the same toolkit. Whether the SDK install that
127 Visual Studio performs selects that feature varies by version, so the elevated
128 half **detects first** — `%ProgramFiles(x86)%\Windows Kits\10\Windows
129 Performance Toolkit`, its 64-bit twin, and the ADK location — and only falls
130 back to `winget install Microsoft.WindowsADK` when nothing is there. It then
131 re-asserts that directory on the machine `PATH` (the toolkit's own installer
132 usually does this, and the Start Menu gets *Windows Kits > Windows Performance
133 Toolkit* shortcuts for WPA and WPR). To install just the toolkit instead of the
134 whole ADK, run the standalone SDK setup with
135 `winsdksetup.exe /features OptionId.WindowsPerformanceToolkit /q`. A newer WPA
136 also exists in the Microsoft Store (`winget install --id 9N0W1B2BXGNZ --source
137 msstore`); it is not installed here because the Store source needs an
138 interactive, signed-in session, which the unattended elevated half does not
139 have.
1e91b38f
MV
140- **Intel VTune Profiler is reported, not installed.** The elevated half prints
141 whether it is on the box, its version, and the path to `vtune.exe`; if it is
142 missing it prints the download page instead (and says so if the CPU is not
143 Intel). Automating the install is not worth it here: the offline installer is a
144 ~750 MB download from a URL carrying a per-release GUID with no "latest"
145 redirect behind it, so every new build would mean editing a hard-coded link,
146 and it is only worth having on Intel silicon since hardware event-based
147 sampling reads Intel PMU counters. It does install unattended if you want it
148 scripted elsewhere:
149
150 ```powershell
151 intel-vtune-<version>_offline.exe -a --silent --cli --eula accept
152 ```
153
95307dbb
MV
154 **Run it from an administrator account, elevated.** Hardware event-based
155 sampling (`uarch-exploration`, `memory-access`, `hotspots -knob
156 sampling-mode=hw`) requires it, and VTune warns about that at the top of every
157 unelevated run. Worth knowing that the failure it gives there is *"cannot
5c01c42c
MV
158 recognize the processor"*, which reads like a hardware problem and is not one:
159 the drivers (`sepdrv5`, `sepdal`, `vtss`) are installed and running, and VTune
95307dbb
MV
160 identifies the PMU through them. There is no group to join to get around it —
161 the Linux driver can be handed to a `vtune` group, but on Windows the
5c01c42c
MV
162 documented answer is to run as administrator.
163
95307dbb
MV
164- **Collect traces from an elevated Administrator session. Non-elevated
165 collection was tried here and abandoned.** The attempt was to put one ordinary
166 account into `BUILTIN\Performance Log Users`, which appears in the default
167 security descriptors ETW keeps per provider GUID under
168 `HKLM\SYSTEM\CurrentControlSet\Control\WMI\Security`, and collect without a UAC
169 prompt. It does not survive contact with the real workflow: `xperf -on base`
170 and `wpr -start` drive the *NT Kernel Logger*, reserved for Administrators and
171 LocalSystem, and granting the group `SeSystemProfilePrivilege` ("Profile system
172 performance") plus an explicit ACE for `TRACELOG_ACCESS_KERNEL_LOGGER` on
173 `SystemTraceControlGuid` — all three in place, across a reboot — still answered
99725a30
MV
174
175 ```text
95307dbb 176 xperf: error: NT Kernel Logger: Access is denied. (0x5).
99725a30
MV
177 ```
178
95307dbb
MV
179 It is not a check an ACE overrides, and the same wall turned up often enough
180 elsewhere that the whole approach was dropped rather than carried as a
181 half-working path. **Sign in to an administrator account and run `xperf`, `wpr`
182 and VTune from an elevated prompt.** Analysis is the exception and never needed
183 any of this: `wpa.exe` opens an existing `.etl` as a plain user.
184
185 If an earlier revision of these scripts ran on a box, it left that account in
186 the group. Take it back out with:
0aec6243
MV
187
188 ```powershell
95307dbb 189 net localgroup "Performance Log Users" DOMAIN\user /delete
0aec6243 190 ```
593189b7 191
95307dbb
MV
192 Two revisions also granted the privilege and the ACE. Undo the privilege in
193 `secpol.msc` > Local Policies > User Rights Assignment > "Profile system
194 performance" by removing Performance Log Users. The ACEs sit in the
195 `{9e814aad-3204-11d2-9a82-006008a86939}` value under
593189b7
MV
196 `HKLM\SYSTEM\CurrentControlSet\Control\WMI\Security`: strip the `LU` entries
197 from that descriptor rather than deleting the value, which also carries entries
198 for SYSTEM, Administrators and two service accounts.
95307dbb 199
3c096107
MV
200- The scripts were extracted from a native Windows project, so the component
201 selection is tuned for that: Spectre-mitigated runtimes, the v141/XP toolset,
202 and driver-kit headers. Trim the component lists in the `.ps1` if you don't
203 need them — each group is a plain array near the top.