http://bugs.winehq.org/show_bug.cgi?id=16577
Summary: ntdll/loader/actctx: add support of SxS assembly binding redirects Product: Wine Version: 1.1.10 Platform: All URL: http://nikonusa.com/software/NX/1.3/win/CNX130NSAEN.EXE OS/Version: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: ntdll AssignedTo: wine-bugs@winehq.org ReportedBy: focht@gmx.net
Hello,
this is a showcase bug. I used the app from bug 12414 as example because it highlights some of the issues and hopefully helps to understand the problem (with my comments). We need to end this winetricks vcrun2XXX SxS mess/hell, which requires direct match of SxS assembly dependencies/bindings.
Download: http://nikonusa.com/software/NX/1.3/win/CNX130NSAEN.EXE
$ sha1sum CNX130NSAEN.EXE -> f31b38e3bcca17c8050c207b79315c9be23d582d
Prerequisite: clean WINEPREFIX, winetricks dotnet20
---
The first installer show stopper (which is this bug report out) are actually two bugs: one in winetricks and one in the installer. When you did 'sh winetricks dotnet20' step and start the installer, an error message box will be shown shortly thereafter:
--- snip --- Microsoft Visual C++ Runtime Library
Program: c:\windows\temp\RarSFX0\cnx.exe
R6034 An application has made an attempt to load the C runtime library incorrectly. --- snip ---
The problem comes in form of a sub-installer dependency:
WINEDEBUG=+tid,+seh,+loaddll,+process wine ./nikon.exe
--- snip --- ... 0079:trace:process:CreateProcessW app (null) cmdline L"C:\windows\temp\RarSFX0\cnx.exe" ... 0079:trace:process:CreateProcessW started process pid 007a tid 007b ... 007b:trace:loaddll:free_modref Unloaded module L"C:\windows\temp\nshbb9d.tmp\UserInfo.dll" : native 007b:trace:loaddll:load_native_dll Loaded L"C:\windows\temp\nshbb9d.tmp\process.dll" at 0x10000000: native 007b:fixme:actctx:parse_depend_manifests Could not find dependent assembly L"Microsoft.VC80.CRT" 007b:trace:loaddll:load_native_dll Loaded L"C:\windows\temp\nshbb9d.tmp\LIBEXPATW.dll" at 0x3d0000: native 007b:trace:loaddll:load_builtin_dll Loaded L"C:\windows\system32\mpr.dll" at 0x60c50000: builtin 007b:trace:loaddll:load_builtin_dll Loaded L"C:\windows\system32\wininet.dll" at 0x60c00000: builtin 007b:trace:loaddll:load_builtin_dll Loaded L"C:\windows\system32\msvcrt.dll" at 0x60c80000: builtin 007b:trace:loaddll:load_native_dll Loaded L"C:\windows\system32\MSVCR80.dll" at 0x78130000: native 007b:trace:loaddll:load_native_dll Loaded L"C:\windows\system32\MSVCP80.dll" at 0x7c420000: native 007b:trace:loaddll:load_native_dll Loaded L"C:\windows\temp\nshbb9d.tmp\Activation.dll" at 0x3a0000: native --- snip ---
The culprit is: "fixme:actctx:parse_depend_manifests Could not find dependent assembly L"Microsoft.VC80.CRT"
If we dump the embedded manifest from PE for the "Activation.dll":
--- snip --- <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity> </dependentAssembly> </dependency> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"> </assemblyIdentity> --- snip ---
We can see two VC 8.0 runtime versions referenced, the VC 8.0 SP1 and an older VC 8.0 one.
"8.0.50727.762" -> Visual C++ 2005 SP1 Redistributable Pack 8.0.50727.762
At this stage, only .NET Framwork 2.0 redist got installed as prerequisite in WINEPREFIX. Because of winetricks' winver 2k hack (missing junction point workaround, bug 12401), VC 8.0.50727.42 runtimes are placed in both: system32 and SxS repo.
This results in errorneous behaviour in case of SxS assembly resolver failure (app references 8.x CRT assemblies not found in SxS) - a fallback load from system32 - which causes the CRT error.
I already explained the differences between 2K and XP in several other bug reports when it comes to loading of SxS assemblies. In short: prevent any CRT (and ATL/MFC) 8.x+ runtime from being put into system32! Such assemblies are never to be loaded from system32 with winver > 2K!
To fix this, 'winetricks dotnet20' step needs to include the removal of these assemblies from system32 as cleanup procedure. A second copy is properly installed into SxS as precaution from M$ guys in the light of win2k -> winxp update which knows about activation contexts/SxS.
--- snip .wine/drive_c/windows/system32 --- $ ls -lsa msvc* 472 -rw-rw-r-- 1 focht focht 479232 2005-09-23 08:29 msvcm80.dll 540 -rw-rw-r-- 1 focht focht 548864 2005-09-23 08:29 msvcp80.dll 616 -rw-rw-r-- 1 focht focht 626688 2005-09-23 08:29 msvcr80.dll .. --- snip .wine/drive_c/windows/system32 ---
The vendor msi installer bug at this stage is that the sub-installer is executed *before* the VC redist installer which would install all required CRT dependencies into SxS. Hence this error is only shown once. That sub-installer failure seems not critical.
Now one might think: "ok, lets do the usual winetricks vcrun2005 ... vcrun2005sp1 mess" before install. If you do this, the error will still remain (assuming you restart with clean WINEPREFIX). The reason is the other "old" VC 8.0 CRT version, referenced in dll manifest: 8.0.50608.0
Winetricks dotnet20 installed a VC 8.0.50727.42 CRT version into SxS (after we removed the ones from system32). This would ideally work but Wine's loader doesn't support the redirection of assembly bindings yet. If you take a look at the policy file from .NET 2.0 installed VC 8 runtime:
"c:\windows\winSxS\policies\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773":
--- snip 8.0.50727.42.policy --- <bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.42"/> --- snip 8.0.50727.42.policy ---
The policy rule would be satisfied, because the assembly asks for version 8.0.50608.0 and the current "up-to-date" version 8.0.50727.42 can be used for that.
After VC 8.0 SP1 install (sh winetricks vcrun2005sp1), another policy file is added:
--- snip 8.0.50727.762.policy ---
<bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.762"/> <bindingRedirect oldVersion="8.0.50727.42-8.0.50727.762" newVersion="8.0.50727.762"/>
--- snip 8.0.50727.762.policy ---
This would cover (match) the first assembly binding dependency, 8.0.50727.762
Regards