Fixed WS_getpeername parameter in WS_accept.
Changed order of event processing in WINSOCK_DoAsyncEvent.
diff --git a/dlls/winsock/socket.c b/dlls/winsock/socket.c
index 78b65c2..1d0e6fc 100644
--- a/dlls/winsock/socket.c
+++ b/dlls/winsock/socket.c
@@ -202,6 +202,23 @@
0
};
+/* Permutation of 0..FD_MAX_EVENTS - 1 representing the order in which we post
+ * messages if there are multiple events. Used in WINSOCK_DoAsyncEvent. The
+ * problem is if there is both a FD_CONNECT event and, say, an FD_READ event
+ * available on the same socket, we want to notify the app of the connect event
+ * first. Otherwise it may discard the read event because it thinks it hasn't
+ * connected yet.
+ */
+static const int event_bitorder[FD_MAX_EVENTS] = {
+ FD_CONNECT_BIT,
+ FD_ACCEPT_BIT,
+ FD_OOB_BIT,
+ FD_WRITE_BIT,
+ FD_READ_BIT,
+ FD_CLOSE_BIT,
+ 6, 7, 8, 9 /* leftovers */
+};
+
/* set last error code from NT status without mapping WSA errors */
inline static unsigned int set_error( unsigned int err )
{
@@ -908,7 +925,7 @@
if (as)
{
unsigned omask = _get_sock_mask( s );
- WS_getpeername(fd, addr, addrlen32);
+ WS_getpeername(as, addr, addrlen32);
if (omask & FD_WINE_SERVEVENT)
ws2_async_accept(s, as);
return as;
@@ -2762,7 +2779,7 @@
VOID CALLBACK WINSOCK_DoAsyncEvent( ULONG_PTR ptr )
{
ws_select_info *info = (ws_select_info*)ptr;
- unsigned int i, pmask, orphan = FALSE;
+ unsigned int i, j, pmask, orphan = FALSE;
int errors[FD_MAX_EVENTS];
TRACE("socket %08x, event %08x\n", info->sock, info->event);
@@ -2800,13 +2817,17 @@
}
pmask &= ~FD_WINE_SERVEVENT;
}
- /* dispatch network events */
- for (i=0; i<FD_MAX_EVENTS; i++)
- if (pmask & (1<<i)) {
- TRACE("post: event bit %d, error %d\n", i, errors[i]);
- PostMessageA(info->hWnd, info->uMsg, info->sock,
- WSAMAKESELECTREPLY(1<<i, errors[i]));
- }
+ /* dispatch network events, but use the order in the event_bitorder
+ * array.
+ */
+ for (i=0; i<FD_MAX_EVENTS; i++) {
+ j = event_bitorder[i];
+ if (pmask & (1<<j)) {
+ TRACE("post: event bit %d, error %d\n", j, errors[j]);
+ PostMessageA(info->hWnd, info->uMsg, info->sock,
+ WSAMAKESELECTREPLY(1<<j, errors[j]));
+ }
+ }
/* cleanup */
if (orphan)
{