http://bugs.winehq.org/show_bug.cgi?id=34681
Anastasius Focht focht@gmx.net changed:
What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download Status|UNCONFIRMED |NEW URL| |http://updates.playpw.com/P | |WSetup.exe CC| |focht@gmx.net Ever Confirmed|0 |1
--- Comment #4 from Anastasius Focht focht@gmx.net 2013-11-10 13:00:56 CST --- Hello folks,
confirming.
The game launcher makes heavy use of QT 4.8.x Network library and Boost C++ library (threading, signals, ...).
Fortunately the game is very verbose in what it does, write log files and uses OutputDebugString().
Launcher output when the problem occurs:
--- snip --- .\Net\Detail\HttpImpl.cpp(274): Throw in function void __thiscall Net::Detail::HttpImpl::OnFinished(class QNetworkReply *) Dynamic exception type: class boost::exception_detail::clone_impl<class Net::HttpError> std::exception::what: HTTP Error: #2, Connection closed (200), url: http://cdn.en.playpw.com/updates/PC/en-US/Client/Client/patches/00000_00010/... --- snip ---
Relevant part of trace log with +winsock:
--- snip --- ... 003a:trace:winsock:WS2_recv_base socket 06a8, wsabuf 0xa56c4fc, nbufs 1, flags 0, from (nil), fromlen -1, ovl (nil), func (nil) 003a:trace:winsock:WS2_recv_base fd=54, options=0 003a:trace:winsock:WS2_recv_base -> 1001 bytes 003a:trace:winsock:WSAAsyncSelect 6a8, hWnd 0x30086, uMsg 00000400, event 00000029 003a:trace:winsock:WSAIoctl 1704, 0x4004667f, 0xa56c59c, 4, 0xa56c594, 4, 0xa56c598, (nil), (nil) 003a:trace:winsock:WSAAsyncSelect 6a8, hWnd 0x30086, uMsg 00000000, event 00000000 003a:trace:winsock:WSAIoctl 1704, 0x4004667f, 0xa56c620, 4, 0xa56c618, 4, 0xa56c61c, (nil), (nil) 003a:trace:winsock:WSAIoctl 1704, 0x4004667f, 0xa56c580, 4, 0xa56c578, 4, 0xa56c57c, (nil), (nil) 003a:trace:winsock:WSAAsyncSelect 6a8, hWnd 0x30086, uMsg 00000400, event 00000029
003a:trace:winsock:WS2_recv_base socket 06a8, wsabuf 0xa56c554, nbufs 1, flags 0, from (nil), fromlen -1, ovl (nil), func (nil) 003a:trace:winsock:WS2_recv_base fd=54, options=0 003a:trace:winsock:WS2_recv_base -> 0 bytes
003a:trace:winsock:WSAAsyncSelect 6a8, hWnd 0x30086, uMsg 00000000, event 00000000
003a:trace:winsock:WS_closesocket socket 06a8 (http_impl) 13:18:14.687 W: HTTP error: #2: Connection closed, url: http://cdn.en.playpw.com/updates/PC/en-US/Client/Client/patches/00000_00010/...
0035:warn:debugstr:OutputDebugStringA "(http_impl) 13:18:14.687 W: HTTP error: #2: Connection closed, url: http://cdn.en.playpw.com/updates/PC/en-US/Client/Client/patches/00000_00010/..." (http_impl) 13:18:14.687 d: HttpImpl Finished. err: #2, code: 200, url: http://cdn.en.playpw.com/updates/PC/en-US/Client/Client/patches/00000_00010/...
0035:warn:debugstr:OutputDebugStringA "(http_impl) 13:18:14.687 d: HttpImpl Finished. err: #2, code: 200, url: http://cdn.en.playpw.com/updates/PC/en-US/Client/Client/patches/00000_00010/..." --- snip ---
The problem occurs when the connection was closed by server -> bytes read = 0 (not a socket error).
There is a bug entry on QT bugtracker which explains a similar problem for QT's own QHttpSocketEngine in detail: https://bugreports.qt-project.org/browse/qtbug-21351
The game implements HTTP protocol handling on its own, on top of Boost C++ classes. QT C++ network classes are used for low level socket handling.
"HTTP error: #2" is "RemoteHostClosedError":
--- snip --- class QNetworkReplyPrivate; class Q_NETWORK_EXPORT QNetworkReply: public QIODevice { Q_OBJECT Q_ENUMS(NetworkError) public: enum NetworkError { NoError = 0,
// network layer errors [relating to the destination server] (1-99): ConnectionRefusedError = 1, RemoteHostClosedError, HostNotFoundError, TimeoutError, OperationCanceledError, SslHandshakeFailedError, TemporaryNetworkFailureError, UnknownNetworkError = 99, --- snip ---
Small launcher code snippet that seems to be responsible for error handling (annotated):
--- snip --- ... 004ADE68 mov ecx, edi 004ADE6A call ebp ; QNetworkReply::error(void) 004ADE6C test eax, eax 004ADE6E jz loc_4AE00C 004ADE74 mov ecx, edi 004ADE76 call ebp ; QNetworkReply::error(void) 004ADE78 cmp eax, 5 ; OperationCanceledError 004ADE7B jnz 004ADF01 004ADE81 push ... ; "User has aborted the request" ... 004ADFD7 mov ... ; "void __thiscall Net::Detail::HttpImpl::" 004ADFE2 mov ... ; ".\Net\Detail\HttpImpl.cpp" 004ADFED mov ..., 112h ; line number 274 004ADFF8 call throw_cpp_exc ; .\Net\Detail\HttpImpl.cpp(274): Throw in function void __thiscall Net::Detail::HttpImpl::OnFinished(class QNetworkReply *) --- snip ---
Lower layer error codes 0 and 5 are explicitly handled while all others are generically handled as error (C++ exception thrown).
Anyway, "remote closed" might be a legitimate case and could be handled as such. I patched the executable to handle RemoteHostClosedError (#2) more gracefully. It reduced the error frequency but still encountered situations where some data/files were too short/corrupted.
Reducing the concurrency by modifying "app.config.xml" in "app" directory didn't really help, there were still failures.
"Proceed download queue: 0 [max=1]"
--- snip --- <MaxNumOfSimultaneousDownloads>1</MaxNumOfSimultaneousDownloads> --- snip ---
One thing to investigate is why "remote closed connection" (bytes read = 0) doesn't happen with the launcher on Windows (otherwise people would see similar failure/error propagation). If this situation could be prevented the launcher might actually succeed at all downloads.
QT Network code for reference (just to see lower layer socket API usage):
--- snip --- $ git clone git://gitorious.org/qt/qt.git -b v4.8.3 --- snip ---
$ sha1sum PWSetup.exe 4678e218e4c3d095c9f8075303f6c507e5fd59fd PWSetup.exe
$ du -sh PWSetup.exe 12M PWSetup.exe
$ wine --version wine-1.7.6-109-g917d303
Regards