[PATCH 0/1] MR11723: appwiz.cpl: Fix default_dir lookup
Refactored to include the default prefix of `/usr/local/share` from configure. Declaring `WCHAR data_dirs[]` fixed this anyway. Left in as a fallback. Package managers may add/remove packages from `/usr/share/wine`, so `/usr/local/share/wine` is very handy (particularly when bisecting). The TRACEs helped a lot here, so left some behind. Symptom: Wine would insist that packages I downloaded manually to `/usr/local/share/wine/mono` had to be downloaded again (to `~/.cache`). The new Mono package is not ready/installed locally at time of writing. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723
From: Ken Sharp <imwellcushtymelike@gmail.com> Refactored to include the default prefix of /usr/local/share from configure. Declaring data_dirs[] as WCHAR fixed this anyway. Left in as a fallback. --- dlls/appwiz.cpl/addons.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/dlls/appwiz.cpl/addons.c b/dlls/appwiz.cpl/addons.c index a01fd0f091d..393622a72a6 100644 --- a/dlls/appwiz.cpl/addons.c +++ b/dlls/appwiz.cpl/addons.c @@ -297,6 +297,13 @@ static enum install_res install_from_default_dir(void) const WCHAR *package_dir; WCHAR *dir_buf = NULL; enum install_res ret = INSTALL_NEXT; + int i; + static const WCHAR * const data_dirs[] = { + L"\\\\?\\unix" INSTALL_DATADIR "/wine/", + L"\\\\?\\unix/usr/share/wine/", + L"\\\\?\\unix/usr/local/share/wine/", + L"\\\\?\\unix/opt/wine/" + }; if ((package_dir = _wgetenv( L"WINEBUILDDIR" ))) { @@ -313,12 +320,14 @@ static enum install_res install_from_default_dir(void) free(dir_buf); } - if (ret == INSTALL_NEXT) - ret = install_from_file(L"\\\\?\\unix" INSTALL_DATADIR "/wine/", addon->subdir_name, addon->file_name); - if (ret == INSTALL_NEXT && strcmp("" INSTALL_DATADIR, "/usr/share") != 0) - ret = install_from_file(L"\\\\?\\unix/usr/share/wine/", addon->subdir_name, addon->file_name); - if (ret == INSTALL_NEXT) - ret = install_from_file(L"\\\\?\\unix/opt/wine/", addon->subdir_name, addon->file_name); + for (i = 0; i < ARRAY_SIZE(data_dirs) && ret == INSTALL_NEXT; i++) + { + TRACE("(Try %d) Installing %s from %s...\n", i, debugstr_w(addon->file_name), debugstr_w(data_dirs[i])); + ret = install_from_file(data_dirs[i], addon->subdir_name, addon->file_name); + + if (ret == INSTALL_NEXT) TRACE("(Try %d) fail.\n", i); + else TRACE("(Try %d) success.\n", i); + } return ret; } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11723
Potentially trying the same dir twice doesn't seem like an improvement. What's wrong with the existing code? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723#note_149506
On Fri Aug 21 15:18:45 2026 +0000, Alexandre Julliard wrote:
Potentially trying the same dir twice doesn't seem like an improvement. What's wrong with the existing code? `INSTALL_DATADIR` is not resolved properly:
``` 009c:trace:appwizcpl:install_from_default_dir package dir L"\\??\\Z:\\tmp\\wine\\wine32\\..\\" ``` The string is not concatencated correctly because of a difference between wide and narrow strings. ``` L"\\\\?\\unix" INSTALL_DATA_DIR "/wine/" ``` Casting `WCHAR data_dirs[]` resolves this.
Potentially trying the same dir twice doesn't seem like an improvement
That's always been the case, if `INSTALL_DATADIR == "/usr/share/wine"`. ``` if (ret == INSTALL_NEXT) ret = install_from_file(L"\\\\?\\unix" INSTALL_DATADIR "/wine/", addon->subdir_name, addon->file_name); if (ret == INSTALL_NEXT && strcmp("" INSTALL_DATADIR, "/usr/share") != 0) ret = install_from_file(L"\\\\?\\unix/usr/share/wine/", addon->subdir_name, addon->file_name); ``` In theory, anyway, but the first part doesn't work. If `INSTALL_DATADIR == /opt/wine-my-special-build` then checking `/usr/local/share/wine` still makes sense and isn't checked twice. It's a fallback like the others. Initially I changed the layout so I could add traces, but then found it worked so here it is. ``` 01ac:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-gecko-2.47.4-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 01ac:trace:appwizcpl:install_from_default_dir (Try 0) success. ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723#note_149536
The string is not concatencated correctly because of a difference between wide and narrow strings.
No, that works just fine.
That's always been the case, if INSTALL_DATADIR == "/usr/share/wine".
INSTALL_DATADIR would be "/usr/share" in this case, it comes from configure. I don't see anything to fix here. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723#note_149542
On Fri Aug 21 16:44:34 2026 +0000, Alexandre Julliard wrote:
The string is not concatencated correctly because of a difference between wide and narrow strings. No, that works just fine. That's always been the case, if INSTALL_DATADIR == "/usr/share/wine". INSTALL_DATADIR would be "/usr/share" in this case, it comes from configure. I don't see anything to fix here. Yeah I meant `/usr/share` not `/usr/share/wine`.
Adding a trace in `install_from_file()`... Before: ``` 009c:trace:appwizcpl:DllMain (75A70000, 1, 00000000) 009c:trace:appwizcpl:install_from_default_dir package_dir is L"\\??\\Z:\\tmp\\wine\\wine32\\..\\" 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00a0:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b4:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00b4:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/opt/wine/mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:get_cache_file_name got L"\\\\?\\Z:\\home\\test\\.cache\\wine\\wine-mono-11.3.0-x86.msi" 009c:warn:appwizcpl:sha_check Could not open file: 3 009c:warn:appwizcpl:install_from_cache could not validate checksum 009c:trace:appwizcpl:get_url Got URL L"http://source.winehq.org/winemono.php?arch=x86&v=11.3.0&winev=11.15" 009c:trace:appwizcpl:DllMain (75A70000, 0, 00000000) 01ac:trace:appwizcpl:DllMain (74FB0000, 1, 00000000) 01ac:trace:appwizcpl:install_from_default_dir package_dir is L"\\??\\Z:\\tmp\\wine\\wine32\\..\\" 01ac:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/opt/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:get_cache_file_name got L"\\\\?\\Z:\\home\\test\\.cache\\wine\\wine-gecko-2.47.4-x86.msi" 01ac:warn:appwizcpl:sha_check Could not open file: 3 01ac:warn:appwizcpl:install_from_cache could not validate checksum 01ac:trace:appwizcpl:get_url Got URL L"http://source.winehq.org/winegecko.php?arch=x86&v=2.47.4&winev=11.15" 01ac:trace:appwizcpl:DllMain (74FB0000, 0, 00000000) ``` After: ``` wine: created the configuration directory '/tmp/wine/wineprefix' 009c:trace:appwizcpl:DllMain (75A70000, 1, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-mono-11.3.0-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00a0:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b4:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_default_dir (Try 0) success. 009c:trace:appwizcpl:DllMain (75A70000, 0, 00000000) 01ac:trace:appwizcpl:DllMain (74FB0000, 1, 00000000) 01ac:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-gecko-2.47.4-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir (Try 0) success. 01ac:trace:appwizcpl:DllMain (74FB0000, 0, 00000000) ``` The first trace clearly shows that it's failing and moves on to try and download the package. The second trace shows it succeeds. Unfortunately, it's not obvious WHY this works. The mixed casts explanation possibly (probably) isn't the cause, as this should have been fixed with C99 (and GCC 15). Before: ``` 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" ``` After ``` 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-mono-11.3.0-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" ``` The `canonical_path` looks identical to me in both cases. This is very easy to test: 1. Make sure packages are in `/usr/local/share` and nowhere else. 2. Build 3. `wineboot` I am asked to download the packages. If they're already in `~/.cache` then obviously it won't ask again. This may be indicative of another issue. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723#note_149551
On Fri Aug 21 18:45:44 2026 +0000, Ken Sharp wrote:
Yeah I meant `/usr/share` not `/usr/share/wine`. Adding a trace in `install_from_file()`... Before: ``` 009c:trace:appwizcpl:DllMain (75A70000, 1, 00000000) 009c:trace:appwizcpl:install_from_default_dir package_dir is L"\\??\\Z:\\tmp\\wine\\wine32\\..\\" 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00a0:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b4:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00b4:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/opt/wine/mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:get_cache_file_name got L"\\\\?\\Z:\\home\\test\\.cache\\wine\\wine-mono-11.3.0-x86.msi" 009c:warn:appwizcpl:sha_check Could not open file: 3 009c:warn:appwizcpl:install_from_cache could not validate checksum 009c:trace:appwizcpl:get_url Got URL L"http://source.winehq.org/winemono.php?arch=x86&v=11.3.0&winev=11.15" 009c:trace:appwizcpl:DllMain (75A70000, 0, 00000000) 01ac:trace:appwizcpl:DllMain (74FB0000, 1, 00000000) 01ac:trace:appwizcpl:install_from_default_dir package_dir is L"\\??\\Z:\\tmp\\wine\\wine32\\..\\" 01ac:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/opt/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:get_cache_file_name got L"\\\\?\\Z:\\home\\test\\.cache\\wine\\wine-gecko-2.47.4-x86.msi" 01ac:warn:appwizcpl:sha_check Could not open file: 3 01ac:warn:appwizcpl:install_from_cache could not validate checksum 01ac:trace:appwizcpl:get_url Got URL L"http://source.winehq.org/winegecko.php?arch=x86&v=2.47.4&winev=11.15" 01ac:trace:appwizcpl:DllMain (74FB0000, 0, 00000000) ``` After: ``` wine: created the configuration directory '/tmp/wine/wineprefix' 009c:trace:appwizcpl:DllMain (75A70000, 1, 00000000) 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-mono-11.3.0-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" 00a0:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b4:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00b8:trace:appwizcpl:DllMain (75A70000, 2, 00000000) 00ac:trace:appwizcpl:DllMain (75A70000, 3, 00000000) 009c:trace:appwizcpl:install_from_default_dir (Try 0) success. 009c:trace:appwizcpl:DllMain (75A70000, 0, 00000000) 01ac:trace:appwizcpl:DllMain (74FB0000, 1, 00000000) 01ac:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-gecko-2.47.4-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 01ac:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/gecko\\wine-gecko-2.47.4-x86.msi" 01ac:trace:appwizcpl:install_from_default_dir (Try 0) success. 01ac:trace:appwizcpl:DllMain (74FB0000, 0, 00000000) ``` The first trace clearly shows that it's failing and moves on to try and download the package. The second trace shows it succeeds. Unfortunately, it's not obvious WHY this works. The mixed casts explanation possibly (probably) isn't the cause, as this should have been fixed with C99 (and GCC 15). Before: ``` 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir Trying to install from: L"\\\\?\\unix/usr/local/share/wine/" 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" ``` After ``` 009c:trace:appwizcpl:install_from_file canonical_path: L"Z:\\tmp\\wine\\mono\\wine-mono-11.3.0-x86.msi" 009c:trace:appwizcpl:install_from_default_dir (Try 0) Installing L"wine-mono-11.3.0-x86.msi" from L"\\\\?\\unix/usr/local/share/wine/"... 009c:trace:appwizcpl:install_from_file canonical_path: L"\\\\?\\unix/usr/local/share/wine/mono\\wine-mono-11.3.0-x86.msi" ``` The `canonical_path` looks identical to me in both cases. This is very easy to test: 1. Make sure packages are in `/usr/local/share` and nowhere else. 2. Build 3. `wineboot` I am asked to download the packages. If they're already in `~/.cache` then obviously it won't ask again. This may be indicative of another issue. If there's actually a bug, the right way is to figure out what the bug is. Then you can work on fixing it, ideally with the minimal amount of changes needed to fix the issue.
Starting by rewriting the function before understanding what's going on is not a good idea. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11723#note_149559
participants (3)
-
Alexandre Julliard (@julliard) -
Ken Sharp -
Ken Sharp (@imwellcushtymelike)