Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
f670a162
Commit
f670a162
authored
Nov 20, 2018
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
server: Return WSA error codes in socket events.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
f4b07ee8
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
64 deletions
+80
-64
socket.c
dlls/ws2_32/socket.c
+70
-43
sock.c
server/sock.c
+10
-21
No files found.
dlls/ws2_32/socket.c
View file @
f670a162
...
@@ -1038,41 +1038,74 @@ static UINT wsaHerrno(int loc_errno)
...
@@ -1038,41 +1038,74 @@ static UINT wsaHerrno(int loc_errno)
}
}
}
}
static
inline
DWORD
NtStatusToWSAError
(
const
DWORD
status
)
static
NTSTATUS
sock_error_to_ntstatus
(
DWORD
err
)
{
switch
(
err
)
{
case
0
:
return
STATUS_SUCCESS
;
case
WSAEBADF
:
return
STATUS_INVALID_HANDLE
;
case
WSAEACCES
:
return
STATUS_ACCESS_DENIED
;
case
WSAEFAULT
:
return
STATUS_NO_MEMORY
;
case
WSAEINVAL
:
return
STATUS_INVALID_PARAMETER
;
case
WSAEMFILE
:
return
STATUS_TOO_MANY_OPENED_FILES
;
case
WSAEWOULDBLOCK
:
return
STATUS_CANT_WAIT
;
case
WSAEINPROGRESS
:
return
STATUS_PENDING
;
case
WSAEALREADY
:
return
STATUS_NETWORK_BUSY
;
case
WSAENOTSOCK
:
return
STATUS_OBJECT_TYPE_MISMATCH
;
case
WSAEDESTADDRREQ
:
return
STATUS_INVALID_PARAMETER
;
case
WSAEMSGSIZE
:
return
STATUS_BUFFER_OVERFLOW
;
case
WSAEPROTONOSUPPORT
:
case
WSAESOCKTNOSUPPORT
:
case
WSAEPFNOSUPPORT
:
case
WSAEAFNOSUPPORT
:
case
WSAEPROTOTYPE
:
return
STATUS_NOT_SUPPORTED
;
case
WSAENOPROTOOPT
:
return
STATUS_INVALID_PARAMETER
;
case
WSAEOPNOTSUPP
:
return
STATUS_NOT_SUPPORTED
;
case
WSAEADDRINUSE
:
return
STATUS_ADDRESS_ALREADY_ASSOCIATED
;
case
WSAEADDRNOTAVAIL
:
return
STATUS_INVALID_PARAMETER
;
case
WSAECONNREFUSED
:
return
STATUS_CONNECTION_REFUSED
;
case
WSAESHUTDOWN
:
return
STATUS_PIPE_DISCONNECTED
;
case
WSAENOTCONN
:
return
STATUS_CONNECTION_DISCONNECTED
;
case
WSAETIMEDOUT
:
return
STATUS_IO_TIMEOUT
;
case
WSAENETUNREACH
:
return
STATUS_NETWORK_UNREACHABLE
;
case
WSAENETDOWN
:
return
STATUS_NETWORK_BUSY
;
case
WSAECONNRESET
:
return
STATUS_CONNECTION_RESET
;
case
WSAECONNABORTED
:
return
STATUS_CONNECTION_ABORTED
;
default:
FIXME
(
"unmapped error %u
\n
"
,
err
);
return
STATUS_UNSUCCESSFUL
;
}
}
static
DWORD
NtStatusToWSAError
(
DWORD
status
)
{
{
/* We only need to cover the status codes set by server async request handling */
DWORD
wserr
;
switch
(
status
)
switch
(
status
)
{
{
case
STATUS_SUCCESS
:
wserr
=
0
;
break
;
case
STATUS_SUCCESS
:
return
0
;
case
STATUS_PENDING
:
wserr
=
WSA_IO_PENDING
;
break
;
case
STATUS_PENDING
:
return
WSA_IO_PENDING
;
case
STATUS_OBJECT_TYPE_MISMATCH
:
wserr
=
WSAENOTSOCK
;
break
;
case
STATUS_OBJECT_TYPE_MISMATCH
:
return
WSAENOTSOCK
;
case
STATUS_INVALID_HANDLE
:
wserr
=
WSAEBADF
;
break
;
case
STATUS_INVALID_HANDLE
:
return
WSAEBADF
;
case
STATUS_INVALID_PARAMETER
:
wserr
=
WSAEINVAL
;
break
;
case
STATUS_INVALID_PARAMETER
:
return
WSAEINVAL
;
case
STATUS_PIPE_DISCONNECTED
:
wserr
=
WSAESHUTDOWN
;
break
;
case
STATUS_PIPE_DISCONNECTED
:
return
WSAESHUTDOWN
;
case
STATUS_NETWORK_BUSY
:
wserr
=
WSAEALREADY
;
break
;
case
STATUS_NETWORK_BUSY
:
return
WSAEALREADY
;
case
STATUS_NETWORK_UNREACHABLE
:
wserr
=
WSAENETUNREACH
;
break
;
case
STATUS_NETWORK_UNREACHABLE
:
return
WSAENETUNREACH
;
case
STATUS_CONNECTION_REFUSED
:
wserr
=
WSAECONNREFUSED
;
break
;
case
STATUS_CONNECTION_REFUSED
:
return
WSAECONNREFUSED
;
case
STATUS_CONNECTION_DISCONNECTED
:
wserr
=
WSAENOTCONN
;
break
;
case
STATUS_CONNECTION_DISCONNECTED
:
return
WSAENOTCONN
;
case
STATUS_CONNECTION_RESET
:
wserr
=
WSAECONNRESET
;
break
;
case
STATUS_CONNECTION_RESET
:
return
WSAECONNRESET
;
case
STATUS_CONNECTION_ABORTED
:
wserr
=
WSAECONNABORTED
;
break
;
case
STATUS_CONNECTION_ABORTED
:
return
WSAECONNABORTED
;
case
STATUS_CANCELLED
:
wserr
=
WSA_OPERATION_ABORTED
;
break
;
case
STATUS_CANCELLED
:
return
WSA_OPERATION_ABORTED
;
case
STATUS_ADDRESS_ALREADY_ASSOCIATED
:
wserr
=
WSAEADDRINUSE
;
break
;
case
STATUS_ADDRESS_ALREADY_ASSOCIATED
:
return
WSAEADDRINUSE
;
case
STATUS_IO_TIMEOUT
:
case
STATUS_IO_TIMEOUT
:
case
STATUS_TIMEOUT
:
wserr
=
WSAETIMEDOUT
;
break
;
case
STATUS_TIMEOUT
:
return
WSAETIMEDOUT
;
case
STATUS_NO_MEMORY
:
wserr
=
WSAEFAULT
;
break
;
case
STATUS_NO_MEMORY
:
return
WSAEFAULT
;
case
STATUS_ACCESS_DENIED
:
wserr
=
WSAEACCES
;
break
;
case
STATUS_ACCESS_DENIED
:
return
WSAEACCES
;
case
STATUS_TOO_MANY_OPENED_FILES
:
wserr
=
WSAEMFILE
;
break
;
case
STATUS_TOO_MANY_OPENED_FILES
:
return
WSAEMFILE
;
case
STATUS_CANT_WAIT
:
wserr
=
WSAEWOULDBLOCK
;
break
;
case
STATUS_CANT_WAIT
:
return
WSAEWOULDBLOCK
;
case
STATUS_BUFFER_OVERFLOW
:
wserr
=
WSAEMSGSIZE
;
break
;
case
STATUS_BUFFER_OVERFLOW
:
return
WSAEMSGSIZE
;
case
STATUS_NOT_SUPPORTED
:
wserr
=
WSAEOPNOTSUPP
;
break
;
case
STATUS_NOT_SUPPORTED
:
return
WSAEOPNOTSUPP
;
case
STATUS_HOST_UNREACHABLE
:
wserr
=
WSAEHOSTUNREACH
;
break
;
case
STATUS_HOST_UNREACHABLE
:
return
WSAEHOSTUNREACH
;
default:
return
RtlNtStatusToDosError
(
status
);
default:
wserr
=
RtlNtStatusToDosError
(
status
);
FIXME
(
"Status code %08x converted to DOS error code %x
\n
"
,
status
,
wserr
);
}
}
return
wserr
;
}
}
/* set last error code from NT status without mapping WSA errors */
/* set last error code from NT status without mapping WSA errors */
...
@@ -1164,7 +1197,7 @@ static void _get_sock_errors(SOCKET s, int *events)
...
@@ -1164,7 +1197,7 @@ static void _get_sock_errors(SOCKET s, int *events)
SERVER_END_REQ
;
SERVER_END_REQ
;
}
}
static
int
_
get_sock_error
(
SOCKET
s
,
unsigned
int
bit
)
static
int
get_sock_error
(
SOCKET
s
,
unsigned
int
bit
)
{
{
int
events
[
FD_MAX_EVENTS
];
int
events
[
FD_MAX_EVENTS
];
_get_sock_errors
(
s
,
events
);
_get_sock_errors
(
s
,
events
);
...
@@ -3460,13 +3493,8 @@ int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
...
@@ -3460,13 +3493,8 @@ int WINAPI WS_connect(SOCKET s, const struct WS_sockaddr* name, int namelen)
do_block
(
fd
,
POLLIN
|
POLLOUT
,
-
1
);
do_block
(
fd
,
POLLIN
|
POLLOUT
,
-
1
);
_sync_sock_state
(
s
);
/* let wineserver notice connection */
_sync_sock_state
(
s
);
/* let wineserver notice connection */
/* retrieve any error codes from it */
/* retrieve any error codes from it */
result
=
_get_sock_error
(
s
,
FD_CONNECT_BIT
);
if
(
!
(
result
=
get_sock_error
(
s
,
FD_CONNECT_BIT
)))
goto
connect_success
;
if
(
result
)
SetLastError
(
result
);
SetLastError
(
NtStatusToWSAError
(
result
));
else
{
goto
connect_success
;
}
}
}
else
else
{
{
...
@@ -3589,7 +3617,7 @@ static BOOL WINAPI WS2_ConnectEx(SOCKET s, const struct WS_sockaddr* name, int n
...
@@ -3589,7 +3617,7 @@ static BOOL WINAPI WS2_ConnectEx(SOCKET s, const struct WS_sockaddr* name, int n
/* If the connect already failed */
/* If the connect already failed */
if
(
status
==
STATUS_PIPE_DISCONNECTED
)
if
(
status
==
STATUS_PIPE_DISCONNECTED
)
{
{
ov
->
Internal
=
_get_sock_error
(
s
,
FD_CONNECT_BIT
);
ov
->
Internal
=
sock_error_to_ntstatus
(
get_sock_error
(
s
,
FD_CONNECT_BIT
)
);
ov
->
InternalHigh
=
0
;
ov
->
InternalHigh
=
0
;
if
(
cvalue
)
WS_AddCompletion
(
s
,
cvalue
,
ov
->
Internal
,
ov
->
InternalHigh
,
FALSE
);
if
(
cvalue
)
WS_AddCompletion
(
s
,
cvalue
,
ov
->
Internal
,
ov
->
InternalHigh
,
FALSE
);
if
(
ov
->
hEvent
)
NtSetEvent
(
ov
->
hEvent
,
NULL
);
if
(
ov
->
hEvent
)
NtSetEvent
(
ov
->
hEvent
,
NULL
);
...
@@ -3983,7 +4011,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
...
@@ -3983,7 +4011,6 @@ INT WINAPI WS_getsockopt(SOCKET s, INT level,
{
{
if
(
events
[
i
])
if
(
events
[
i
])
{
{
events
[
i
]
=
NtStatusToWSAError
(
events
[
i
]);
TRACE
(
"returning SO_ERROR %d from wine server
\n
"
,
events
[
i
]);
TRACE
(
"returning SO_ERROR %d from wine server
\n
"
,
events
[
i
]);
*
(
int
*
)
optval
=
events
[
i
];
*
(
int
*
)
optval
=
events
[
i
];
break
;
break
;
...
@@ -5079,10 +5106,10 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
...
@@ -5079,10 +5106,10 @@ INT WINAPI WSAIoctl(SOCKET s, DWORD code, LPVOID in_buff, DWORD in_size, LPVOID
else
if
(
overlapped
)
else
if
(
overlapped
)
{
{
ULONG_PTR
cvalue
=
(
overlapped
&&
((
ULONG_PTR
)
overlapped
->
hEvent
&
1
)
==
0
)
?
(
ULONG_PTR
)
overlapped
:
0
;
ULONG_PTR
cvalue
=
(
overlapped
&&
((
ULONG_PTR
)
overlapped
->
hEvent
&
1
)
==
0
)
?
(
ULONG_PTR
)
overlapped
:
0
;
overlapped
->
Internal
=
s
tatus
;
overlapped
->
Internal
=
s
ock_error_to_ntstatus
(
status
)
;
overlapped
->
InternalHigh
=
total
;
overlapped
->
InternalHigh
=
total
;
if
(
cvalue
)
WS_AddCompletion
(
HANDLE2SOCKET
(
s
),
cvalue
,
overlapped
->
Internal
,
total
,
FALSE
);
if
(
overlapped
->
hEvent
)
NtSetEvent
(
overlapped
->
hEvent
,
NULL
);
if
(
overlapped
->
hEvent
)
NtSetEvent
(
overlapped
->
hEvent
,
NULL
);
if
(
cvalue
)
WS_AddCompletion
(
HANDLE2SOCKET
(
s
),
cvalue
,
status
,
total
,
FALSE
);
}
}
if
(
!
status
)
if
(
!
status
)
...
@@ -7333,7 +7360,7 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
...
@@ -7333,7 +7360,7 @@ int WINAPI WSAEnumNetworkEvents(SOCKET s, WSAEVENT hEvent, LPWSANETWORKEVENTS lp
for
(
i
=
0
;
i
<
FD_MAX_EVENTS
;
i
++
)
for
(
i
=
0
;
i
<
FD_MAX_EVENTS
;
i
++
)
{
{
if
(
lpEvent
->
lNetworkEvents
&
(
1
<<
i
))
if
(
lpEvent
->
lNetworkEvents
&
(
1
<<
i
))
lpEvent
->
iErrorCode
[
i
]
=
NtStatusToWSAError
(
errors
[
i
])
;
lpEvent
->
iErrorCode
[
i
]
=
errors
[
i
]
;
}
}
return
0
;
return
0
;
}
}
...
...
server/sock.c
View file @
f670a162
...
@@ -109,7 +109,7 @@ struct sock
...
@@ -109,7 +109,7 @@ struct sock
user_handle_t
window
;
/* window to send the message to */
user_handle_t
window
;
/* window to send the message to */
unsigned
int
message
;
/* message to send */
unsigned
int
message
;
/* message to send */
obj_handle_t
wparam
;
/* message wparam (socket handle) */
obj_handle_t
wparam
;
/* message wparam (socket handle) */
int
errors
[
FD_MAX_EVENTS
];
/* event errors */
unsigned
int
errors
[
FD_MAX_EVENTS
];
/* event errors */
timeout_t
connect_time
;
/* time the socket was connected */
timeout_t
connect_time
;
/* time the socket was connected */
struct
sock
*
deferred
;
/* socket that waits for a deferred accept */
struct
sock
*
deferred
;
/* socket that waits for a deferred accept */
struct
async_queue
read_q
;
/* queue for asynchronous reads */
struct
async_queue
read_q
;
/* queue for asynchronous reads */
...
@@ -134,7 +134,7 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
...
@@ -134,7 +134,7 @@ static void sock_queue_async( struct fd *fd, struct async *async, int type, int
static
void
sock_reselect_async
(
struct
fd
*
fd
,
struct
async_queue
*
queue
);
static
void
sock_reselect_async
(
struct
fd
*
fd
,
struct
async_queue
*
queue
);
static
int
sock_get_ntstatus
(
int
err
);
static
int
sock_get_ntstatus
(
int
err
);
static
int
sock_get_error
(
int
err
);
static
unsigned
int
sock_get_error
(
int
err
);
static
void
sock_set_error
(
void
);
static
void
sock_set_error
(
void
);
static
const
struct
object_ops
sock_ops
=
static
const
struct
object_ops
sock_ops
=
...
@@ -292,7 +292,7 @@ static void sock_wake_up( struct sock *sock )
...
@@ -292,7 +292,7 @@ static void sock_wake_up( struct sock *sock )
int
event
=
event_bitorder
[
i
];
int
event
=
event_bitorder
[
i
];
if
(
sock
->
pmask
&
(
1
<<
event
))
if
(
sock
->
pmask
&
(
1
<<
event
))
{
{
lparam_t
lparam
=
(
1
<<
event
)
|
(
sock
_get_error
(
sock
->
errors
[
event
])
<<
16
);
lparam_t
lparam
=
(
1
<<
event
)
|
(
sock
->
errors
[
event
]
<<
16
);
post_message
(
sock
->
window
,
sock
->
message
,
sock
->
wparam
,
lparam
);
post_message
(
sock
->
window
,
sock
->
message
,
sock
->
wparam
,
lparam
);
}
}
}
}
...
@@ -345,14 +345,14 @@ static void sock_dispatch_events( struct sock *sock, int prevstate, int event, i
...
@@ -345,14 +345,14 @@ static void sock_dispatch_events( struct sock *sock, int prevstate, int event, i
{
{
sock
->
pmask
|=
FD_CONNECT
;
sock
->
pmask
|=
FD_CONNECT
;
sock
->
hmask
|=
FD_CONNECT
;
sock
->
hmask
|=
FD_CONNECT
;
sock
->
errors
[
FD_CONNECT_BIT
]
=
error
;
sock
->
errors
[
FD_CONNECT_BIT
]
=
sock_get_error
(
error
)
;
goto
end
;
goto
end
;
}
}
if
(
prevstate
&
FD_WINE_LISTENING
)
if
(
prevstate
&
FD_WINE_LISTENING
)
{
{
sock
->
pmask
|=
FD_ACCEPT
;
sock
->
pmask
|=
FD_ACCEPT
;
sock
->
hmask
|=
FD_ACCEPT
;
sock
->
hmask
|=
FD_ACCEPT
;
sock
->
errors
[
FD_ACCEPT_BIT
]
=
error
;
sock
->
errors
[
FD_ACCEPT_BIT
]
=
sock_get_error
(
error
)
;
goto
end
;
goto
end
;
}
}
...
@@ -381,7 +381,7 @@ static void sock_dispatch_events( struct sock *sock, int prevstate, int event, i
...
@@ -381,7 +381,7 @@ static void sock_dispatch_events( struct sock *sock, int prevstate, int event, i
{
{
sock
->
pmask
|=
FD_CLOSE
;
sock
->
pmask
|=
FD_CLOSE
;
sock
->
hmask
|=
FD_CLOSE
;
sock
->
hmask
|=
FD_CLOSE
;
sock
->
errors
[
FD_CLOSE_BIT
]
=
error
;
sock
->
errors
[
FD_CLOSE_BIT
]
=
sock_get_error
(
error
)
;
}
}
end:
end:
sock_wake_up
(
sock
);
sock_wake_up
(
sock
);
...
@@ -823,7 +823,7 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
...
@@ -823,7 +823,7 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
}
}
/* return an errno value mapped to a WSA error */
/* return an errno value mapped to a WSA error */
static
int
sock_get_error
(
int
err
)
static
unsigned
int
sock_get_error
(
int
err
)
{
{
switch
(
err
)
switch
(
err
)
{
{
...
@@ -1265,24 +1265,13 @@ DECL_HANDLER(set_socket_event)
...
@@ -1265,24 +1265,13 @@ DECL_HANDLER(set_socket_event)
DECL_HANDLER
(
get_socket_event
)
DECL_HANDLER
(
get_socket_event
)
{
{
struct
sock
*
sock
;
struct
sock
*
sock
;
int
i
;
int
errors
[
FD_MAX_EVENTS
];
sock
=
(
struct
sock
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
FILE_READ_ATTRIBUTES
,
&
sock_ops
);
if
(
!
(
sock
=
(
struct
sock
*
)
get_handle_obj
(
current
->
process
,
req
->
handle
,
if
(
!
sock
)
FILE_READ_ATTRIBUTES
,
&
sock_ops
)))
return
;
{
reply
->
mask
=
0
;
reply
->
pmask
=
0
;
reply
->
state
=
0
;
return
;
}
reply
->
mask
=
sock
->
mask
;
reply
->
mask
=
sock
->
mask
;
reply
->
pmask
=
sock
->
pmask
;
reply
->
pmask
=
sock
->
pmask
;
reply
->
state
=
sock
->
state
;
reply
->
state
=
sock
->
state
;
for
(
i
=
0
;
i
<
FD_MAX_EVENTS
;
i
++
)
set_reply_data
(
sock
->
errors
,
min
(
get_reply_max_size
(),
sizeof
(
sock
->
errors
)
));
errors
[
i
]
=
sock_get_ntstatus
(
sock
->
errors
[
i
]);
set_reply_data
(
errors
,
min
(
get_reply_max_size
(),
sizeof
(
errors
)
));
if
(
req
->
service
)
if
(
req
->
service
)
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment