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 */