Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/wine/afd.h | 1 + server/sock.c | 50 ++++++++++++++++++++++++++++------------------ 2 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/include/wine/afd.h b/include/wine/afd.h index 24e6c31f228..9ca03039f81 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -24,6 +24,7 @@ #include <winioctl.h>
#define IOCTL_AFD_CREATE CTL_CODE(FILE_DEVICE_NETWORK, 200, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_AFD_ACCEPT CTL_CODE(FILE_DEVICE_NETWORK, 201, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_AFD_ADDRESS_LIST_CHANGE CTL_CODE(FILE_DEVICE_NETWORK, 323, METHOD_BUFFERED, 0)
diff --git a/server/sock.c b/server/sock.c index f165e86b129..f66fe091174 100644 --- a/server/sock.c +++ b/server/sock.c @@ -851,16 +851,11 @@ static int accept_new_fd( struct sock *sock ) }
/* accept a socket (creates a new fd) */ -static struct sock *accept_socket( obj_handle_t handle ) +static struct sock *accept_socket( struct sock *sock ) { struct sock *acceptsock; - struct sock *sock; int acceptfd;
- sock = (struct sock *)get_handle_obj( current->process, handle, FILE_READ_DATA, &sock_ops ); - if (!sock) - return NULL; - if (get_unix_fd( sock->fd ) == -1) return NULL;
if ( sock->deferred ) @@ -870,15 +865,10 @@ static struct sock *accept_socket( obj_handle_t handle ) } else { - if ((acceptfd = accept_new_fd( sock )) == -1) - { - release_object( sock ); - return NULL; - } + if ((acceptfd = accept_new_fd( sock )) == -1) return NULL; if (!(acceptsock = create_socket())) { close( acceptfd ); - release_object( sock ); return NULL; }
@@ -899,7 +889,6 @@ static struct sock *accept_socket( obj_handle_t handle ) get_fd_options( sock->fd ) ))) { release_object( acceptsock ); - release_object( sock ); return NULL; } } @@ -907,7 +896,6 @@ static struct sock *accept_socket( obj_handle_t handle ) sock->pmask &= ~FD_ACCEPT; sock->hmask &= ~FD_ACCEPT; sock_reselect( sock ); - release_object( sock ); return acceptsock; }
@@ -1100,6 +1088,26 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
+ case IOCTL_AFD_ACCEPT: + { + struct sock *acceptsock; + obj_handle_t handle; + + if (get_reply_max_size() != sizeof(handle)) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return 0; + } + + if (!(acceptsock = accept_socket( sock ))) return 0; + handle = alloc_handle( current->process, &acceptsock->obj, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, OBJ_INHERIT ); + acceptsock->wparam = handle; + release_object( acceptsock ); + set_reply_data( &handle, sizeof(handle) ); + return 0; + } + case IOCTL_AFD_ADDRESS_LIST_CHANGE: if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async )) { @@ -1420,15 +1428,19 @@ struct object *create_socket_device( struct object *root, const struct unicode_s /* accept a socket */ DECL_HANDLER(accept_socket) { - struct sock *sock; + struct sock *sock, *acceptsock; + + if (!(sock = (struct sock *)get_handle_obj( current->process, req->lhandle, FILE_READ_DATA, &sock_ops ))) + return;
reply->handle = 0; - if ((sock = accept_socket( req->lhandle )) != NULL) + if ((acceptsock = accept_socket( sock )) != NULL) { - reply->handle = alloc_handle( current->process, &sock->obj, req->access, req->attributes ); - sock->wparam = reply->handle; /* wparam for message is the socket handle */ - release_object( &sock->obj ); + reply->handle = alloc_handle( current->process, &acceptsock->obj, req->access, req->attributes ); + acceptsock->wparam = reply->handle; /* wparam for message is the socket handle */ + release_object( acceptsock ); } + release_object( sock ); }
/* accept a socket into an initialized socket */
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index bc61b56667b..031688b2d96 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2771,9 +2771,11 @@ static int WS2_register_async_shutdown( SOCKET s, int type ) SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32) { DWORD err; - SOCKET as; int fd; BOOL is_blocking; + IO_STATUS_BLOCK io; + NTSTATUS status; + obj_handle_t accept_handle;
TRACE("socket %04lx\n", s ); err = sock_is_blocking(s, &is_blocking); @@ -2782,18 +2784,12 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32)
for (;;) { - /* try accepting first (if there is a deferred connection) */ - SERVER_START_REQ( accept_socket ) - { - req->lhandle = wine_server_obj_handle( SOCKET2HANDLE(s) ); - req->access = GENERIC_READ|GENERIC_WRITE|SYNCHRONIZE; - req->attributes = OBJ_INHERIT; - err = NtStatusToWSAError( wine_server_call( req )); - as = HANDLE2SOCKET( wine_server_ptr_handle( reply->handle )); - } - SERVER_END_REQ; - if (!err) + status = NtDeviceIoControlFile( SOCKET2HANDLE(s), NULL, NULL, NULL, &io, IOCTL_AFD_ACCEPT, + NULL, 0, &accept_handle, sizeof(accept_handle) ); + if (!status) { + SOCKET as = HANDLE2SOCKET(wine_server_ptr_handle( accept_handle )); + if (!socket_list_add(as)) { CloseHandle(SOCKET2HANDLE(as)); @@ -2807,6 +2803,7 @@ SOCKET WINAPI WS_accept(SOCKET s, struct WS_sockaddr *addr, int *addrlen32) TRACE("\taccepted %04lx\n", as); return as; } + err = NtStatusToWSAError( status ); if (!is_blocking) break; if (err != WSAEWOULDBLOCK) break; fd = get_sock_fd( s, FILE_READ_DATA, NULL );
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/protocol.def | 10 ---------- server/sock.c | 18 ------------------ 2 files changed, 28 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index f538c6dcf51..6534092f2cc 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1383,16 +1383,6 @@ enum server_fd_type @END
-/* Accept a socket */ -@REQ(accept_socket) - obj_handle_t lhandle; /* handle to the listening socket */ - unsigned int access; /* wanted access rights */ - unsigned int attributes; /* object attributes */ -@REPLY - obj_handle_t handle; /* handle to the new socket */ -@END - - /* Accept into an initialized socket */ @REQ(accept_into_socket) obj_handle_t lhandle; /* handle to the listening socket */ diff --git a/server/sock.c b/server/sock.c index f66fe091174..26a2c4fa668 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1425,24 +1425,6 @@ struct object *create_socket_device( struct object *root, const struct unicode_s return create_named_object( root, &socket_device_ops, name, attr, sd ); }
-/* accept a socket */ -DECL_HANDLER(accept_socket) -{ - struct sock *sock, *acceptsock; - - if (!(sock = (struct sock *)get_handle_obj( current->process, req->lhandle, FILE_READ_DATA, &sock_ops ))) - return; - - reply->handle = 0; - if ((acceptsock = accept_socket( sock )) != NULL) - { - reply->handle = alloc_handle( current->process, &acceptsock->obj, req->access, req->attributes ); - acceptsock->wparam = reply->handle; /* wparam for message is the socket handle */ - release_object( acceptsock ); - } - release_object( sock ); -} - /* accept a socket into an initialized socket */ DECL_HANDLER(accept_into_socket) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/wine/afd.h | 1 + server/sock.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/include/wine/afd.h b/include/wine/afd.h index 9ca03039f81..5a994084e16 100644 --- a/include/wine/afd.h +++ b/include/wine/afd.h @@ -25,6 +25,7 @@
#define IOCTL_AFD_CREATE CTL_CODE(FILE_DEVICE_NETWORK, 200, METHOD_BUFFERED, FILE_WRITE_ACCESS) #define IOCTL_AFD_ACCEPT CTL_CODE(FILE_DEVICE_NETWORK, 201, METHOD_BUFFERED, FILE_WRITE_ACCESS) +#define IOCTL_AFD_ACCEPT_INTO CTL_CODE(FILE_DEVICE_NETWORK, 202, METHOD_BUFFERED, FILE_WRITE_ACCESS)
#define IOCTL_AFD_ADDRESS_LIST_CHANGE CTL_CODE(FILE_DEVICE_NETWORK, 323, METHOD_BUFFERED, 0)
diff --git a/server/sock.c b/server/sock.c index 26a2c4fa668..360bf756f96 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1108,6 +1108,27 @@ static int sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async ) return 0; }
+ case IOCTL_AFD_ACCEPT_INTO: + { + static const int access = FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | FILE_READ_DATA; + struct sock *acceptsock; + obj_handle_t handle; + + if (get_req_data_size() != sizeof(handle)) + { + set_error( STATUS_BUFFER_TOO_SMALL ); + return 0; + } + handle = *(obj_handle_t *)get_req_data(); + + if (!(acceptsock = (struct sock *)get_handle_obj( current->process, handle, access, &sock_ops ))) + return 0; + if (accept_into_socket( sock, acceptsock )) + acceptsock->wparam = handle; + release_object( acceptsock ); + return 0; + } + case IOCTL_AFD_ADDRESS_LIST_CHANGE: if ((sock->state & FD_WINE_NONBLOCKING) && async_is_blocking( async )) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 031688b2d96..2eb1e1a7307 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -2517,13 +2517,11 @@ static NTSTATUS WS2_async_accept( void *user, IO_STATUS_BLOCK *iosb, NTSTATUS st
if (status == STATUS_ALERTED) { - SERVER_START_REQ( accept_into_socket ) - { - req->lhandle = wine_server_obj_handle( wsa->listen_socket ); - req->ahandle = wine_server_obj_handle( wsa->accept_socket ); - status = wine_server_call( req ); - } - SERVER_END_REQ; + obj_handle_t accept_handle = wine_server_obj_handle( wsa->accept_socket ); + IO_STATUS_BLOCK io; + + status = NtDeviceIoControlFile( wsa->listen_socket, NULL, NULL, NULL, &io, IOCTL_AFD_ACCEPT_INTO, + &accept_handle, sizeof(accept_handle), NULL, 0 );
if (NtStatusToWSAError( status ) == WSAEWOULDBLOCK) return STATUS_PENDING;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- server/protocol.def | 7 ------- server/sock.c | 23 ----------------------- 2 files changed, 30 deletions(-)
diff --git a/server/protocol.def b/server/protocol.def index 6534092f2cc..16c0b936743 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1383,13 +1383,6 @@ enum server_fd_type @END
-/* Accept into an initialized socket */ -@REQ(accept_into_socket) - obj_handle_t lhandle; /* handle to the listening socket */ - obj_handle_t ahandle; /* handle to the accepting socket */ -@END - - /* Set socket event parameters */ @REQ(set_socket_event) obj_handle_t handle; /* handle to the socket */ diff --git a/server/sock.c b/server/sock.c index 360bf756f96..4f97fe72080 100644 --- a/server/sock.c +++ b/server/sock.c @@ -1446,29 +1446,6 @@ struct object *create_socket_device( struct object *root, const struct unicode_s return create_named_object( root, &socket_device_ops, name, attr, sd ); }
-/* accept a socket into an initialized socket */ -DECL_HANDLER(accept_into_socket) -{ - struct sock *sock, *acceptsock; - const int all_attributes = FILE_READ_ATTRIBUTES|FILE_WRITE_ATTRIBUTES|FILE_READ_DATA; - - if (!(sock = (struct sock *)get_handle_obj( current->process, req->lhandle, - all_attributes, &sock_ops))) - return; - - if (!(acceptsock = (struct sock *)get_handle_obj( current->process, req->ahandle, - all_attributes, &sock_ops))) - { - release_object( sock ); - return; - } - - if (accept_into_socket( sock, acceptsock )) - acceptsock->wparam = req->ahandle; /* wparam for message is the socket handle */ - release_object( acceptsock ); - release_object( sock ); -} - /* set socket event parameters */ DECL_HANDLER(set_socket_event) {