https://bugs.winehq.org/show_bug.cgi?id=44793
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Hardware|x86 |x86-64 Summary|EpicGamesLauncher.exe: |Epic Games Launcher 7.x |Fatal Unhandled Exception: |crashes on startup (relies |EXCEPTION_ACCESS_VIOLATION |on 'shcore.dll' load |0xdaaaa600 |dependency from other | |Windows dll) Keywords| |download Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Component|-unknown |-unknown Product|Wine-staging |Wine URL| |https://www.epicgames.com/u | |nrealtournament/download CC| |focht@gmx.net
--- Comment #5 from Anastasius Focht focht@gmx.net --- Hello folks,
confirming.
The installer for Epic games launcher has some prerequisite installer that needs .NET Framework 2.0 or 4.0 installed. It's essentially a WiX-based installer that bundles multiple MSVC++ runtimes and DirectX 9.0c together (normally done by official MS redist installers). Part of the DirectX installer is managed DirectX which causes the sub-installer to fail if not present. Anyway, the real problem is something different.
Relevant part of trace log:
--- snip --- $ pwd /home/focht/wineprefix32/drive_c/Program Files/Epic Games/Launcher/Portal/Binaries/Win32
$ WINEDEBUG=+seh,+loaddll,+process,+relay wine ./EpicGamesLauncher.exe
log.txt 2>&1
... 0039:Call KERNEL32.LoadLibraryW(003d66a0 L"shcore.dll") ret=0064bc70 0039:trace:loaddll:load_builtin_dll Loaded L"C:\windows\system32\shcore.dll" at 0xf7d30000: builtin 0039:Call PE DLL (proc=0xf7d3b127,module=0xf7d30000 L"shcore.dll",reason=PROCESS_ATTACH,res=(nil)) 0039:Call KERNEL32.DisableThreadLibraryCalls(f7d30000) ret=f7d3af7d 0039:Ret KERNEL32.DisableThreadLibraryCalls() retval=00000001 ret=f7d3af7d 0039:Ret PE DLL (proc=0xf7d3b127,module=0xf7d30000 L"shcore.dll",reason=PROCESS_ATTACH,res=(nil)) retval=1 0039:Ret KERNEL32.LoadLibraryW() retval=f7d30000 ret=0064bc70 0039:Call KERNEL32.SetErrorMode(00000000) ret=006471e4 0039:Ret KERNEL32.SetErrorMode() retval=00008000 ret=006471e4 0039:Call KERNEL32.GetProcAddress(f7d30000,0227f94c "SetProcessDpiAwareness") ret=00646d4d 0039:Ret KERNEL32.GetProcAddress() retval=f7d3aeac ret=00646d4d 0039:Call KERNEL32.GetProcAddress(f7d30000,0227f944 "GetDpiForMonitor") ret=00646d4d 0039:Ret KERNEL32.GetProcAddress() retval=f7d3ae80 ret=00646d4d 0039:Call KERNEL32.FreeLibrary(f7d30000) ret=006468fa 0039:Call PE DLL (proc=0xf7d3b127,module=0xf7d30000 L"shcore.dll",reason=PROCESS_DETACH,res=(nil)) 0039:Ret PE DLL (proc=0xf7d3b127,module=0xf7d30000 L"shcore.dll",reason=PROCESS_DETACH,res=(nil)) retval=1 0039:trace:loaddll:free_modref Unloaded module L"C:\windows\system32\shcore.dll" : builtin 0039:Ret KERNEL32.FreeLibrary() retval=00000001 ret=006468fa 0039:trace:seh:raise_exception code=c0000005 flags=0 addr=0xf7d3aeac ip=f7d3aeac tid=0039 0039:trace:seh:raise_exception info[0]=00000008 0039:trace:seh:raise_exception info[1]=f7d3aeac 0039:trace:seh:raise_exception eax=00000001 ebx=01670000 ecx=373927c1 edx=7bcf9780 esi=f7d30000 edi=f7d3aeac 0039:trace:seh:raise_exception ebp=01674afc esp=0227f9e0 cs=0023 ds=002b es=002b fs=0063 gs=006b flags=00210286 0039:trace:seh:call_stack_handlers calling handler at 0x162e815 code=c0000005 flags=0 0039:Call ucrtbase._except_handler4_common(01b9adf4,0162e229,0227f988,0227fe54,0227f6bc,0227f57c) ret=0162e833 0039:trace:seh:_except_handler4_common exception c0000005 flags=0 at 0xf7d3aeac handler=0x162e815 0x227f6bc 0x227f57c cookie=373927c1 scope table=0x1b64108 cookies=-2/0,-76/0 0039:trace:seh:_except_handler4_common level 0 prev -2 filter 0x545ed8 ... --- snip ---
There is lovely piece of brain damage (small annotations by me):
--- snip --- ... 0063DDF0 PUSH OFFSET 017066C0 ; UNICODE "enablehighdpi" 0063DDF5 CALL 005DA630 0063DDFA PUSH EAX 0063DDFB CALL 005FC300 0063DE00 ADD ESP,8 0063DE03 TEST AL,AL 0063DE05 JE SHORT 0063DE7E 0063DE07 PUSH ESI 0063DE08 PUSH EDI 0063DE09 PUSH OFFSET 017066DC ; UNICODE "shcore.dll" 0063DE0E CALL 00646D80 ; MyLoadLibrary() 0063DE13 MOV ESI,EAX 0063DE15 ADD ESP,4 0063DE18 TEST ESI,ESI 0063DE1A JE SHORT 0063DE4D ; alternate code path for < Win8? 0063DE1C PUSH OFFSET 017066F4 ; UNICODE "SetProcessDpiAwareness" 0063DE21 PUSH ESI 0063DE22 CALL 00646C70 ; MyGetProcAddress() 0063DE27 PUSH OFFSET 01706724 ; UNICODE "GetDpiForMonitor" 0063DE2C PUSH ESI 0063DE2D MOV EDI,EAX 0063DE2F CALL 00646C70 ; MyGetProcAddress() 0063DE34 PUSH ESI ; HMODULE shcore.dll 0063DE35 MOV DWORD PTR DS:[1BDBF98],EAX 0063DE3A CALL 006468F0 ; MyFreeLibrary() 0063DE3F ADD ESP,14 0063DE42 TEST EDI,EDI 0063DE44 JE SHORT 0063DE7C 0063DE46 PUSH 2 0063DE48 CALL EDI ; shcore.SetProcessDpiAwareness() 0063DE4A POP EDI 0063DE4B POP ESI 0063DE4C RETN ... 006468F0 PUSH DWORD PTR SS:[ESP+4] ; HMODULE shcore.dll 006468F4 CALL DWORD PTR DS:[<&KERNEL32.FreeLibrary>] 006468FA RETN ... --- snip ---
Some genius thought it would be good idea to call 'shcore.SetProcessDpiAwareness()' after the dll has been unloaded. The unload happens unconditionally before the call, there is no other code path in between. On Windows 8+ most likely some other dll holds a reference to 'shcore.dll' so the LoadLibrary/FreeLibrary didn't make a difference here (refcount > 0). I have no idea which other Windows dll has this load time dependency. Maybe someone could run the launcher with a dependency walker (http://www.dependencywalker.com/) or similar tool on Windows 8+ to figure this out.
Anyway, I've looked at the surrounding code and it seems there is an alternate code path when 'shcore.dll' can't be loaded. If you disable 'shcore.dll' (can be done per app basis or whole WINEPREFIX), the launcher will show the user interface (login page).
NOTE: For multi-monitor setups you need Wine-Staging patchset to work around bug 41258 (UE4 applications)
$ sha1sum EpicInstaller-7.7.0.msi 42e9cabf76eb715e8e23c2a5436f828d16a263b1 EpicInstaller-7.7.0.msi
$ du -sh EpicInstaller-7.7.0.msi 31M EpicInstaller-7.7.0.msi
$ wine --version wine-3.5-5-g03ece22480
Regards