fix(wine): keep the profile reachable under both lineages' names - #236
Conversation
CrossOver-lineage builds hardcode users/crossover for the shell folders while every Wine build names the real profile after the Unix user, so a bottle opened on the other lineage booted into an empty profile. Symlink whichever name is missing to the one holding the data before each launch, and only displace a directory that is an untouched skeleton.
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
|
Review notes, since this one cannot be self-approved. The mechanism is verified at the source: ntdll's set_home_dir is identical in upstream wine-11.16 and winecx (name from USER, then getpwuid), and the divergence is entirely shell32's hardcoded "crossover" in shellpath.c, so a filesystem alias is the only lever the app has. The reconcile sits on every launch path that carries a bottle (runProgram, runWineProcess, runWineWithBottle, generateRunCommand) and skips wineserver, which never touches the profile. Safety properties I checked against the tests: a directory is only replaced when it has no regular file outside Temp, the displaced skeleton is parked at .profile-reconcile inside the bottle root rather than under drive_c/users, so detectWineUsername cannot pick it up, and a failed link after the move puts the skeleton back. Hand-made symlinks are respected, two populated profiles are left alone. Full kit suite 1294 XCTest plus 234 Swift Testing green, app target builds, both lints clean, CI green. Merging; the real-runtime exercise happens as part of the beta audit on #163. |
|
Exercised against real runtimes now, closing the caveat in the description. A prefix booted by the stock 3.1.1 engine (users/afranke, with a marker file in AppData/Roaming) reconciled to crossover -> afranke through WineUserProfile.reconcile. Opened with the v4.6.4-beta.1 runtime: wineboot -u exits 0, cmd reports USERPROFILE as C:\users\crossover and APPDATA under it, the symlink is intact afterwards, the marker is readable through the crossover path, and no third profile or displaced skeleton appeared. That is the exact scenario the empty-profile reports came from. |
…nkea#236) CrossOver-lineage builds hardcode users/crossover for the shell folders while every Wine build names the real profile after the Unix user, so a bottle opened on the other lineage booted into an empty profile. Symlink whichever name is missing to the one holding the data before each launch, and only displace a directory that is an untouched skeleton. (cherry picked from commit fb03370)
Closes the users/crossover gate on the v4 engine promotion (#163).
the problem
Every Wine build names the profile directory after the Unix user (
set_home_dirin ntdll is identical in upstream and winecx), so a bottle created on the stock engine hasdrive_c/users/<name>. CrossOver-lineage builds carry "CrossOver Hack 12735" in shell32'sshellpath.c, which expands%USERPROFILE%toC:\users\crossoverregardless of the user. Open a stock bottle on a v4 runtime and the shell folders resolve into a fresh, emptyusers/crossover: Steam asks for a login, saves are gone, nothing errors. The name is a compile-time constant in that build, so no environment variable steers it; the fix has to be on disk.the change
WineUserProfile.reconcile(bottleURL:)runs before every launch that goes through a bottle (runProgram,runWineProcess(bottle:),runWineWithBottle, and the terminalgenerateRunCommand). It makes the profile reachable under both names:Tempcontents only, no regular file anywhere else): the skeleton is moved to<bottle>/.profile-reconcile/<name>-<timestamp>and replaced by the symlink. Moved, never deleted, and parked outsidedrive_c/usersso neither Wine nordetectWineUsernamesees it as a profile.bothPopulated, merging is a decision for a personThe common case is a handful of stat calls.
detectWineUsernamealready prefers the non-crossover name, and it sees through the symlink either way, so the rest of the app keeps working with the paths it has.verified
Not yet exercised against a real v4 runtime; that check is part of the beta audit on #163.