https://bugs.winehq.org/show_bug.cgi?id=36830
Bug ID: 36830 Summary: Nexon Atlantica Online: broken launcher/updater reports 'Atlantica is currently under maintenance. Please try again later' (relies on 'wininet' to initialize sockets API) Product: Wine Version: 1.7.21 Hardware: x86 OS: Linux Status: NEW Severity: normal Priority: P2 Component: wininet Assignee: wine-bugs@winehq.org Reporter: focht@gmx.net
Hello folks,
split this off from bug 22479
An up-to-date client is need for successful login which in turn can only be updated by using the launcher 'AtlanticaRun.exe'.
--- snip --- $ pwd /home/focht/.wine/drive_c/Nexon/Atlantica
$ WINEDEBUG=+tid,+seh,+relay wine ./AtlanticaRun.exe >>log.txt 2>&1 ... 0024:Call KERNEL32.WideCharToMultiByte(00000000,00000000,0051e82c L"auth.atlantica.nexon.net",ffffffff,0033e334,00000100,00000000,00000000) ret=0040f27f 0024:Ret KERNEL32.WideCharToMultiByte() retval=00000019 ret=0040f27f 0024:Call KERNEL32.WideCharToMultiByte(00000000,00000000,0051e85e L"8.31.100.59",ffffffff,0033e544,00000100,00000000,00000000) ret=0040f27f 0024:Ret KERNEL32.WideCharToMultiByte() retval=0000000c ret=0040f27f ... 0024:Call user32.SetWindowTextW(000100a8,0033e034 L"Connecting to Front Server...") ret=0042c4ae ... 0024:Call KERNEL32.MultiByteToWideChar(00000000,00000000,004b1cf4 "auth.atlantica.nexon.net",ffffffff,0051df80,00000100) ret=0047282d 0024:Ret KERNEL32.MultiByteToWideChar() retval=00000019 ret=0047282d 0024:Call ws2_32.gethostbyname(0051de80 "auth.atlantica.nexon.net") ret=0047287b 0024:Ret ws2_32.gethostbyname() retval=00000000 ret=0047287b ... 0024:Call KERNEL32.MultiByteToWideChar(00000000,00000000,004b1df4 "8.31.100.59",ffffffff,0051df80,00000100) ret=0047282d 0024:Ret KERNEL32.MultiByteToWideChar() retval=0000000c ret=0047282d 0024:Call ws2_32.inet_addr(0051de80 "8.31.100.59") ret=004728c7 0024:Ret ws2_32.inet_addr() retval=3b641f08 ret=004728c7 0024:Call ws2_32.htons(000014b4) ret=004728de 0024:Ret ws2_32.htons() retval=0000b414 ret=004728de 0024:Call KERNEL32.GetTickCount() ret=00472925 0024:Ret KERNEL32.GetTickCount() retval=021fe7bc ret=00472925 0024:Call ws2_32.WSASocketA(00000002,00000001,00000000,00000000,00000000,00000001) ret=00472963 0024:Ret ws2_32.WSASocketA() retval=ffffffff ret=00472963 ... <repeats> 0024:Call user32.MessageBoxW(00030076,0056e280 L"Atlantica is currently under maintenance. Please try again later.\r\nIf it's not a maintenance problem, please check your connection, firewall, and/or router settings.",00498558 L"Error",00000040) ret=00427dce --- snip ---
Debugger:
--- snip --- Wine-dbg>bt Backtrace: =>0 0x7df3718c WS_gethostbyname(name="auth.atlantica.nexon.net") [/home/focht/projects/wine/wine.repo/src/dlls/ws2_32/socket.c:5284] in ws2_32 (0x0033e270) 1 0x00472c35 in atlanticarun (+0x72c34) (0x0033e288) 2 0x0041dfb5 in atlanticarun (+0x1dfb4) (0x0033e2a8) 3 0x00479648 in atlanticarun (+0x79647) (0x0033e2b4) 4 0x00479aee in atlanticarun (+0x79aed) (0x0033e2f8) 5 0x0042b476 in atlanticarun (+0x2b475) (0x0033e390) 6 0x0042767d in atlanticarun (+0x2767c) (0x0033e3b0) 7 0x00429b35 in atlanticarun (+0x29b34) (0x0033e418) 8 0x00429bc4 in atlanticarun (+0x29bc3) (0x0033e438) ...
Wine-dbg>p num_startup 0 --- snip ---
Some "genius" decided to call this API without prior 'WSAStartup'.
MSDN: http://msdn.microsoft.com/en-us/library/windows/desktop/ms738524%28v=vs.85%2...
--- quote --- Return value
If no error occurs, gethostbyname returns a pointer to the hostent structure described above. Otherwise, it returns a null pointer and a specific error number can be retrieved by calling WSAGetLastError. Error code Meaning
WSANOTINITIALISED
A successful WSAStartup call must occur before using this function. --- quote ---
It gets better ... there is no 'WSAStartup' import at all.
Dumping 'AtlanticaRun.exe' imports table reveals:
(I added descriptions for ordinal-only)
--- snip --- ... 12. ImageImportDescriptor: OriginalFirstThunk: 0x000A7434 TimeDateStamp: 0x00000000 (GMT: Thu Jan 01 00:00:00 1970) ForwarderChain: 0x00000000 Name: 0x000A7F72 ("WS2_32.dll") FirstThunk: 0x0008A6FC
Ordinal/Hint API name ------------ --------------------------------------- 0x0013 (ordinal only) -> "send" 0x0008 (ordinal only) -> "htonl" 0x000F (ordinal only) -> "ntohs" 0x000A (ordinal only) -> "ioctlsocket" 0x000C (ordinal only) -> "inet_ntoa" 0x0010 (ordinal only) -> "recv" 0x0009 (ordinal only) -> "htons" 0x0003 (ordinal only) -> "closesocket" 0x0034 (ordinal only) -> "gethostbyname" 0x0052 "WSASocketA" 0x006F (ordinal only) -> "WSAGetLastError" 0x0049 "WSASend" 0x0044 "WSARecv" 0x000B (ordinal only) -> "inet_addr" 0x0004 (ordinal only) -> "connect"
13. ImageImportDescriptor: OriginalFirstThunk: 0x000A6E14 TimeDateStamp: 0x00000000 (GMT: Thu Jan 01 00:00:00 1970) ForwarderChain: 0x00000000 Name: 0x000A7F8E ("IPHLPAPI.DLL") FirstThunk: 0x0008A0DC
Ordinal/Hint API name ------------ --------------------------------------- 0x0082 "IcmpSendEcho"
--- snip ---
What most likely happens is that the stupid code relies on 'wininet' to initialize sockets API (remains mapped the whole time).
There is an early 'wininet' API call before trying auth server/explicit Windows sockets API:
--- snip --- ... 0024:Ret PE DLL (proc=0x7de7e038,module=0x7de40000 L"wininet.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0024:Starting process L"C:\Nexon\Atlantica\AtlanticaRun.exe" (entryproc=0x4438bd) ... 0024:Call wininet.InternetOpenW(00502c90 L"AtlanticaRun",00000000,00000000,00000000,00000000) ret=004351c0 ... 0024:Ret wininet.InternetOpenW() retval=00000001 ret=004351c0 ... --- snip ---
'winetricks -q wininet' works around.
Unlike the Wine builtin which uses BSD sockets API directly, native binds to 'ws2_32' and calls 'WSAStartup' from 'InternetOpen' to initialize sockets API.
--- snip --- 0024:Ret PE DLL (proc=0x76c0137c,module=0x76c00000 L"WININET.dll",reason=PROCESS_ATTACH,res=0x1) retval=1 0024:Starting process L"C:\Nexon\Atlantica\AtlanticaRun.exe" (entryproc=0x4438bd) ... 0024:Call KERNEL32.CreateMutexA(00000000,00000000,76c07b6c "WininetStartupMutex") ret=76c07489 0024:Ret KERNEL32.CreateMutexA() retval=00000070 ret=76c07489 ... 0024:Call advapi32.RegOpenKeyExA(80000002,76c05020 "SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings",00000000,00000001,0033e3f4) ret=76c0521b 0024:Ret advapi32.RegOpenKeyExA() retval=00000000 ret=76c0521b ... 0024:Call advapi32.RegQueryValueExA(00000064,76c07680 "BadProxyExpiresTime",00000000,0033e3d8,0033e3d4,0033e3c8) ret=76c05262 0024:Ret advapi32.RegQueryValueExA() retval=00000002 ret=76c05262 ... 0024:Call ws2_32.WSAStartup(00000101,0033e378) ret=76c16d16 0024:Ret ws2_32.WSAStartup() retval=00000000 ret=76c16d16 ... 0024:Call KERNEL32.MultiByteToWideChar(00000000,00000000,004b1cf4 "auth.atlantica.nexon.net",ffffffff,0051df80,00000100) ret=0047282d 0024:Ret KERNEL32.MultiByteToWideChar() retval=00000019 ret=0047282d 0024:Call ws2_32.gethostbyname(0051de80 "auth.atlantica.nexon.net") ret=0047287b ... 0024:Ret ws2_32.gethostbyname() retval=00163778 ret=0047287b 0024:Call ws2_32.htons(000014b4) ret=004728de 0024:Ret ws2_32.htons() retval=0000b414 ret=004728de ... 0024:Call ws2_32.WSASocketA(00000002,00000001,00000000,00000000,00000000,00000001) ret=00472963 0024:Ret ws2_32.WSASocketA() retval=000000f4 ret=00472963 ... --- snip ---
It should be ok to duplicate Windows at least for the part of having 'WSAStartup' called from 'InternetOpenW' and tearing it down with 'InternetCloseHandle'. Using 'DllMain' function for that would be bad idea and even MS advises against it.
$ sha1sum Atlantica_Downloader.exe 814aa0c4fc441e5ab177328a10da59537ef3302b Atlantica_Downloader.exe
$ du -sh Atlantica_Downloader.exe 2.5M Atlantica_Downloader.exe
$ wine --version wine-1.7.21-19-g8812193
Regards